1
# python yapps2.py grammar.g grammar.py
4
_units = ['em', 'ex', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'deg', 'rad'
5
'grad', 'ms', 's', 'hz', 'khz', '%']
7
ParserValue = lambda s: s
8
NumberValue = lambda s: float(s)
9
StringValue = lambda s: s
10
QuotedStringValue = lambda s: s
11
BooleanValue = lambda s: bool(s)
12
ColorValue = lambda s: s
14
def __init__(self, v):
15
if isinstance(v, self.__class__):
25
def _reorder_list(lst):
26
return dict((i if isinstance(k, int) else k, v) for i, (k, v) in enumerate(sorted(lst.items())))
29
def interpolate(v, R):
33
def call(fn, args, R, function=True):
34
print 'call: ', fn, args
37
################################################################################
38
#'(?<!\\s)(?:' + '|'.join(_units) + ')(?![-\\w])'
39
## Grammar compiled using Yapps:
46
class CalculatorScanner(Scanner):
50
('[ \r\t\n]+', '[ \r\t\n]+'),
59
('SIGN', '-(?![a-zA-Z_])'),
60
('AND', '(?<![-\\w])and(?![-\\w])'),
61
('OR', '(?<![-\\w])or(?![-\\w])'),
62
('NOT', '(?<![-\\w])not(?![-\\w])'),
72
('UNITS', '(?<!\\s)(?:px|cm|mm|hz|%)(?![-\\w])'),
73
('NUM', '(?:\\d+(?:\\.\\d*)?|\\.\\d+)'),
74
('BOOL', '(?<![-\\w])(?:true|false)(?![-\\w])'),
75
('COLOR', '#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])'),
76
('VAR', '\\$[-a-zA-Z0-9_]+'),
77
('FNCT', '[-a-zA-Z_][-a-zA-Z0-9_]*(?=\\()'),
78
('ID', '[-a-zA-Z_][-a-zA-Z0-9_]*'),
81
def __init__(self, input=None):
82
if hasattr(self, 'setup_patterns'):
83
self.setup_patterns(self._patterns)
84
elif self.patterns is None:
85
self.__class__.patterns = []
86
for t, p in self._patterns:
87
self.patterns.append((t, re.compile(p)))
88
super(CalculatorScanner, self).__init__(None, ['[ \r\t\n]+'], input)
91
class Calculator(Parser):
93
expr_lst = self.expr_lst(R)
94
v = expr_lst.first() if len(expr_lst) == 1 else expr_lst
95
END = self._scan('END')
99
and_test = self.and_test(R)
101
while self._peek(self.expr_rsts) == 'OR':
102
OR = self._scan('OR')
103
and_test = self.and_test(R)
104
v = and_test if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v or and_test)
107
def and_test(self, R):
108
not_test = self.not_test(R)
110
while self._peek(self.and_test_rsts) == 'AND':
111
AND = self._scan('AND')
112
not_test = self.not_test(R)
113
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v and not_test)
116
def not_test(self, R):
117
_token_ = self._peek(self.not_test_rsts)
118
if _token_ not in self.not_test_chks:
119
comparison = self.comparison(R)
121
else: # in self.not_test_chks
123
_token_ = self._peek(self.not_test_chks)
125
NOT = self._scan('NOT')
126
not_test = self.not_test(R)
127
v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else (not not_test)
129
INV = self._scan('INV')
130
not_test = self.not_test(R)
131
v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else _inv('!', not_test)
132
if self._peek(self.not_test_rsts_) not in self.not_test_chks:
136
def comparison(self, R):
137
a_expr = self.a_expr(R)
139
while self._peek(self.comparison_rsts) in self.comparison_chks:
140
_token_ = self._peek(self.comparison_chks)
142
LT = self._scan('LT')
143
a_expr = self.a_expr(R)
144
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v < a_expr)
145
elif _token_ == 'GT':
146
GT = self._scan('GT')
147
a_expr = self.a_expr(R)
148
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v > a_expr)
149
elif _token_ == 'LE':
150
LE = self._scan('LE')
151
a_expr = self.a_expr(R)
152
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v <= a_expr)
153
elif _token_ == 'GE':
154
GE = self._scan('GE')
155
a_expr = self.a_expr(R)
156
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v >= a_expr)
157
elif _token_ == 'EQ':
158
EQ = self._scan('EQ')
159
a_expr = self.a_expr(R)
160
v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) == (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr)
162
NE = self._scan('NE')
163
a_expr = self.a_expr(R)
164
v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) != (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr)
168
m_expr = self.m_expr(R)
170
while self._peek(self.a_expr_rsts) in self.a_expr_chks:
171
_token_ = self._peek(self.a_expr_chks)
173
ADD = self._scan('ADD')
174
m_expr = self.m_expr(R)
175
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v + m_expr)
177
SUB = self._scan('SUB')
178
m_expr = self.m_expr(R)
179
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v - m_expr)
183
u_expr = self.u_expr(R)
185
while self._peek(self.m_expr_rsts) in self.m_expr_chks:
186
_token_ = self._peek(self.m_expr_chks)
188
MUL = self._scan('MUL')
189
u_expr = self.u_expr(R)
190
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v * u_expr)
192
DIV = self._scan('DIV')
193
u_expr = self.u_expr(R)
194
v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v / u_expr)
198
_token_ = self._peek(self.u_expr_rsts)
199
if _token_ == 'SIGN':
200
SIGN = self._scan('SIGN')
201
u_expr = self.u_expr(R)
202
return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else _inv('-', u_expr)
203
elif _token_ == 'ADD':
204
ADD = self._scan('ADD')
205
u_expr = self.u_expr(R)
206
return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else u_expr
207
else: # in self.u_expr_chks
210
if self._peek(self.u_expr_rsts_) == 'UNITS':
211
UNITS = self._scan('UNITS')
212
v = call(UNITS, ListValue(ParserValue({0: v, 1: UNITS})), R, False)
216
_token_ = self._peek(self.u_expr_chks)
217
if _token_ == 'LPAR':
218
LPAR = self._scan('LPAR')
219
expr_lst = self.expr_lst(R)
220
RPAR = self._scan('RPAR')
221
return expr_lst.first() if len(expr_lst) == 1 else expr_lst
222
elif _token_ == 'ID':
223
ID = self._scan('ID')
225
elif _token_ == 'FNCT':
226
FNCT = self._scan('FNCT')
228
LPAR = self._scan('LPAR')
229
if self._peek(self.atom_rsts) != 'RPAR':
230
expr_lst = self.expr_lst(R)
232
RPAR = self._scan('RPAR')
233
return call(FNCT, v, R)
234
elif _token_ == 'NUM':
235
NUM = self._scan('NUM')
236
return NumberValue(ParserValue(NUM))
237
elif _token_ == 'STR':
238
STR = self._scan('STR')
239
return StringValue(ParserValue(STR))
240
elif _token_ == 'QSTR':
241
QSTR = self._scan('QSTR')
242
return QuotedStringValue(ParserValue(QSTR))
243
elif _token_ == 'BOOL':
244
BOOL = self._scan('BOOL')
245
return BooleanValue(ParserValue(BOOL))
246
elif _token_ == 'COLOR':
247
COLOR = self._scan('COLOR')
248
return ColorValue(ParserValue(COLOR))
250
VAR = self._scan('VAR')
251
return interpolate(VAR, R)
253
def expr_lst(self, R):
255
if self._peek(self.expr_lst_rsts) == 'VAR':
256
VAR = self._scan('VAR')
257
if self._peek(self.expr_lst_rsts_) == '":"':
261
expr_slst = self.expr_slst(R)
262
v = {n or 0: expr_slst}
263
while self._peek(self.expr_lst_rsts__) == 'COMMA':
265
COMMA = self._scan('COMMA')
267
if self._peek(self.expr_lst_rsts) == 'VAR':
268
VAR = self._scan('VAR')
269
if self._peek(self.expr_lst_rsts_) == '":"':
273
expr_slst = self.expr_slst(R)
274
v[n or len(v)] = expr_slst
275
return ListValue(ParserValue(v))
277
def expr_slst(self, R):
280
while self._peek(self.expr_slst_rsts) not in self.expr_lst_rsts__:
283
return ListValue(ParserValue(v)) if len(v) > 1 else v[0]
285
not_test_rsts_ = set(['AND', 'LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR'])
286
m_expr_chks = set(['MUL', 'DIV'])
287
comparison_rsts = set(['LPAR', 'QSTR', 'RPAR', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'ADD', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'GE', 'BOOL', 'NOT', 'OR'])
288
atom_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'NOT', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'RPAR', 'ID'])
289
not_test_chks = set(['NOT', 'INV'])
290
u_expr_chks = set(['LPAR', 'COLOR', 'QSTR', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID'])
291
m_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'MUL', 'DIV', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR'])
292
expr_lst_rsts_ = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'BOOL', '":"', 'STR', 'NOT', 'ID', 'FNCT'])
293
expr_lst_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'NOT', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID'])
294
and_test_rsts = set(['AND', 'LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR'])
295
u_expr_rsts_ = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'VAR', 'MUL', 'DIV', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'UNITS', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR'])
296
u_expr_rsts = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'VAR', 'ID'])
297
expr_rsts = set(['LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'ID', 'RPAR', 'OR'])
298
not_test_rsts = set(['LPAR', 'QSTR', 'COLOR', 'INV', 'SIGN', 'VAR', 'ADD', 'NUM', 'BOOL', 'FNCT', 'STR', 'NOT', 'ID'])
299
comparison_chks = set(['GT', 'GE', 'NE', 'LT', 'LE', 'EQ'])
300
expr_slst_rsts = set(['LPAR', 'QSTR', 'END', 'COLOR', 'INV', 'RPAR', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BOOL', 'SIGN', 'ID'])
301
a_expr_chks = set(['ADD', 'SUB'])
302
a_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'INV', 'ADD', 'BOOL', 'NOT', 'OR'])
303
expr_lst_rsts__ = set(['END', 'COMMA', 'RPAR'])
306
expr_lst_rsts_ = None
309
################################################################################
311
P = Calculator(CalculatorScanner())
314
def parse(rule, text, *args):
316
return wrap_error_reporter(P, rule, *args)
319
if __name__ == '__main__':
322
s = raw_input('>>> ')
327
print parse('goal', s, None)