Rudiments of a recursive descent parser.
Cat's Eye Technologies
12 years ago
0 | 0 | #!/usr/bin/env python |
1 | 1 | |
2 | """An attempt to implement Xoomonk in Python. Embryonic, as of this writing; | |
3 | only includes some runtime support, no parser. | |
2 | """An attempt to implement Xoomonk in Python. | |
4 | 3 | |
5 | 4 | """ |
5 | ||
6 | class Scanner(object): | |
7 | def __init__(self, text): | |
8 | self.text = text | |
9 | self.scan() | |
10 | ||
11 | def scan(self): | |
12 | pass | |
13 | ||
14 | def expect(self, token): | |
15 | if self.token == token: | |
16 | self.scan() | |
17 | else: | |
18 | raise SyntaxError("expected %s" % token) | |
19 | ||
20 | def on(self, token): | |
21 | return self.token == token | |
22 | ||
23 | def consume(self, token): | |
24 | if self.token == token: | |
25 | self.scan() | |
26 | return True | |
27 | else: | |
28 | return False | |
29 | ||
30 | ||
31 | # Parser | |
32 | ||
33 | class Parser(object): | |
34 | def program(self): | |
35 | while not self.scanner.at_end(): | |
36 | self.stmt() | |
37 | ||
38 | def stmt(self): | |
39 | if self.scanner.on("print"): | |
40 | self.print_stmt() | |
41 | else: | |
42 | self.assign() | |
43 | ||
44 | def assign(self): | |
45 | self.ref() | |
46 | self.scanner.expect(":=") | |
47 | self.expr() | |
48 | ||
49 | def print_stmt(self): | |
50 | self.scanner.expect("print") | |
51 | if self.scanner.consume("string"): | |
52 | st = self.scanner.token | |
53 | self.scanner.scan() | |
54 | elif self.scanner.consume("char"): | |
55 | self.expr() | |
56 | else: | |
57 | self.expr() | |
58 | if self.scanner.consume(";"): | |
59 | # mark as no nl | |
60 | pass | |
61 | ||
62 | def expr(self): | |
63 | v = None | |
64 | if self.scanner.on("{"): | |
65 | v = self.block() | |
66 | elif self.scanner.on_pattern(r'\d+'): | |
67 | v = int(self.token) | |
68 | else: | |
69 | v = self.ref() | |
70 | if self.scanner.consume("*"): | |
71 | # v = copy(v) | |
72 | pass | |
73 | return v | |
74 | ||
75 | def block(self): | |
76 | self.scanner.expect("{") | |
77 | while not self.scanner.on("}"): | |
78 | self.stmt() | |
79 | self.scanner.expect("}") | |
80 | ||
81 | def ref(self): | |
82 | self.name() | |
83 | while self.scanner.consume("."): | |
84 | self.name() | |
85 | ||
86 | def name(self): | |
87 | if self.scanner.consume("^"): | |
88 | return "^" | |
89 | elif self.scanner.consume("$"): | |
90 | return self.scanner.token | |
91 | else: | |
92 | return self.scanner.token | |
93 | ||
6 | 94 | |
7 | 95 | # Runtime support for Xoomonk. |
8 | 96 |