Detect conflicts in the table generation.
This commit is contained in:
parent
edd5ee3d55
commit
c1ecf8e260
1 changed files with 31 additions and 6 deletions
37
parser.py
37
parser.py
|
|
@ -192,6 +192,8 @@ class GenerateLR0(object):
|
|||
the other actions are always associated with terminals.)
|
||||
|
||||
- 'accept': Accept the result of the parse, it worked.
|
||||
|
||||
Anything missing from the row indicates an error.
|
||||
"""
|
||||
action_table = []
|
||||
config_sets = self.gen_all_sets()
|
||||
|
|
@ -202,17 +204,24 @@ class GenerateLR0(object):
|
|||
for config in config_set:
|
||||
if config.at_end:
|
||||
if config.name != '__start':
|
||||
actions.update({
|
||||
a: ('reduce', config.name, len(config.symbols))
|
||||
for a in self.terminals
|
||||
})
|
||||
for a in self.terminals:
|
||||
self.set_table_action(
|
||||
actions,
|
||||
a,
|
||||
('reduce', config.name, len(config.symbols)),
|
||||
)
|
||||
else:
|
||||
actions['$'] = ('accept',)
|
||||
self.set_table_action(actions, '$', ('accept',))
|
||||
|
||||
else:
|
||||
if config.next in self.terminals:
|
||||
successor = self.gen_successor(config_set, config.next)
|
||||
index = self.find_set_index(config_sets, successor)
|
||||
actions[config.next] = ('shift', index)
|
||||
self.set_table_action(
|
||||
actions,
|
||||
config.next,
|
||||
('shift', index),
|
||||
)
|
||||
|
||||
# Gotos
|
||||
for symbol in self.nonterminals:
|
||||
|
|
@ -225,6 +234,22 @@ class GenerateLR0(object):
|
|||
|
||||
return action_table
|
||||
|
||||
def set_table_action(self, row, symbol, action):
|
||||
"""Set the action for 'symbol' in the table row to 'action'.
|
||||
|
||||
This is destructive; it changes the table. It raises an error if
|
||||
there is already an action for the symbol in the row.
|
||||
"""
|
||||
existing = row.get(symbol, None)
|
||||
if existing is not None:
|
||||
raise ValueError(
|
||||
"Conflict: {old} vs {new}",
|
||||
old=existing,
|
||||
new=action,
|
||||
)
|
||||
row[symbol] = action
|
||||
|
||||
|
||||
|
||||
def parse(table, input, trace=False):
|
||||
"""Parse the input with the generated parsing table and return the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue