-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclr_table.py
More file actions
46 lines (40 loc) · 1.92 KB
/
Copy pathclr_table.py
File metadata and controls
46 lines (40 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class CLRTable:
def __init__(self, grammar, states, transitions):
self.grammar = grammar
self.states = states
self.transitions = transitions
self.action = {}
self.goto = {}
self.conflicts = []
def build_table(self):
for i, state in enumerate(self.states):
for item in state:
# ACCEPT
if (item.lhs == self.grammar.start_symbol and
item.dot == len(item.rhs) and
item.lookahead == "$"):
self.action[(i, "$")] = "acc"
# REDUCE — only on item.lookahead
elif item.dot == len(item.rhs) or item.rhs == ['^']:
if item.lhs == self.grammar.start_symbol:
continue
rule = f"{item.lhs} -> {' '.join(item.rhs)}"
terminal = item.lookahead
key = (i, terminal)
new_action = f"r({rule})"
if key in self.action and self.action[key] != new_action:
self.conflicts.append((i, terminal, self.action[key], new_action))
self.action[key] = new_action
# SHIFT / GOTO
else:
symbol = item.rhs[item.dot]
if (i, symbol) in self.transitions:
j = self.transitions[(i, symbol)]
if symbol in self.grammar.terminals:
key = (i, symbol)
new_action = f"s{j}"
if key in self.action and self.action[key] != new_action:
self.conflicts.append((i, symbol, self.action[key], new_action))
self.action[key] = new_action
else:
self.goto[(i, symbol)] = j