如何将具有多个非终端生成的EBNF转换为函数调用

时间:2018-10-23 14:15:09

标签: python compiler-construction ebnf

我正在学习编译器的构造,并且已经设法创建了可以解释简单代码行的小型Python脚本。但是,我正在努力实现提供非终端产品选择的EBNF语句的正确方法。让我们以这个EBNF为例:

expression ::= term
               | expression '+' term
               | expression '-' term

term       ::= factor
               | term '*' factor
               | term '/' factor

factor     ::= NUMBER
               | '(' expression ')'

这是EBNF,用于解释简单的数学表达式,例如5 *(3 + 4)。

从编译器文献中,我了解了使用if语句识别终端符号(令牌)的基本方法,对于非终端生产,我们将其称为子函数。有了这些知识,我就能编写解释factor的函数:

def factor():
    if token.type == 'NUMBER':
        number = token.value
        eat('NUM')
        return number
    elif token.type == '(':
        eat('(')
        expr = self.expression()
        eat(')')
        return expr

实现expressionterm非终端的推荐方法是什么?我使用了peek()函数来向前看一个令牌:

def expression():
    next_token = peek()
    if token.type in ['NUMBER', '('] and next_token.type == '+':
        expression = expression(token)
        eat('+')
        term = term()
        return (expression, '+', term)
    elif token.type in ['NUMBER', '('] and next_token.type == '-':
        expression = expression(token)
        eat('-')
        term = term()
        return (expression, '-', term)
    elif token.type in ['NUMBER', '(']:
        term = term()
        return term

我感到很奇怪,我必须查看两个级别的EBNF(termfactor)以找到可以用来决定在{ {1}}(与expression中一样)。我不确定的另一件事是,if token.type in ['NUMBER', '('] and next_token.type == '+':上方的方法需要最后测试。这意味着测试EBNF中非终端生产的顺序变得很重要。这是正确的方法吗?

0 个答案:

没有答案