Парсер остановка-возобновление функциональности - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть парсер, который выглядит следующим образом:

@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
...