-module(sbeezg_parser). -define(THIS_MODULE, sbeezg_parser). -export([parse/1, parse_and_scan/1, format_error/1]). new_name({name,{atom,Line,Name}}=A) -> case get(A) of defn -> return_error(0, io_lib:format("Name '~w' already defined", [Name])); _ -> put(A, defn) end. existing_name({name,{atom,Line,Name}}=A) -> case get(A) of undefined -> return_error(0, io_lib:format("Name '~w' is not yet defined", [Name])); _ -> ok end. %%% END of sbeezg_parser.yrl %%% %% ``The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved via the world wide web at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings %% AB. All Rights Reserved.'' %% %% $Id$ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The parser generator will insert appropriate declarations before this line.% parse(Tokens) -> case catch yeccpars1(Tokens, false, 0, [], []) of error -> Errorline = if Tokens == [] -> 0; true -> element(2, hd(Tokens)) end, {error, {Errorline, ?THIS_MODULE, "syntax error at or after this line."}}; Other -> Other end. parse_and_scan({Mod, Fun, Args}) -> case apply(Mod, Fun, Args) of {eof, _} -> {ok, eof}; {error, Descriptor, _} -> {error, Descriptor}; {ok, Tokens, _} -> yeccpars1(Tokens, {Mod, Fun, Args}, 0, [], []) end. format_error(Message) -> case io_lib:deep_char_list(Message) of true -> Message; _ -> io_lib:write(Message) end. % To be used in grammar files to throw an error message to the parser toplevel. % Doesn't have to be exported! return_error(Line, Message) -> throw({error, {Line, ?THIS_MODULE, Message}}). % Don't change yeccpars1/6 too much, it is called recursively by yeccpars2/8! yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) -> yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tokenizer); yeccpars1([], {M, F, A}, State, States, Vstack) -> case catch apply(M, F, A) of {eof, Endline} -> {error, {Endline, ?THIS_MODULE, "end_of_file"}}; {error, Descriptor, Endline} -> {error, Descriptor}; {'EXIT', Reason} -> {error, {0, ?THIS_MODULE, Reason}}; {ok, Tokens, Endline} -> case catch yeccpars1(Tokens, {M, F, A}, State, States, Vstack) of error -> Errorline = element(2, hd(Tokens)), {error, {Errorline, ?THIS_MODULE, "syntax error at or after this line."}}; Other -> Other end end; yeccpars1([], false, State, States, Vstack) -> yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false). % For internal use only. yeccerror(Token) -> {error, {element(2, Token), ?THIS_MODULE, ["syntax error before: ", yecctoken2string(Token)]}}. yecctoken2string({atom, _, A}) -> io_lib:write(A); yecctoken2string({integer,_,N}) -> io_lib:write(N); yecctoken2string({float,_,F}) -> io_lib:write(F); yecctoken2string({char,_,C}) -> io_lib:write_char(C); yecctoken2string({var,_,V}) -> io_lib:format('~s', [V]); yecctoken2string({string,_,S}) -> io_lib:write_string(S); yecctoken2string({reserved_symbol, _, A}) -> io_lib:format('~w', [A]); yecctoken2string({Cat, _, Val}) -> io_lib:format('~w', [Val]); yecctoken2string({'dot', _}) -> io_lib:format('~w', ['.']); yecctoken2string({'$end', _}) -> []; yecctoken2string({Other, _}) when atom(Other) -> io_lib:format('~w', [Other]); yecctoken2string(Other) -> io_lib:write(Other). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% yeccpars2(0, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [0 | __Ss], [__T | __Stack]); yeccpars2(0, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(1, '$end', _, __Stack, _, _, _) -> {ok, hd(__Stack)}; yeccpars2(1, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(2, ';', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 27, [2 | __Ss], [__T | __Stack]); yeccpars2(2, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) -> __Val = {alist,__1,nil}, yeccpars2(yeccgoto(alist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(3, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) -> __Val = {name,__1}, yeccpars2(yeccgoto(name, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(4, '=', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 5, [4 | __Ss], [__T | __Stack]); yeccpars2(4, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(5, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [5 | __Ss], [__T | __Stack]); yeccpars2(5, integer, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 7, [5 | __Ss], [__T | __Stack]); yeccpars2(5, '*', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 6, [5 | __Ss], [__T | __Stack]); yeccpars2(5, '{', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 10, [5 | __Ss], [__T | __Stack]); yeccpars2(5, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(6, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 26, [6 | __Ss], [__T | __Stack]); yeccpars2(6, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(7, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) -> __Val = {lit,__1}, yeccpars2(yeccgoto(val, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(8, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) -> __Val = begin existing_name(__1), __1 end, yeccpars2(yeccgoto(val, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(9, '(', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 20, [9 | __Ss], [__T | __Stack]); yeccpars2(9, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) -> __Val = begin new_name(__1), {assign,__1,__3} end, __Nss = lists:nthtail(2, __Ss), yeccpars2(yeccgoto(appl, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(10, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [10 | __Ss], [__T | __Stack]); yeccpars2(10, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(11, ',', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 18, [11 | __Ss], [__T | __Stack]); yeccpars2(11, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) -> __Val = begin new_name(__1), {nlist,__1,nil} end, yeccpars2(yeccgoto(nlist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(12, '|', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 13, [12 | __Ss], [__T | __Stack]); yeccpars2(12, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(13, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [13 | __Ss], [__T | __Stack]); yeccpars2(13, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(14, '|', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 15, [14 | __Ss], [__T | __Stack]); yeccpars2(14, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(15, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [15 | __Ss], [__T | __Stack]); yeccpars2(15, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(16, '}', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 17, [16 | __Ss], [__T | __Stack]); yeccpars2(16, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(17, __Cat, __Ss, [__7,__6,__5,__4,__3,__2,__1|__Stack], __T, __Ts, __Tzr) -> __Val = {lambda,__2,__4,__6}, __Nss = lists:nthtail(6, __Ss), yeccpars2(yeccgoto(val, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(18, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [18 | __Ss], [__T | __Stack]); yeccpars2(18, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(19, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) -> __Val = begin new_name(__1), {nlist,__1,__3} end, __Nss = lists:nthtail(2, __Ss), yeccpars2(yeccgoto(nlist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(20, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [20 | __Ss], [__T | __Stack]); yeccpars2(20, integer, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 7, [20 | __Ss], [__T | __Stack]); yeccpars2(20, '*', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 6, [20 | __Ss], [__T | __Stack]); yeccpars2(20, '{', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 10, [20 | __Ss], [__T | __Stack]); yeccpars2(20, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(21, ',', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 24, [21 | __Ss], [__T | __Stack]); yeccpars2(21, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) -> __Val = {vlist,__1,nil}, yeccpars2(yeccgoto(vlist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(22, ')', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 23, [22 | __Ss], [__T | __Stack]); yeccpars2(22, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(23, __Cat, __Ss, [__6,__5,__4,__3,__2,__1|__Stack], __T, __Ts, __Tzr) -> __Val = begin new_name(__1), {assign,__1,__3,__5} end, __Nss = lists:nthtail(5, __Ss), yeccpars2(yeccgoto(appl, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(24, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [24 | __Ss], [__T | __Stack]); yeccpars2(24, integer, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 7, [24 | __Ss], [__T | __Stack]); yeccpars2(24, '*', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 6, [24 | __Ss], [__T | __Stack]); yeccpars2(24, '{', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 10, [24 | __Ss], [__T | __Stack]); yeccpars2(24, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(25, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) -> __Val = {vlist,__1,__3}, __Nss = lists:nthtail(2, __Ss), yeccpars2(yeccgoto(vlist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(26, __Cat, __Ss, [__2,__1|__Stack], __T, __Ts, __Tzr) -> __Val = {lit,__2}, __Nss = lists:nthtail(1, __Ss), yeccpars2(yeccgoto(val, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(27, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [27 | __Ss], [__T | __Stack]); yeccpars2(27, _, _, _, __T, _, _) -> yeccerror(__T); yeccpars2(28, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) -> __Val = {alist,__1,__3}, __Nss = lists:nthtail(2, __Ss), yeccpars2(yeccgoto(alist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr); yeccpars2(__Other, _, _, _, _, _, _) -> exit({parser, __Other, missing_state_in_action_table}). yeccgoto(alist, 0) -> 1; yeccgoto(alist, 13) -> 14; yeccgoto(alist, 27) -> 28; yeccgoto(appl, 0) -> 2; yeccgoto(appl, 13) -> 2; yeccgoto(appl, 27) -> 2; yeccgoto(name, 0) -> 4; yeccgoto(name, 5) -> 8; yeccgoto(name, 10) -> 11; yeccgoto(name, 13) -> 4; yeccgoto(name, 15) -> 16; yeccgoto(name, 18) -> 11; yeccgoto(name, 20) -> 8; yeccgoto(name, 24) -> 8; yeccgoto(name, 27) -> 4; yeccgoto(nlist, 10) -> 12; yeccgoto(nlist, 18) -> 19; yeccgoto(val, 5) -> 9; yeccgoto(val, 20) -> 21; yeccgoto(val, 24) -> 21; yeccgoto(vlist, 20) -> 22; yeccgoto(vlist, 24) -> 25; yeccgoto(__Symbol, __State) -> exit({__Symbol, __State, missing_in_goto_table}).