%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1997-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% %CopyrightEnd% %% %% -export([parse/1, parse_and_scan/1, format_error/1]). -import(lists, [reverse/1]). -ifdef(JAM). -compile([{parse_transform,jam_yecc_pj},pj]). -endif. -include("icforms.hrl"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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, ?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, ?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, ?MODULE, "end_of_file"}}; {error, Descriptor, _Endline} -> {error, Descriptor}; {'EXIT', Reason} -> {error, {0, ?MODULE, Reason}}; {ok, Tokens, _Endline} -> case catch yeccpars1(Tokens, {M, F, A}, State, States, Vstack) of error -> Errorline = element(2, hd(Tokens)), {error, {Errorline, ?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), ?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({'dot', _}) -> "'.'"; yecctoken2string({'$end', _}) -> []; yecctoken2string({Other, _}) when is_atom(Other) -> io_lib:format("~w", [Other]); yecctoken2string({_, _, Other}) when is_list(Other) andalso is_number(hd(Other)) -> Other; yecctoken2string({_, _, Other}) -> io_lib:format("~p", [Other]); yecctoken2string(Other) -> io_lib:write(Other). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%