From 7624c7d2c056370061c9d3d9256b3e8fd69e8713 Mon Sep 17 00:00:00 2001 From: Fehr Mathieu Date: Mon, 12 Jun 2023 13:26:28 +0200 Subject: [PATCH] core: Create ParserState (NFC) (#1114) `ParserState` is used to encapsulate the state of a given parser. This will allow us to share the state between parsers, so we can better separate the parser code. For instance, when encountering an affine expression, an `AffineParser` will be created with that state, and will take care of parsing the expression. --- xdsl/parser.py | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/xdsl/parser.py b/xdsl/parser.py index 1cea4c1266..351a1a290d 100644 --- a/xdsl/parser.py +++ b/xdsl/parser.py @@ -178,6 +178,22 @@ def operand_name(self) -> str: return self.span.text[1:] +@dataclass(init=False) +class ParserState: + """ + The parser state. It contains the lexer, and the next token to parse. + The parser state should be shared between all parsers, so parsers can + share the same position. + """ + + lexer: Lexer + current_token: Token + + def __init__(self, lexer: Lexer): + self.lexer = lexer + self.current_token = lexer.lex() + + class Parser(ABC): """ Basic recursive descent parser. @@ -212,10 +228,7 @@ class Parser(ABC): This field map a name and a tuple index to the forward declared SSA value. """ - lexer: Lexer - - _current_token: Token - """Token at the current location""" + parser_state: ParserState T_ = TypeVar("T_") """ @@ -231,9 +244,8 @@ def __init__( input: str, name: str = "", allow_unregistered_dialect: bool = False, - ): - self.lexer = Lexer(Input(input, name)) - self._current_token = self.lexer.lex() + ) -> None: + self.parser_state = ParserState(Lexer(Input(input, name))) self.ctx = ctx self.ssa_values = dict() self.blocks = dict() @@ -248,6 +260,18 @@ def resume_from(self, pos: Position): self.lexer.pos = pos self._current_token = self.lexer.lex() + @property + def _current_token(self) -> Token: + return self.parser_state.current_token + + @_current_token.setter + def _current_token(self, token: Token): + self.parser_state.current_token = token + + @property + def lexer(self) -> Lexer: + return self.parser_state.lexer + @property def pos(self) -> Position: """Get the position of the next token."""