Как я могу использовать утверждения в lex? - PullRequest
2 голосов
/ 11 апреля 2011

Мне нужны положительные взгляды за утверждениями в lex (flex 2.5.35). После изучения документации я не вижу прямого способа сделать это. У него есть что-то похожее на предпросмотр (синтаксис r / s), но не взгляд назад. Как лучше всего добиться того же эффекта?

Вот пример: скажем, у меня есть следующие правила в файле спецификации сканера:

a         printf("matched a ");
b         printf("matched b ");
c         printf("matched c ");
d         printf("matched d ");

Как бы я сопоставил «d» после «b» и сам «b», чтобы на входе «abd» я получил:

matched a matched b matched d following b

Но для строки 'acd'

matched a matched c matched d

Правило:

bd        printf("matched d following b ");

явно не работает, так как он потребляет b; для 'abd' выводит:

matched a matched d following b

Если бы у меня был вид сзади, я мог бы написать:

(?<=b)d   printf("matched d following b ");

и все будет хорошо, но lex этого не поддерживает.

Ответы [ 3 ]

1 голос
/ 11 апреля 2011

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

  1. Инвертируйте вашу строку и ищите также инвертированный шаблон. То, что обычно было до того, как ваш паттерн теперь опережает его.

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

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

1 голос
/ 11 апреля 2011

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

%x matched_b
%%
<INITIAL,matched_b>{
    a       { printf("matched a\n"); BEGIN(INITIAL); }
    b       { printf("matched b\n"); BEGIN(matched_b); }
    c       { printf("matched c\n"); BEGIN(INITIAL); }
}

d       printf("matched d\n");
<matched_b>d    { printf("matched d following b\n"); BEGIN(INITIAL); }

С этим сканером я получаю:

$ echo abcd | ./5615080
matched a
matched b
matched c
matched d

$ echo abdd | ./5615080
matched a
matched b
matched d following b
matched d
0 голосов
/ 11 апреля 2011

Для pcre синтаксис выглядит следующим образом:

(?<= ... ) для положительного
(?<! ... ) отрицательного

И pcre требует фиксированного взгляда сзади (положительного или отрицательного).

Если у lex они есть, вероятно, он имеет такую ​​форму.

...