blob: ca004f7556818a91a280895b875024f1bdf672ca (
plain) (
blame)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
from .lexer import Lexer, Token
__all__ = ["Parser"]
class Parser:
"""
A class representing a parser for Psi code.
Args:
input: The input code to be parsed.
Returns:
None
Example:
```python
parser = Parser(input)
parser.parse()
```
"""
def __init__(self, input):
"""
Initializes a Parser object.
Args:
input: The input code to be parsed.
Returns:
None
"""
self.lexer = Lexer(input)
self.tokens = iter(self.lexer)
self.current_token = next(self.tokens)
def parse(self):
"""
Parses the input code.
Returns:
The result of the parsing.
"""
return self.parse_expr()
def parse_expr(self):
"""
Parses an expression in the input code.
Returns:
The result of the parsing.
"""
token = self.current_token
if token.value == "?":
self.eat("?")
condition = self.parse_condition()
self.eat(":")
if condition:
result = self.parse_reply()
else:
result = None
return result
def parse_condition(self):
"""
Parses a condition in the input code.
Returns:
The result of the parsing.
"""
variable = self.parse_variable()
self.eat("==")
value = self.parse_value()
return variable == value
def parse_variable(self):
"""
Parses a variable in the input code.
Returns:
The result of the parsing.
"""
token = self.current_token
self.eat("IDENTIFIER")
return token.value
def parse_value(self):
"""
Parses a value in the input code.
Returns:
The result of the parsing.
Raises:
Exception: Raised when an invalid value is encountered.
"""
token = self.current_token
if token.type == "INTEGER":
self.eat("INTEGER")
return token.value
else:
raise Exception(f"Invalid value: {token.value}")
def parse_reply(self):
"""
Parses a reply in the input code.
Returns:
The result of the parsing.
Raises:
Exception: Raised when an invalid reply is encountered.
"""
self.eat("reply")
self.eat(":")
token = self.current_token
if token.type != "SEPARATOR":
raise Exception(f"Invalid reply: {token.value}")
return token.value
def eat(self, expected_type):
"""
Consumes the current token if it matches the expected type.
Args:
expected_type: The expected type of the token.
Returns:
None
Raises:
Exception: Raised when an unexpected token is encountered.
"""
if self.current_token.type == expected_type:
self.current_token = next(self.tokens)
else:
raise Exception(f"Unexpected token: {self.current_token.value}")
|