У меня есть парсер, который выглядит следующим образом:
@dataclass
class Parser:
lex: Lexer
_errors: List[str] = field(default_factory=list)
cur_token: Token = None
peek_token: Token = None
...
def next_token(self) -> None:
self.cur_token = self.peek_token
self.peek_token = self.lex.get_next_token()
def parse_program(self) -> Program:
program = Program()
while not self.cur_token_is(Tokens.EOF):
stmt = self.parse_statement()
if stmt:
program.statements.append(stmt)
self.next_token()
return program
...
def parse_if_expression(self) -> Optional[Expression]:
expression = IfExpression(token=self.cur_token)
if not self.expect_peek(Tokens.IDENT):
return None
expression.condition = self.parse_expression(LOWEST)
if not self.expect_peek(Tokens.THEN):
return None
expression.consequence = self.parse_block_statement([Tokens.ELSE, Tokens.FI])
if self.cur_token_is(Tokens.ELSE):
expression.alternative = self.parse_block_statement(Tokens.FI)
return expression
...
Я могу использовать его простым способом, чтобы получить AST ,
input = "if x < y then x else y fi"
l = Lexer(input)
p = Parser.parser(l)
program = p.parse_program()
Значение что мне нужно будет прочитать весь исходный файл и предоставить его лексеру. Что является хорошим способом заставить этот анализатор читать файл построчно, но при этом иметь возможность распознавать и анализировать многострочные операторы, например, набрав REPL ,
>>> if x < y then
... x
... else
... y
... fi;
>>>
Или читая мой файл, как это,
def readfile(f):
with open(f) as infile:
for line in infile:
yield line