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