Browse Source

Better reduce/reduce errors

tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.11.0
Erez Sh 4 years ago
parent
commit
c196f99cd4
1 changed files with 8 additions and 1 deletions
  1. +8
    -1
      lark/parsers/lalr_analysis.py

+ 8
- 1
lark/parsers/lalr_analysis.py View File

@@ -246,13 +246,14 @@ class LALR_Analyzer(GrammarAnalyzer):


def compute_lalr1_states(self): def compute_lalr1_states(self):
m = {} m = {}
reduce_reduce = []
for state in self.lr0_states: for state in self.lr0_states:
actions = {} actions = {}
for la, next_state in state.transitions.items(): for la, next_state in state.transitions.items():
actions[la] = (Shift, next_state.closure) actions[la] = (Shift, next_state.closure)
for la, rules in state.lookaheads.items(): for la, rules in state.lookaheads.items():
if len(rules) > 1: if len(rules) > 1:
raise GrammarError('Reduce/Reduce collision in %s between the following rules: %s' % (la, ''.join([ '\n\t\t- ' + str(r) for r in rules ])))
reduce_reduce.append((la, rules))
if la in actions: if la in actions:
if self.debug: if self.debug:
logger.warning('Shift/Reduce conflict for terminal %s: (resolving as shift)', la.name) logger.warning('Shift/Reduce conflict for terminal %s: (resolving as shift)', la.name)
@@ -261,6 +262,12 @@ class LALR_Analyzer(GrammarAnalyzer):
actions[la] = (Reduce, list(rules)[0]) actions[la] = (Reduce, list(rules)[0])
m[state] = { k.name: v for k, v in actions.items() } m[state] = { k.name: v for k, v in actions.items() }


if reduce_reduce:
msgs = [ 'Reduce/Reduce collision in %s between the following rules: %s'
% (la, ''.join([ '\n\t\t- ' + str(r) for r in rules ]))
for la, rules in reduce_reduce]
raise GrammarError('\n\n'.join(msgs))

states = { k.closure: v for k, v in m.items() } states = { k.closure: v for k, v in m.items() }


# compute end states # compute end states


Loading…
Cancel
Save