212
|
1
|
|
2
|
|
3
|
|
4 class Token:
|
|
5 pass
|
|
6
|
|
7 # Base functions:
|
|
8 class Pbase:
|
|
9 def __init__(self):
|
|
10 self.pa = None
|
|
11 def parse(self, txt):
|
|
12 r = self.do(txt)
|
|
13 if r:
|
|
14 match, rest = r
|
|
15 # Apply action:
|
|
16 if self.ParseAction:
|
|
17 match = self.ParseAction(match)
|
|
18 return match, rest
|
|
19 else:
|
|
20 # TODO: fail in some way
|
|
21 pass
|
|
22 def getParseAction(self):
|
|
23 return self.pa
|
|
24 def setParseAction(self, pa):
|
|
25 self.pa = pa
|
|
26
|
|
27 ParseAction = property(getParseAction, setParseAction)
|
|
28
|
|
29 # basic elements:
|
|
30
|
|
31 class Literal(Pbase):
|
|
32 def __init__(self, s):
|
|
33 super().__init__()
|
|
34 self.pat = s
|
|
35 def do(self, txt):
|
|
36 if txt.startswith(self.pat):
|
|
37 return self.pat, txt[len(self.pat):]
|
|
38
|
|
39 class Or(Pbase):
|
|
40 def __init__(self, options):
|
|
41 super().__init__()
|
|
42 self.options = options
|
|
43 def do(self, txt):
|
|
44 for option in self.options:
|
|
45 r = option.parse(txt)
|
|
46 if r:
|
|
47 return r
|
|
48
|
|
49 class And:
|
|
50 def __init__(self, options):
|
|
51 self.options = options
|
|
52
|
|
53 class Sequence(Pbase):
|
|
54 def __init__(self, seq):
|
|
55 super().__init__()
|
|
56 self.seq = seq
|
|
57 def do(self, txt):
|
|
58 results = []
|
|
59 for thung in self.seq:
|
|
60 r = thung.parse(txt)
|
|
61 if r:
|
|
62 res, txt = r
|
|
63 results.append(res)
|
|
64 else:
|
|
65 return
|
|
66 return results, txt
|
|
67
|
|
68 class Optional(Pbase):
|
|
69 def __init__(self, thung):
|
|
70 super().__init__()
|
|
71 self.thung = thung
|
|
72 def do(self, txt):
|
|
73 r = self.thung.do(txt)
|
|
74 if r:
|
|
75 return r
|
|
76 return (0, txt)
|
|
77
|
|
78 # Contraptions of basic blocks:
|
|
79
|
|
80 def OneOrMore():
|
|
81 def __init__(self, thingy):
|
|
82 pass
|
|
83
|