Как преобразовать EBNF с множеством нетерминальных производств в вызовы функций - PullRequest
0 голосов
/ 23 октября 2018

Я изучаю конструкцию компилятора и уже успел создать небольшие скрипты 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

Каков рекомендуемый способ реализации нетерминалов expression и term?Я использовал функцию 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 (term и factor), чтобы найтитерминальные символы, которые я могу использовать, чтобы решить, какой из вариантов сделать в expression (как в if token.type in ['NUMBER', '('] and next_token.type == '+':).Другая вещь, в которой я не уверен, заключается в том, что подход выше term должен быть проверен последним.Это означает, что порядок проверки нетерминальных производств в EBNF становится важным.Это правильный способ сделать это?

...