diff options
| author | 2024-02-28 12:09:56 +0800 | |
|---|---|---|
| committer | 2024-02-28 12:09:56 +0800 | |
| commit | 8793ecea74706aedb4674434f65ef9d05850b769 (patch) | |
| tree | 425fcec75d4f899760a0919fa0604327b20309f9 /nivis_python/parsers.py | |
| parent | ab026b7e0ba3baa1ffab7603e7f5fa47864427f7 (diff) | |
| download | TRPGNivis-8793ecea74706aedb4674434f65ef9d05850b769.tar.gz TRPGNivis-8793ecea74706aedb4674434f65ef9d05850b769.zip | |
refactor(bones)!: rename nivis-python -> nivis_python
Diffstat (limited to 'nivis_python/parsers.py')
| -rw-r--r-- | nivis_python/parsers.py | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/nivis_python/parsers.py b/nivis_python/parsers.py new file mode 100644 index 0000000..ca004f7 --- /dev/null +++ b/nivis_python/parsers.py @@ -0,0 +1,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}") |
