Условия для гибкого - PullRequest
       44

Условия для гибкого

1 голос
/ 25 февраля 2020

Можно ли поместить условные выражения для правил в flex? Это нужно мне для того, чтобы соответствовать определенному правилу c, только когда выполняется какое-то условие. Примерно так:

%option c++
%option noyywrap

%%
/*if (condition) {*/
[0-9] {}
/*}*/
[0-9]{2} {}
.     /* eat up any unmatched character */
%%

void yylex(void);

int main()
{
    FlexLexer *lexer = new yyFlexLexer();
    lexer->yylex();
    delete lexer;
}

Или возможно изменить окончательный сгенерированный код на С ++, чтобы соответствовать только некоторым указанным c правилам регулярных выражений?

ОБНОВЛЕНИЕ:

Использование условий запуска не помогает. То, что я хочу, в зависимости от какой-то внешней переменной (например, isNthRegexActive), чтобы иметь возможность совпадать или не указывать c регулярное выражение. Например, если у меня есть 4 правила регулярных выражений, а первое и второе не активны, программа должна проверять только остальные 2 и всегда проверять их все (не останавливаться при первом совпадении - возможно, используйте REJECT).

Пример для 4 правил:

/* Declared at the top */
isActive[0] = false;
isActive[1] = false;
isActive[2] = true;
isActive[3] = true;

%%
[0-9]{4} { printf("1st: %s\n", yytext); REJECT;}
[0-3]{2}[0-3]{2} { printf("2nd: %s\n", yytext); REJECT; }
[1-3]{2}[0-3]{2} { printf("3rd: %s\n", yytext); REJECT; }
[1-2]{2}[1-2]{2} { printf("4th: %s\n", yytext); REJECT; }
.
%%

Для ввода: 1212 результат должен быть:

3rd: 1212
4th: 1212

1 Ответ

1 голос
/ 25 февраля 2020

Не используйте REJECT, если у вас нет абсолютно никакой альтернативы. Это значительно замедляет лексическое сканирование, искусственно ограничивает размер буфера токенов и очень затрудняет анализ лексического анализа.

Возможно, вы думаете, что сканер, генерируемый (f) lex, проверяет каждую регулярную Выражение по одному, чтобы выбрать лучший для данного соответствия. Это не работает таким образом; это было бы слишком медленно. Что он делает, так это эффективно проверяет все регулярные выражения параллельно, используя предварительно скомпилированный конечный автомат для определения c, представленный в виде таблицы поиска.

Конечный автомат выполняет ровно один переход для каждого входного байта, используя простой O (1) поиск в таблице переходов. (Существуют разные методы сжатия таблиц, которые сравнивают размер таблицы с константой в поиске O (1), но это не меняет основы c logi c.) Это означает, что вы можете использовать как много регулярных выражений по вашему желанию; Время проведения лексического анализа не зависит от количества или сложности регулярных выражений. (За исключением эффектов кэширования: если ваша таблица переходов действительно большая, вы можете начать сталкиваться с промахами кэша во время поиска переходов. В таких случаях вы можете предпочесть алгоритм сжатия, который сжимает больше.)

В большинстве случаев Вы можете использовать начальные условия для достижения условного соответствия, хотя вам может понадобиться много начальных условий, если существует более нескольких взаимодействующих условий. Поскольку у сканера может быть только одно активное условие запуска, вам нужно будет создать разные условия запуска для каждой допустимой комбинации условий, которые вы хотите рассмотреть. Обычно этого легче всего достичь с помощью автоматической c генерации правил вашего сканера, но это, безусловно, можно сделать вручную, если их не слишком много.

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

...