Токенизация оставшихся данных с помощью lex / yacc

StackOverflow https://stackoverflow.com/questions/841159

  •  20-08-2019
  •  | 
  •  

Вопрос

Простите меня, я совершенно новичок в синтаксическом анализе и lex / yacc, и я, вероятно, перегибаю палку, но тем не менее:

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

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

Кто-нибудь знает, как я могу определить, по сути, токен "поймать все, что осталось"?Или есть лучший способ, которым я могу справиться с этим?

Это было полезно?

Решение

Имеется встроенный error токен в yacc.Обычно вы бы сделали что-то вроде:

линия:хорошая линия | плохая линия ;

плохая линия :ошибка '\ n' /* Действие по обработке ошибок, если необходимо */

goodline : equation '\n' ;

Любая строка, которая не совпадает equation будет обработан badline.

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

Другие советы

Определите токен (конец ввода) и сделайте так, чтобы ваш лексер выводил его в конце ввода.

Так что раньше, если у вас были эти токены:

'1' 'PLUS' '1'

Теперь у вас есть:

'1' 'PLUS' '1' 'END_OF_INPUT'

Теперь вы можете определить правило верхнего уровня в вашем парсере. Вместо (например):

Equation ::= EXPRESSION

У вас будет

Equation ::= EXPRESSION END_OF_INPUT

Очевидно, вам придется переписать их в синтаксисе PLY, но это должно помочь вам в большей части.

Обычно я использую отдельное «средство чтения команд», чтобы получить полную команду - возможно, строку в вашем случае - в строку переменных хоста, а затем организую анализатор строки для лексического анализатора, в том числе сообщая мне, когда это не так ». Дойти до конца. Это сложно настроить, но упростит некоторые классы отчетов об ошибках. В одном из мест, где я обычно использовал эту технику, есть многострочные команды с тремя соглашениями о комментариях, двумя наборами строк в кавычках и некоторыми другими неприятностями, чтобы поставить мои зубы на край (контекстно-зависимый токенизация - чёрт!).

В противном случае совет Дона с токеном 'ошибки' Yacc хорош.

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

Вы говорите, что используете PLY, но это потому, что вы хотите, чтобы компилятор работал в среде Python? Если это так, вы можете рассмотреть и другие инструменты. Для таких работ я часто использую ANTLR ( http://www.antlr.org ), в котором есть генератор кода Python , У ANTLR есть много хитростей для выполнения таких вещей, как съедение множества входных данных на уровне лексера, поэтому парсер никогда не видит его (например, комментарии), возможность вызывать подправило (например, уравнение) в пределах более крупной грамматики (которая должна заканчиваться, как только Правило было найдено без дополнительной обработки ввода ... звучит как то, что вы хотите сделать) и очень хороший алгоритм левого факторинга.

Возможность разбора ANTLR в сочетании с использованием StringTemplate ( http://www.stringtemplate.org ) Движок делает хорошую комбинацию, и оба поддерживают Python (среди многих других).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top