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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
import sys
import ply.yacc as yacc
from ply.lex import LexToken
# Get the token map from the lexer. This is required.
from lexer import tokens
# Error rule for syntax errors
def p_error(p: LexToken):
if p:
print(f"Unexpected {repr(p.value)} on line {p.lineno}")
else:
print("Unexpected end of file.")
def p_program(p):
'''program : instruction_list
| empty'''
pass
def p_empty(p):
'''empty :'''
pass
def p_inss(p):
'''instruction_list : instruction_list line
| line
'''
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
# print(f"INSes: {len(p)}")
# print(f" {p[1]}")
# if len(p) > 2:
# print(f" {p[2]}")
pass
def p_inss2(p):
'''instruction_list2 : line instruction_list2
| line
'''
if len(p) == 2:
p[0] = [p[1]]
else:
p[0] = [p[1]] + p[2]
print(f"INSes2: {len(p)}")
print(f" {p[1]}")
if len(p) > 2:
print(f" {p[2]}")
pass
def p_line(p):
'''line : instruction NL
| NL
'''
if len(p) == 2:
pass
else:
p[0] = p[1]
def p_instruction(p):
'''instruction : noarg
| onearg
| twoarg
| jumpdest
| invalid_arg
'''
print(f"INS: {p[1]}")
p[0] = p[1]
pass
def p_jumpdest(p):
'''jumpdest : SYMBOL COLON'''
p[0] = (p[1], )
def p_twoarg(p):
'''twoarg : op REG COMMA argument COMMA argument'''
p[0] = (*p[1], p[2], p[4], p[6])
pass
def p_argument(p):
'''argument : number
| REG
| SYMBOL
'''
pass
def p_onearg(p):
'''onearg : op REG COMMA argument'''
p[0] = (*p[1], p[2], p[4], None)
pass
def p_noarg(p):
'''noarg : op'''
p[0] = (*p[1], None, None, None)
pass
def p_invalid_arg(p):
'''invalid_arg : op argument'''
print(f"Invalid opcode, destination missing: {p[1:]}")
sys.exit(1)
pass
def p_op(p):
'''op : OP DOT JUMP
| OP
'''
if len(p) == 2:
p[0] = (p[1], None)
else:
p[0] = (p[1], p[3])
def p_number(p):
'''number : NUMBER
| HEXNUMBER
'''
p[0] = p[1]
parser = yacc.yacc()
|