Восстановление токенов ошибок при разборе (Lemon) - PullRequest
4 голосов
/ 20 июля 2010

Я использую Lemon в качестве генератора синтаксического анализатора, его обработка ошибок такая же, как у yacc и bison, если вы не знаете Lemon.

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

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

input ::= string(A) { printf("%s", A); } // Print the result
string(A) ::= string(B) part(C). { A = append(B, C); }
string(A) ::= part(B). { A = B; }
part(A) ::= NUMBER(B) NAME(C). { A = append(C, B); } // Rearrange the number and name
part(A) ::= error(B). { A = B; } // On error keep the token anyways

На входе:

"Username 1234Joseph"

Я получаю вывод:

"Joseph1234"

Поскольку текст «Имя пользователя» не поддерживается парсером в части(A) :: = ошибка (B) правило, но я действительно хочу:

"Username Joseph1234"

в качестве вывода.

Если вы можете решить эту проблему в бизоне или другом генераторе синтаксического анализатора, я бы принялчто как ответ :) 1019 *

Ответы [ 2 ]

2 голосов
/ 06 июня 2012

При использовании yacc / bison ошибка синтаксического анализа переводит инструмент в режим устранения ошибок, если это возможно.Он попытается сбросить токены на пути к «чистому» состоянию.

Мне не удалось найти ссылку на lemon, поэтому я не могу показать какой-нибудь лимонный код, чтобы это исправить, но с yacc / bison можно использовать правила здесь .

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

Например, если грамматика, определенная как MyOther, MyOther увидела MyTok MyOther:

stack
MyTok: "the text"
MyOther: "new text"

stack
MyOther: "the text"
MyOther: "new text"

Чтобы выполнить это, посмотрите на использование yybackup .Я не могу найти альтернативный метод, хотя yybackup осуждается.

2 голосов
/ 28 мая 2011

Это старый, но почему бы и нет ...

Грамматика должна включать пробелы. На данный момент грамматика допускает только последовательность токенов NUMBER NAME (без пробелов между токенами).

...