-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspyro_parser.py
More file actions
194 lines (159 loc) · 5.45 KB
/
spyro_parser.py
File metadata and controls
194 lines (159 loc) · 5.45 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
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
import ply.yacc
from lexer import SpyroSygusLexer
from spyro_ast import *
class SpyroSygusParser(object):
tokens = SpyroSygusLexer.tokens
def p_program(self, p):
"""program : target_fun_plus declare_language declare_semantics"""
p[0] = Program(p[1], p[2], p[3])
self._ast_root = p[0]
def p_target_fun_plus(self, p):
"""target_fun_plus : target_fun_plus target_fun
| target_fun"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_target_fun(self, p):
"""target_fun : TK_LPAREN TK_TARGET_FUN TK_SYMBOL TK_LPAREN arg_plus TK_RPAREN arg term TK_RPAREN"""
p[0] = TargetFunctionCommand(p[3], p[5], p[7], p[8])
def p_arg_plus(self, p):
"""arg_plus : arg_plus arg
| arg"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_arg(self, p):
"""arg : TK_LPAREN TK_SYMBOL sort TK_RPAREN"""
p[0] = (p[2], p[3])
def p_sort_star(self, p):
"""sort_star : sort_plus
| """
if 2 == len(p):
p[0] = p[1]
else:
p[0] = []
def p_sort_plus(self, p):
"""sort_plus : sort_plus sort
| sort"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_sort(self, p):
"""sort : TK_SYMBOL"""
p[0] = SortExpression(p[1])
def p_symbol(self, p):
"""symbol : TK_SYMBOL"""
p[0] = IdentifierTerm(p[1])
def p_numeral(self, p):
"""numeral : TK_NUMERAL"""
p[0] = NumeralTerm(p[1])
def p_app(self, p):
"""app : TK_LPAREN TK_SYMBOL term_star TK_RPAREN"""
p[0] = FunctionApplicationTerm(p[2], p[3])
def p_term_star(self, p):
"""term_star : term_plus
| """
if 2 == len(p):
p[0] = p[1]
else:
p[0] = []
def p_term_plus(self, p):
"""term_plus : term_plus term
| term"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_term(self, p):
"""term : symbol
| numeral
| app"""
p[0] = p[1]
def p_declare_language(self, p):
"""declare_language : TK_LPAREN TK_DECLARE_LANGUAGE TK_LPAREN nonterminal_plus TK_RPAREN TK_LPAREN syntactic_rule_plus TK_RPAREN TK_RPAREN"""
p[0] = DeclareLanguageCommand(p[4], p[7])
def p_nonterminal_plus(self, p):
"""nonterminal_plus : nonterminal_plus nonterminal
| nonterminal"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_nonterminal(self, p):
"""nonterminal : TK_LPAREN TK_SYMBOL sort TK_RPAREN"""
p[0] = (p[2], p[3])
def p_syntactic_rule_plus(self, p):
"""syntactic_rule_plus : syntactic_rule_plus syntactic_rule
| syntactic_rule"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_syntactic_rule(self, p):
"""syntactic_rule : TK_LPAREN production_plus TK_RPAREN"""
p[0] = SyntacticRule(p[2])
def p_production_plus(self, p):
"""production_plus : production_plus production
| production"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_production(self, p):
"""production : TK_LPAREN TK_PRODUCTION TK_SYMBOL sort_star TK_RPAREN """
p[0] = ProductionRule(p[3], p[4])
def p_declare_semantics(self, p):
"""declare_semantics : TK_LPAREN TK_DECLARE_SEMANTICS sem_plus TK_RPAREN"""
p[0] = DeclareSemanticsCommand(p[3])
def p_sem_plus(self, p):
"""sem_plus : sem_plus sem
| sem"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_sem(self, p):
"""sem : TK_LPAREN TK_SYMBOL match term TK_RPAREN"""
p[0] = SemanticRule(p[2], p[3], p[4])
def p_match(self, p):
"""match : TK_LPAREN TK_PRODUCTION TK_SYMBOL var_star TK_RPAREN"""
p[0] = ProductionMatch(p[3], p[4])
def p_var_star(self, p):
"""var_star : var_plus
| """
if 2 == len(p):
p[0] = p[1]
else:
p[0] = []
def p_var_plus(self, p):
"""var_plus : var_plus TK_SYMBOL
| TK_SYMBOL"""
if 2 == len(p):
p[0] = [p[1]]
else:
p[0] = p[1] + [p[2]]
def p_error(self, p):
if p:
print(f"Line {p.lineno}: Parsing error at '{p.value}'")
else:
print("Parsing error at EOF")
def __init__(self):
self.parser = ply.yacc.yacc(debug=False, module=self, start="program")
self.input_string = None
self.lexer = None
self._ast_root = None
def _parse(self, reset: bool = True):
self.parser.parse(self.input_string, lexer=self.lexer.lexer)
if not reset:
return self._ast_root
self.input_string = None
result = self._ast_root
self._ast_root = None
return result
def parse(self, input_string):
self.input_string = input_string
self.lexer = SpyroSygusLexer()
return self._parse()