Странные лексические ключевые слова против сопоставления идентификаторов регулярному выражению - PullRequest
0 голосов
/ 23 июня 2019

Я изо всех сил пытался понять некоторое поведение flex.

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

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

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

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

Этот первый пример - нерабочий код

%{
#include <iostream>
using namespace std;
%}
%option noyywrap
%%
[ \t\n]                   {cout << "ws" << endl;};
buzz                      {cout << "kw" << endl;};
[^\n]+                    {cout << "str" << endl;};
%%
int main(){
yylex();
}

Второй пример - модифицированная версия, которая работает правильно.

%{
#include <iostream>
using namespace std;
%}
%option noyywrap
%%
[ \t\n]                   {cout << "ws" << endl;};
buzz                      {cout << "kw" << endl;};
[a-zA-Z]+                 {cout << "str" << endl;};
%%
int main(){
yylex();
}

В коде buzz считается ключевым словом, а все, что следует за ним, следует просто читать как строку.

В первом примере гудение поглощается вместе с оставшимся словом как "str".

Во втором примере, жужжание распознано правильно, а оставшееся слово становится "str".

Я понимаю, что третье правило в обоих случаях также является допустимым определением токена, содержащего символы b-u-z-z. Каждая из этих четырех букв находится в [^ \ n] +, а также [a-zA-Z] +. Так почему же поведение отличается?

Пример ввода будет:

buzz lightyear
buzz aldren

Спасибо!

1 Ответ

0 голосов
/ 24 июня 2019

Flex (как и большинство других генераторов лексеров) работает в соответствии с правилом максимального жаворонка.Это правило говорит, что если на текущем входе могут совпадать несколько шаблонов, выбирается тот, который дает самое длинное соответствие.Если несколько шаблонов дают совпадение одинакового размера, выбирается тот, который появляется первым в файле .l.

Таким образом, в вашем рабочем решении шаблоны buzz и [a-zA-Z0-9]+ оба соответствуют buzz,поэтому buzz выбрано потому, что оно появляется первым в файле (если вы переключили две строки, вместо него будет напечатано str).В вашем нерабочем решении buzz все равно будет соответствовать buzz, но [^\n]+ соответствует buzz lightyear и buzz aldren соответственно, что является более длинным соответствием.Таким образом, он выигрывает в соответствии с правилом максимального жаворонка.

...