diff options
Diffstat (limited to 'lib/parsetools/src/yecc.erl')
-rw-r--r-- | lib/parsetools/src/yecc.erl | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl index f4d76f471d..c4a47d008f 100644 --- a/lib/parsetools/src/yecc.erl +++ b/lib/parsetools/src/yecc.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% %% 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 online 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. -%% +%% %% %CopyrightEnd% %% %% Yacc like LALR-1 parser generator for Erlang. @@ -30,8 +30,8 @@ -import(lists, [append/1, append/2, concat/1, delete/2, filter/2, flatmap/2, foldl/3, foldr/3, foreach/2, keydelete/3, - keysearch/3, keysort/2, last/1, map/2, member/2, - reverse/1, sort/1, usort/1]). + keysort/2, last/1, map/2, member/2, reverse/1, + sort/1, usort/1]). -include("erl_compile.hrl"). -include("ms_transform.hrl"). @@ -297,18 +297,18 @@ options(Options0, [Key | Keys], L) when is_list(Options0) -> false -> Options0 end, - V = case keysearch(Key, 1, Options) of - {value, {Key, Filename0}} when Key =:= includefile; - Key =:= parserfile -> + V = case lists:keyfind(Key, 1, Options) of + {Key, Filename0} when Key =:= includefile; + Key =:= parserfile -> case is_filename(Filename0) of no -> badarg; Filename -> {ok, [{Key, Filename}]} end; - {value, {Key, Bool}} when Bool =:= true; Bool =:= false -> - {ok, [{Key, Bool}]}; - {value, {Key, _}} -> + {Key, Bool} = KB when is_boolean(Bool) -> + {ok, [KB]}; + {Key, _} -> badarg; false -> {ok, [{Key, default_option(Key)}]} @@ -348,8 +348,7 @@ atom_option(verbose) -> {verbose, true}; atom_option(Key) -> Key. is_filename(T) -> - try filename:flatten(T) of - Filename -> Filename + try filename:flatten(T) catch error: _ -> no end. @@ -366,8 +365,8 @@ shorten_filename(Name0) -> start(Infilex, Options) -> Infile = assure_extension(Infilex, ".yrl"), - {value, {_, Outfilex0}} = keysearch(parserfile, 1, Options), - {value, {_, Includefilex}} = keysearch(includefile, 1, Options), + {_, Outfilex0} = lists:keyfind(parserfile, 1, Options), + {_, Includefilex} = lists:keyfind(includefile, 1, Options), Outfilex = case Outfilex0 of [] -> filename:rootname(Infilex, ".yrl"); _ -> Outfilex0 @@ -715,14 +714,14 @@ names(Symbols) -> map(fun(Symbol) -> Symbol#symbol.name end, Symbols). symbol_line(Name, St) -> - {value, #symbol{line = Line}} = symbol_search(Name, St#yecc.all_symbols), + #symbol{line = Line} = symbol_find(Name, St#yecc.all_symbols), Line. symbol_member(Symbol, Symbols) -> - symbol_search(Symbol#symbol.name, Symbols) =/= false. + symbol_find(Symbol#symbol.name, Symbols) =/= false. -symbol_search(Name, Symbols) -> - keysearch(Name, #symbol.name, Symbols). +symbol_find(Name, Symbols) -> + lists:keyfind(Name, #symbol.name, Symbols). states_and_goto_table(St0) -> St1 = create_symbol_table(St0), @@ -876,8 +875,8 @@ add_warnings(SymNames, W0, St0) -> check_rhs([#symbol{name = '$empty'}], St) -> St; check_rhs(Rhs, St0) -> - case symbol_search('$empty', Rhs) of - {value, #symbol{line = Line}} -> + case symbol_find('$empty', Rhs) of + #symbol{line = Line} -> add_error(Line, illegal_empty, St0); false -> foldl(fun(Sym, St) -> @@ -1096,10 +1095,10 @@ compute_states2([{Sym,Seed} | Seeds], N, Try, CurrState, StateTab, Tables) -> compute_states2(Seeds, N, Try, CurrState, StateTab, Tables); {merge, M, NewCurrent} -> %% io:fwrite(<<"Merging with state ~w\n">>, [M]), - Try1 = case keysearch(M, 1, Try) of + Try1 = case lists:keyfind(M, 1, Try) of false -> [{M, NewCurrent} | Try]; - {value, {_, OldCurrent}} -> + {_, OldCurrent} -> case ordsets:is_subset(NewCurrent, OldCurrent) of true -> Try; @@ -1583,6 +1582,11 @@ find_action_conflicts2(Rs, Cxt0) -> find_reduce_reduce([R], Cxt) -> {R, Cxt}; +find_reduce_reduce([accept=A, #reduce{}=R | Rs], Cxt0) -> + Confl = conflict(R, A, Cxt0), + St = conflict_error(Confl, Cxt0#cxt.yecc), + Cxt = Cxt0#cxt{yecc = St}, + find_reduce_reduce([R | Rs], Cxt); find_reduce_reduce([#reduce{head = Categ1, prec = {P1, _}}=R1, #reduce{head = Categ2, prec = {P2, _}}=R2 | Rs], Cxt0) -> #cxt{res = Res0, yecc = St0} = Cxt0, @@ -1774,6 +1778,8 @@ add_conflict(Conflict, St) -> case Conflict of {Symbol, StateN, _, {reduce, _, _, _}} -> St#yecc{reduce_reduce = [{StateN,Symbol} |St#yecc.reduce_reduce]}; + {Symbol, StateN, _, {accept, _}} -> + St#yecc{reduce_reduce = [{StateN,Symbol} |St#yecc.reduce_reduce]}; {Symbol, StateN, _, {shift, _, _}} -> St#yecc{shift_reduce = [{StateN,Symbol} | St#yecc.shift_reduce]}; {_Symbol, _StateN, {one_level_up, _, _}, _Confl} -> @@ -1792,6 +1798,8 @@ conflict(#reduce{rule_nmbr = RuleNmbr1}, NewAction, Cxt) -> #cxt{terminal = Symbol, state_n = N, yecc = St} = Cxt, {R1, RuleLine1, RuleN1} = rule(RuleNmbr1, St), Confl = case NewAction of + accept -> + {accept, St#yecc.rootsymbol}; #reduce{rule_nmbr = RuleNmbr2} -> {R2, RuleLine2, RuleN2} = rule(RuleNmbr2, St), {reduce, R2, RuleN2, RuleLine2}; @@ -1831,7 +1839,10 @@ format_conflict({Symbol, N, Reduce, Confl}) -> {shift, NewState, Sym} -> io_lib:fwrite(<<" shift to state ~w, adding right " "sisters to ~s.">>, - [NewState, format_symbol(Sym)]) + [NewState, format_symbol(Sym)]); + {accept, Rootsymbol} -> + io_lib:fwrite(<<" reduce to rootsymbol ~s.">>, + [format_symbol(Rootsymbol)]) end, [S1, S2, S3]. @@ -1995,14 +2006,16 @@ output_actions(St0, StateJumps, StateInfo) -> %% Not all the clauses of the dispatcher function yeccpars2() can %% be reached. Only when shifting, that is, calling yeccpars1(), %% will yeccpars2() be called. - Y2CL = [NewState || {_State,{Actions,_J}} <- StateJumps, - {_LA, #shift{state = NewState}} <- Actions], + Y2CL = [NewState || {_State,{Actions,J}} <- StateJumps, + {_LA, #shift{state = NewState}} <- + (Actions + ++ [A || {_Tag,_To,Part} <- [J], A <- Part])], Y2CS = ordsets:from_list([0 | Y2CL]), Y2S = ordsets:from_list([S || {S,_} <- StateJumps]), NY2CS = ordsets:subtract(Y2S, Y2CS), Sel = [{S,true} || S <- ordsets:to_list(Y2CS)] ++ [{S,false} || S <- ordsets:to_list(NY2CS)], - + SelS = [{State,Called} || {{State,_JActions}, {State,Called}} <- lists:zip(StateJumps, lists:keysort(1, Sel))], @@ -2079,7 +2092,7 @@ output_action(St0, State, Terminal, #shift{state = NewState}, IsFirst, _SI) -> output_action(St0, State, Terminal, accept, IsFirst, _SI) -> St10 = delim(St0, IsFirst), St = fwrite(St10, - <<"yeccpars2_~w(_S, ~s, _Ss, Stack, _T, _Ts, _Tzr) ->\n">>, + <<"yeccpars2_~w(_S, ~s, _Ss, Stack, _T, _Ts, _Tzr) ->\n">>, [State, quoted_atom(Terminal)]), fwrite(St, <<" {ok, hd(Stack)}">>, []); output_action(St, _State, _Terminal, nonassoc, _IsFirst, _SI) -> |