Лексер обработки ошибок PLY Python - PullRequest
3 голосов
/ 27 ноября 2011

Функция t_error () используется для обработки ошибок лексизма, возникающих при обнаружении недопустимых символов.Мой вопрос: как я могу использовать эту функцию, чтобы получить более конкретную информацию об ошибках?Как тип ошибки, в каком правиле или разделе появляется ошибка и т. Д.

Ответы [ 3 ]

3 голосов
/ 28 ноября 2011

В общем, для функции t_error () доступна только очень ограниченная информация. В качестве входных данных он получает маркерный объект, значение которого было установлено для оставшегося входного текста. Анализ этого текста полностью зависит от вас. Вы можете использовать функцию t.lexer.skip (n), чтобы лексер пропустил определенное количество символов, и это все.

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

Мой совет таков: если вам нужна дополнительная информация в функции t_error (), вы должны установить какой-либо объект, который будет использоваться совместно компонентами lexer и parser вашего кода. Вы должны явно заставить разные части вашего компилятора обновлять этот объект по мере необходимости (например, он может обновляться в определенных грамматических правилах).

Кроме того, как правило, существует очень мало путей действия для плохого жетона. По сути, вы получаете вводимый текст, который не содержит какой-либо известной части алфавита языка (например, нет известного символа). Таким образом, нет даже никакого значения токена, которое вы можете дать парсеру. Обычно единственный способ действия - сообщить о неверном вводе, выбросить его и продолжить.

В качестве продолжения ответа Раймонда я бы также не советовал изменять какой-либо атрибут объекта лексера в t_error ().

1 голос
/ 09 марта 2012

В PLY действительно есть способ управления ошибками, взгляните на это очень интересное представление:

http://www.slideshare.net/dabeaz/writing-parsers-and-compilers-with-ply

и в главе 6.8.1

http://www.dabeaz.com/ply/ply.html#ply_nn3

1 голос
/ 27 ноября 2011

Ply включает в себя пример лексера стиля ANSI-C в файле с именем cpp.py .В нем есть пример того, как извлечь некоторую информацию из t_error ():

def t_error(t):
    t.type = t.value[0]
    t.value = t.value[0]
    t.lexer.skip(1)
    return t

В этой функции вы также можете получить доступ к публичным атрибутам лексера:

  • lineno - номер текущей строки
  • lexpos - текущая позиция во входной строке

Существуют также некоторые другие атрибуты, которые не перечислены как открытыено может обеспечить некоторую полезную диагностику:

  • lexstate - Текущее состояние лексера
  • lexstatestack - Стек состояний лексера
  • lexstateinfo - информация о состоянии
  • lexerrorf - правило ошибки (если есть)
...