diff options
Diffstat (limited to 'lib/parsetools/src')
-rw-r--r-- | lib/parsetools/src/yecc.erl | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl index b8b2b2308c..c4a47d008f 100644 --- a/lib/parsetools/src/yecc.erl +++ b/lib/parsetools/src/yecc.erl @@ -1582,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, @@ -1773,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} -> @@ -1791,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}; @@ -1830,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]. @@ -1994,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))], @@ -2078,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) -> |