Сопоставьте ввод со строкой, используя lex - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь сопоставить префикс строки Что-то .Например, если ввести So, SOM, SomeTH, some, S , все это принимается, поскольку все они являются префиксами Something .

Мой код

Ss[oO]|Ss[omOMOmoM] {
        printf("Accept Something": %s\n", yytext);
}

Вход

Som

Выход

Accept Something: So
Invalid Character

Предполагается прочитать Сом , потому что этоэто префикс Что-то .Я не понимаю, почему мой код не работает.Может кто-нибудь поправить меня в том, что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Прямо сейчас ваш код (как показано) должен соответствовать только "Sso" или "SsO" или "Ssm" или "SsM".

У вас есть две альтернативы, каждая из которых начинается с Ss (без квадрата)скобки) так что те будут совпадать буквально.Затем следует либо [oO], либо [omOMomoM], но символы в квадратных скобках представляют альтернативы, так что это эквивалентно [oOmM] --ie, любому одному из символов o, O, m или M.

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

Тогда, вероятно, проще всего просто перечислить альтернативы буквально:

s|so|som|some|somet|someth|somethi|somethin|something { printf("found prefix"); }

Я думаю, вы можете сделать шаблон немного короче (по крайней мере, в исходном коде), выполнив что-то в этом порядке:

s(o(m(e(t(h(i(n(n(g)?)?)?)?)?)?)?)?)? { printf("found prefix"); }

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

Если вы не хотите использовать %option caseless, базовая идея помогаетбольше:

[sS]([oO]([mM]([eE]([tT]([hH]([iI]([nN]([gG])?)?)?)?)?)?)?)? { printf("found prefix"); }

Перечисление всех возможных комбинаций верхнего и нижнего регистра будет утомительным.

0 голосов
/ 02 октября 2018

Я не знаю, что вы думаете о значении

Ss[oO]|Ss[omOMOmoM]

, но оно соответствует либо:

  • S, за которым следует s следуют ровно за одной из букв o или O, или
  • и S, за которыми следует s, за которыми следует ровно одна из букв o, O, m или M.Помещение символа более одного раза в выражение в скобках не имеет никакого эффекта.

Кроме того, я не вижу, как это может привести к выводу, о котором вы сообщаете.Возможно, произошла ошибка копирования и вставки, или, возможно, у вас есть другие правила шаблона.

Если вы хотите сопоставить префиксы, используйте вложенные необязательные совпадения:

s(o(m(e(t(h(i(ng?)?)?)?)?)?)?)?

Если вы хотите регистр- нечувствительные совпадения, вы можете написать все классы персонажей, но это становится утомительным;проще использовать флаг без учета регистра:

(?i:s(o(m(e(t(h(i(ng?)?)?)?)?)?)?)?)

(?i: включает флаг i nsensitive, пока не будет найдена закрывающая скобка.

На практике это, вероятно, не что вы хотите.Обычно вы хотите распознать полное слово в качестве токена.Затем вы можете проверить, является ли слово префиксом в действии правила:

[[:alpha:]]+    { if (yyleng <= strlen("something") && 0 == strncasemp(yytext, "something", yyleng) { 
                  /* do something */
                  } 
                }

В руководстве Flex содержится много информации *1040*.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...