Ошибка недопустимого токена RPLY с момента добавления печати

#python-3.x #parsing

#python-3.x #синтаксический анализ

Вопрос:

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

 Traceback (most recent call last):
  File "e:/ParserAndLexer/main.py", line 14, in <module>
    result = parser.parse(lexer.lex(command)).eval()
  File "C:Python38libsite-packagesrplyparser.py", line 60, in parse
    self.error_handler(lookahead)
  File "e:ParserAndLexermain_parser.py", line 46, in error_handle
    raise ValueError(f"Invalid token {token}")
ValueError: Invalid token Token('INTEGER', '5')
  

Эта ошибка начала возникать только с тех пор, как я добавил оператор печати в свой анализатор, до тех пор мой код работал нормально. Я использовал его следующим образом

 print(parser.parse(lexer.lex('5   5')).eval())
  

Когда я использую инструкцию print, я получаю следующий вывод.

 print(parser.parse(lexer.lex('print(5   5)')).eval())

>>> 10
>>> None
  

Я не знаю, откуда берется None. Мой код находится в этой вставке.

Комментарии:

1. Пожалуйста, включите свой код в вопрос, а не ссылайтесь на внешний ресурс, который может перестать работать в будущем.

2. Хорошо, извините, я это сделаю

Ответ №1:

Мне было немного сложно понять ваш вопрос. Сначала вы говорите, что синтаксический анализ выдает исключение, а затем показываете, что синтаксический анализ работает должным образом (за исключением того, что вы, очевидно, не ожидали, что функция print напечатает свой аргумент).

Но я предполагаю, что вы имеете в виду, что когда вы изменяете грамматику, чтобы включить print оператор, он выдает ошибки на ранее принятых входных данных.

Начнем со второго вопроса: None возвращается ли значение, возвращаемое eval методом AST, возвращаемым parser.parse . Перед возвратом eval реализовал print оператор, напечатав аргумент. None затем печатается, потому что вы печатаете значение, возвращаемое eval методом. (Возможно, вы захотите запретить печать None вместо печати любых результатов eval.)

Если вы имеете в виду, что новая грамматика не принимает то, что приняла старая грамматика, это, по-видимому, потому, что старая грамматика приняла выражение в качестве входных данных. Возможно, первоначальное первое правило было Program : expression или, может быть, первое правило было правилом для expression нетерминального. Трудно сказать, не видя также старую грамматику. Но очевидно, что ваша новая грамматика указывает Program в качестве начального символа и Program соответствует только вводу, который начинается с токена print . Если первым токеном является что-то другое, например целое число 5, вы можете ожидать, что будет произведена синтаксическая ошибка, поскольку не существует производства, для Program которого применяется.

Если вы хотите, чтобы сгенерированный синтаксический анализатор принимал либо print оператор, либо простое выражение, вам нужно добавить производство, которое позволяет это.

Комментарии:

1. О, хорошо, большое спасибо, это было действительно полезно, ценю это.