SLR1 parsing.
This commit is contained in:
parent
8d0726b3a4
commit
86bd8fffc8
1 changed files with 20 additions and 3 deletions
23
parser.py
23
parser.py
|
|
@ -190,6 +190,13 @@ class GenerateLR0(object):
|
||||||
return i
|
return i
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def gen_reduce_set(self, config):
|
||||||
|
"""Return the set of symbols that indicate we should reduce the given
|
||||||
|
config.
|
||||||
|
|
||||||
|
In an LR0 parser, this is just the set of all terminals."""
|
||||||
|
return self.terminals
|
||||||
|
|
||||||
def gen_table(self):
|
def gen_table(self):
|
||||||
"""Generate the parse table.
|
"""Generate the parse table.
|
||||||
|
|
||||||
|
|
@ -227,7 +234,7 @@ class GenerateLR0(object):
|
||||||
for config in config_set:
|
for config in config_set:
|
||||||
if config.at_end:
|
if config.at_end:
|
||||||
if config.name != '__start':
|
if config.name != '__start':
|
||||||
for a in self.terminals:
|
for a in self.gen_reduce_set(config):
|
||||||
self.set_table_action(
|
self.set_table_action(
|
||||||
actions,
|
actions,
|
||||||
a,
|
a,
|
||||||
|
|
@ -397,6 +404,12 @@ class GenerateSLR1(GenerateLR0):
|
||||||
assert None not in follow # Should always ground out at __start
|
assert None not in follow # Should always ground out at __start
|
||||||
return follow
|
return follow
|
||||||
|
|
||||||
|
def gen_reduce_set(self, config):
|
||||||
|
"""Return the set of symbols that indicate we should reduce the given
|
||||||
|
config.
|
||||||
|
|
||||||
|
In an SLR1 parser, this is the follow set of the config nonterminal."""
|
||||||
|
return self.gen_follow(config.name)
|
||||||
|
|
||||||
|
|
||||||
def parse(table, input, trace=False):
|
def parse(table, input, trace=False):
|
||||||
|
|
@ -469,7 +482,7 @@ def format_table(generator, table):
|
||||||
elif action[0] == 'reduce':
|
elif action[0] == 'reduce':
|
||||||
return 'r' + str(action[1])
|
return 'r' + str(action[1])
|
||||||
|
|
||||||
header = " | {terms} | {nts}".format(
|
header = " | {terms} | {nts}".format(
|
||||||
terms=' '.join(
|
terms=' '.join(
|
||||||
'{0: <6}'.format(terminal)
|
'{0: <6}'.format(terminal)
|
||||||
for terminal in (generator.terminals)
|
for terminal in (generator.terminals)
|
||||||
|
|
@ -484,7 +497,7 @@ def format_table(generator, table):
|
||||||
header,
|
header,
|
||||||
'-' * len(header),
|
'-' * len(header),
|
||||||
] + [
|
] + [
|
||||||
"{index} | {actions} | {gotos}".format(
|
"{index: <3} | {actions} | {gotos}".format(
|
||||||
index=i,
|
index=i,
|
||||||
actions=' '.join(
|
actions=' '.join(
|
||||||
'{0: <6}'.format(format_action(row, terminal))
|
'{0: <6}'.format(format_action(row, terminal))
|
||||||
|
|
@ -553,3 +566,7 @@ except ValueError as e:
|
||||||
gen = GenerateSLR1('E', grammar_lr0_shift_reduce)
|
gen = GenerateSLR1('E', grammar_lr0_shift_reduce)
|
||||||
print("First: {first}".format(first=str(gen.gen_first(['E']))))
|
print("First: {first}".format(first=str(gen.gen_first(['E']))))
|
||||||
print("Follow: {follow}".format(follow=str(gen.gen_follow('E'))))
|
print("Follow: {follow}".format(follow=str(gen.gen_follow('E'))))
|
||||||
|
table = gen.gen_table()
|
||||||
|
print(format_table(gen, table))
|
||||||
|
tree = parse(table, ['id', '+', '(', 'id', '[', 'id', ']', ')'])
|
||||||
|
print(format_node(tree) + "\n")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue