Токенизация оставшихся данных с помощью lex / yacc - PullRequest
3 голосов
/ 08 мая 2009

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

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

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

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

Ответы [ 4 ]

1 голос
/ 11 мая 2009

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

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

'1' 'PLUS' '1'

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

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

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

Equation ::= EXPRESSION

У вас будет

Equation ::= EXPRESSION END_OF_INPUT

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

1 голос
/ 09 мая 2009

Существует встроенный токен error в yacc. Обычно вы делаете что-то вроде:

</p> <p>line: goodline | badline ;</p> <p>badline : error '\n' /* Error-handling action, if needed */</p> <p>goodline : equation '\n' ;

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

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

0 голосов
/ 12 мая 2009

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

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

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

0 голосов
/ 09 мая 2009

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

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

...