Вопрос

Предположим, у меня есть регулярное выражение lex, например

[aA][0-9]{2,2}[pP][sS][nN]? { return TOKEN; }

Если пользователь вводит

A75PsN
A75PS

Это будет соответствовать

Но если пользователь говорит что-то вроде

A75PKN

Я бы хотел, чтобы он допустил ошибку и сказал: «Символ K не распознан, ожидается S».

Сейчас я просто пишу это так:

let [a-zA-Z]
num [0-9]

{let}{num}{2,2}{let}{2,3}

А затем, по сути, перелексирую строку в Yacc, чтобы у меня были значимые условия ошибки.

Как я могу обойти это?

Единственное, о чем я могу думать, это использовать именованные группы?

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

Решение

Ух ты!Интересная схема.

Если вы собираетесь обнаружить это в лексическом анализаторе, вам понадобится универсальное правило, которое касается «любой иначе нераспознанной строки» и выдает сообщение об ошибке.

Определить, что именно буква «К» стала причиной проблемы, будет настоящим адом.

[^aA][0-9]{2,2}[pP][sS][nN]? { report_error(); return ERROR; }
[aA][0-9]{2,2}[^pP][sS][nN]? { report_error(); return ERROR; }
[aA][0-9]{2,2}[pP][^sS][nN]? { report_error(); return ERROR; }
[aA][0-9]{2,2}[pP][sS][^nN]  { report_error(); return ERROR; }

Обратите внимание на расположение кареток и отсутствие вопросительного знака!Иметь дело с нецифрами, слишком большим количеством цифр или слишком малым количеством цифр - ух!

Как правило, вам лучше распознать все «идентификаторы», а затем проверить, какие из них в порядке:

[a-zA-Z][0-9]{2,2}[a-zA-Z]{2,5} { return validate_id_string(); }

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

Обобщите и упростите регулярное выражение, чтобы оно соответствовало тому, что происходит на самом деле.

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