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:
51
token SIGN: "-(?![a-zA-Z_])"
52
token AND: "(?<![-\w])and(?![-\w])"
53
token OR: "(?<![-\w])or(?![-\w])"
54
token NOT: "(?<![-\w])not(?![-\w])"
64
token UNITS: "(?<!\s)(?:px|cm|mm|hz|%)(?![-\w])"
65
token NUM: "(?:\d+(?:\.\d*)?|\.\d+)"
66
token BOOL: "(?<![-\w])(?:true|false)(?![-\w])"
67
token COLOR: "#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])"
68
token VAR: "\$[-a-zA-Z0-9_]+"
69
token FNCT: "[-a-zA-Z_][-a-zA-Z0-9_]*(?=\()"
70
token ID: "[-a-zA-Z_][-a-zA-Z0-9_]*"
71
rule goal<<R>>: expr_lst<<R>> {{ v = expr_lst.first() if len(expr_lst) == 1 else expr_lst }}
73
rule expr<<R>>: and_test<<R>> {{ v = and_test }}
75
OR and_test<<R>> {{ v = and_test if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v or and_test) }}
77
rule and_test<<R>>: not_test<<R>> {{ v = not_test }}
79
AND not_test<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v and not_test) }}
81
rule not_test<<R>>: comparison<<R>> {{ return comparison }}
84
NOT not_test<<R>> {{ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else (not not_test) }}
86
INV not_test<<R>> {{ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else _inv('!', not_test) }}
88
rule comparison<<R>>: a_expr<<R>> {{ v = a_expr }}
90
LT a_expr<<R>> {{ 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) }}
92
GT a_expr<<R>> {{ 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) }}
94
LE a_expr<<R>> {{ 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) }}
96
GE a_expr<<R>> {{ 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) }}
98
EQ a_expr<<R>> {{ 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) }}
100
NE a_expr<<R>> {{ 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) }}
102
rule a_expr<<R>>: m_expr<<R>> {{ v = m_expr }}
104
ADD m_expr<<R>> {{ 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) }}
106
SUB m_expr<<R>> {{ 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) }}
108
rule m_expr<<R>>: u_expr<<R>> {{ v = u_expr }}
110
MUL u_expr<<R>> {{ 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) }}
112
DIV u_expr<<R>> {{ 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) }}
114
rule u_expr<<R>>: SIGN u_expr<<R>> {{ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else _inv('-', u_expr) }}
116
ADD u_expr<<R>> {{ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else u_expr }}
118
atom<<R>> {{ v = atom }}
120
UNITS {{ v = call(UNITS, ListValue(ParserValue({0: v, 1: UNITS})), R, False) }}
122
rule atom<<R>>: LPAR expr_lst<<R>> RPAR {{ return expr_lst.first() if len(expr_lst) == 1 else expr_lst }}
128
expr_lst<<R>> {{ v = expr_lst }}
129
] RPAR {{ return call(FNCT, v, R) }}
131
NUM {{ return NumberValue(ParserValue(NUM)) }}
133
STR {{ return StringValue(ParserValue(STR)) }}
135
QSTR {{ return QuotedStringValue(ParserValue(QSTR)) }}
137
BOOL {{ return BooleanValue(ParserValue(BOOL)) }}
139
COLOR {{ return ColorValue(ParserValue(COLOR)) }}
141
VAR {{ return interpolate(VAR, R) }}
142
rule expr_lst<<R>>: {{ n = None }}
146
] {{ else: self._rewind() }}
148
expr_slst<<R>> {{ v = {n or 0: expr_slst} }}
150
COMMA {{ v['_'] = COMMA }}
154
] {{ else: self._rewind() }}
156
expr_slst<<R>> {{ v[n or len(v)] = expr_slst }}
157
)* {{ return ListValue(ParserValue(v)) }}
158
rule expr_slst<<R>>: expr<<R>> {{ v = {0: expr} }}
160
expr<<R>> {{ v[len(v)] = expr }}
161
)* {{ return ListValue(ParserValue(v)) if len(v) > 1 else v[0] }}
163
expr_lst_rsts_ = None
166
################################################################################
168
P = Calculator(CalculatorScanner())
171
def parse(rule, text, *args):
173
return wrap_error_reporter(P, rule, *args)
176
if __name__ == '__main__':
179
s = raw_input('>>> ')
184
print parse('goal', s, None)