-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslr.py
71 lines (55 loc) · 2.07 KB
/
slr.py
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class ProductionRule:
def __init__(self, left, right):
self.left = left
self.right = right
stack = '$'
n = int(input('Enter no. of production rules: '))
start_symbol = input('Enter start symbol: ')
print('Enter the productions in the form <NT> -> <RHS> :-')
#List to store all productions
productions = []
for i in range(n):
prod_str_splitted = input().split('->')
rule = ProductionRule(prod_str_splitted[0].strip(), prod_str_splitted[1].strip())
productions.append(rule)
input_str = input('Enter the input string to parse: ')
str_index = 0
early_stop = False # Flag to do early stop for special grammars like the one mentioned at the top.
while True:
if early_stop:
break
ch = ''
if str_index < len(input_str):
ch += input_str[str_index]
str_index += 1
stack += ch
print('Stack: ', stack, end='\t')
print('Buffer: ', input_str[str_index:], end='\t')
print('SHIFT')
j = 0
while j<len(productions):
try:
stack_top = stack.index(productions[j].right)
substr_length = len(productions[j].right)
except ValueError:
j += 1
continue
# Replacing matched part with LHS of production
stack = stack[:stack_top] + productions[j].left + stack[stack_top + substr_length :]
print('Stack: ', stack, end='\t')
print('Buffer: ', input_str[str_index:], end='\t')
print('REDUCE ', productions[j].left + ' -> ' + productions[j].right)
if stack[1:]==start_symbol and str_index==len(input_str):
early_stop = True
print('String accepted')
break
# Restarting loop to check immediate reduction of newly derived production
j = 0
# Accept case
# Stack - Start symbol, Buffer - Empty
if stack[1:]==start_symbol and str_index==len(input_str):
print('String accepted')
break
if str_index==len(input_str):
print('String not accepted')
break