-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathonly_syntax.py
102 lines (84 loc) · 2.52 KB
/
only_syntax.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
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
import preamble
from metaparse import Symbol, Rule, Grammar, LALR
from pprint import pprint
class read(type):
class gs(object):
def __init__(self):
self.lexes = []
self.pats = []
self.rules = []
self.prece = {}
def __setitem__(self, k, v):
if not k.startswith('__'):
# lexical tuple
if isinstance(v, tuple):
assert len(v) == 2
l, p = v
self.lexes.append(k)
self.pats.append(l)
self.prece[k] = p
# lexical str
elif isinstance(v, str):
self.lexes.append(k)
self.pats.append(v)
# alternatives
elif isinstance(v, (list, set)):
for alt in v:
if not isinstance(alt, (list, tuple)):
alt = (alt,)
rhs = []
for x in alt:
if isinstance(x, Symbol):
rhs.append(str(x))
elif isinstance(x, str):
self.lexes.append(x)
self.pats.append(None)
rhs.append(x)
self.rules.append(Rule(k, rhs))
#
elif callable(v):
pass
def __getitem__(self, k0):
return Symbol(k0)
@classmethod
def __prepare__(mcls, n, bs, **kw):
return read.gs()
def __new__(mcls, n, bs, gs):
return Grammar(gs.lexes, gs.pats, gs.rules, prece=gs.prece)
class E(metaclass=read):
# IGNORED = r'\s+'
NEG = r'!' , 5
CON = r'&' , 4
DIS = r'\|' , 3
IMP = r'->' , 2
IFF = r'<=>' , 1
W = r'[A-Z]\w*'
Sentence = [
Atomic,
Complex,
]
Atomic = [
'True',
'False',
W,
]
Complex = [
('(', Sentence, ')'),
('[', Sentence, ']'),
(NEG, Sentence),
(Sentence, CON, Sentence),
(Sentence, DIS, Sentence),
(Sentence, IMP, Sentence),
(Sentence, IFF, Sentence),
]
# pprint(E)
# g = Grammar(*E)
# pprint(g)
pprint(E.lex2pats)
p = LALR(E)
# pprint([*p.lexer.tokenize('True & False', True)])
# pprint(p.parse('P & Q | R & !S'))
s = p.dump('meta_dumps.py')
p1 = LALR.load('meta_dumps.py', globals())
# print(s)
pprint(p1.parse('P & Q | R & !S'))