#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. О, хорошо, большое спасибо, это было действительно полезно, ценю это.