From 5a0b1654a9716b16993d851f9e617d3b33c35ec9 Mon Sep 17 00:00:00 2001 From: John Doty Date: Thu, 8 Dec 2016 06:28:21 -0800 Subject: [PATCH] Conflicting examples. --- parser.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/parser.py b/parser.py index 5682114..aee2e6d 100644 --- a/parser.py +++ b/parser.py @@ -1,6 +1,7 @@ # This is doty playing with parser tables. from collections import namedtuple + class Configuration( namedtuple('Configuration', ['name', 'symbols', 'position']) ): @@ -188,8 +189,8 @@ class GenerateLR0(object): def gen_table(self): """Generate the parse table. - The parse table is a list of states. The first state in the list is the starting - state. Each state is a dictionary that maps a symbol to an + The parse table is a list of states. The first state in the list is + the starting state. Each state is a dictionary that maps a symbol to an action. Each action is a tuple. The first element of the tuple is a string describing what to do: @@ -259,16 +260,13 @@ class GenerateLR0(object): there is already an action for the symbol in the row. """ existing = row.get(symbol, None) - if existing is not None: + if existing is not None and existing != action: raise ValueError( - "Conflict: {old} vs {new}", - old=existing, - new=action, + "Conflict: {old} vs {new}".format(old=existing, new=action) ) row[symbol] = action - def parse(table, input, trace=False): """Parse the input with the generated parsing table and return the concrete syntax tree. @@ -370,7 +368,7 @@ def format_table(generator, table): return '\n'.join(lines) -# OK, this is +# OK, this is a very simple LR0 grammar. grammar_simple = [ ('E', ['E', '+', 'T']), ('E', ['T']), @@ -383,5 +381,25 @@ table = gen.gen_table() tree = parse(table, ['id', '+', '(', 'id', ')']) print(format_node(tree)) -grammar_lr0_conflict = [ -] +# This one doesn't work with LR0, though, it has a shift/reduce conflict. +try: + grammar_lr0_conflict = grammar_simple + [ + ('T', ['id', '[', 'E', ']']), + ] + gen = GenerateLR0(grammar_lr0_conflict, 'E') + table = gen.gen_table() + assert False +except ValueError as e: + print(e) + +# Nor does this: it has a reduce/reduce conflict. +try: + grammar_lr0_conflict = grammar_simple + [ + ('E', ['V', '=', 'E']), + ('V', ['id']), + ] + gen = GenerateLR0(grammar_lr0_conflict, 'E') + table = gen.gen_table() + assert False +except ValueError as e: + print(e)