-
Notifications
You must be signed in to change notification settings - Fork 3
/
x.py
51 lines (42 loc) · 1.24 KB
/
x.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
import pe
X = pe.compile(
r'''
Start <- Expr (EOL Expr)* EOF
Expr <- Term PLUS Expr
/ (Sign Sign)+ Term MINUS Expr
/ Term
Sign <- [-+] Spacing
Term <- Factor TIMES Term
/ Factor DIVIDE Term
/ Factor
Factor <- LPAREN Expr RPAREN
/ Atom
Atom <- NAME / NUMBER
NAME <- [a-bA-B_] [a-bA-B0-9_]* Spacing
NUMBER <- ('0' / [1-9] [0-9]*) Spacing
PLUS <- '+' Spacing
MINUS <- '-' Spacing
TIMES <- '*' Spacing
DIVIDE <- '/' Spacing
LPAREN <- '(' Spacing
RPAREN <- ')' Spacing
EOL <- '\r\n' / [\n\r]
EOF <- [ \t\n\v\f\r]* !.
Spacing <- ' '*
''')
def _match(s):
return X.match(s, flags=pe.STRICT | pe.MEMOIZE)
def test_x():
assert _match('--a-b').end() == 5
assert _match('1 + 2 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + '
'(((((('
'11 * 12 * 13 * 14 * 15 + 16 * 17 + 18 * 19 * 20'
'))))))')
assert _match('2*3 + 4*5*6')
if __name__ == '__main__':
import sys
print(0, end='')
for i, line in enumerate(open(sys.argv[1]), 1):
print(f'\r{i}', end='')
X.match(line, flags=pe.STRICT | pe.MEMOIZE)
print('done')