aboutsummaryrefslogtreecommitdiffstats
path: root/lib/parsetools/src/yecc.erl
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2010-03-03 09:51:52 +0000
committerErlang/OTP <[email protected]>2010-03-03 09:51:52 +0000
commit67e5a5f8833a9d090e4e9920f29541870eba34f5 (patch)
tree0a2ba81c2372093091bc89ecae47a1081a7d4fa4 /lib/parsetools/src/yecc.erl
parentf94ff4fb58b9db3926ce0fea2c0fb4b18b1823ca (diff)
downloadotp-67e5a5f8833a9d090e4e9920f29541870eba34f5.tar.gz
otp-67e5a5f8833a9d090e4e9920f29541870eba34f5.tar.bz2
otp-67e5a5f8833a9d090e4e9920f29541870eba34f5.zip
OTP-8483 parsetools: yecc bug
Yecc failed to report reduce/reduce conflicts where one of the reductions involved the root symbol. This bug has been fixed. (Thanks to Manolis Papadakis.)
Diffstat (limited to 'lib/parsetools/src/yecc.erl')
-rw-r--r--lib/parsetools/src/yecc.erl16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index b8b2b2308c..7fb6aae31a 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].
@@ -2078,7 +2090,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) ->