Русская Википедия:Re2c
Шаблон:Заголовок со строчной буквы Шаблон:Программа
re2c (regular expression to c, regular expression to code) — это свободная утилита–генератор, с открытым исходным кодом, генерирует быстрые и легко встраиваемые лексеры, ориентированна на работу совместно с языками: Си, C++, Go, Rust.
Изначально утилита была создана Питером Бамбулисом (Шаблон:Lang-en) и описана в его статье[1], позже re2c был передан в общественное достояние и с тех пор поддерживается добровольцами[2].
Утилита отличается от своих более известных аналогов (таких как lex и flex) тем, что имеет гибкий интерфейс взаимодействия (сгенерированный код взаимодействует с внешней программой с помощью примитивов), генерирует оптимизированные нетабличные лексеры, поддерживает захваты (submatch extraction) на основе детерминированных конечных автоматов с тэгами (TDFA).
Утилита в основном распространена в проектах, где требуется высокая скорость анализа синтаксиса, например Ninja[3] и PHP[4].
Философия
Основная цель re2c — генерировать быстрые лексеры[1], по крайней мере настолько же быстрые, как и разумно оптимизированные лексеры, написанные вручную на языке Си. Вместо использования традиционного табличного подхода re2c кодирует сгенерированный конечный автомат непосредственно в форме условных переходов и сравнений. В результате программа работает быстрее, чем её аналог на основе таблиц[1], и её гораздо проще отлаживать и понимать. Более того, такой подход часто приводит к уменьшению размера лексеров[1], поскольку re2c применяет ряд оптимизаций, таких как минимизация ДКА и построение туннельного автомата[5]. Еще одной отличительной особенностью re2c является его гибкий интерфейс. Вместо того, чтобы использовать фиксированный шаблон программы, re2c позволяет программисту написать большую часть кода интерфейса и адаптировать сгенерированный лексер к любой конкретной среде. Основная идея заключается в том, что re2c должен быть абстракцией с нулевыми затратами для программиста, использование утилиты никогда не должно приводить к более медленной работе программы, чем соответствующая реализация с вручную написанным кодом.
Возможности
- Захваты submatch extraction[6] — re2c поддерживает как группы захвата, совместимые с POSIX, так и отдельные тэги[7].
Реализация основана на алгоритме «lookahead-TDFA»[8][9][10];
- Поддержка различных кодировок[11] — re2c поддерживает ASCII, UTF-8, UTF-16, UTF-32, UCS-2 и EBCDIC;
- Гибкий пользовательский интерфейс[12] — сгенерированный код использует несколько примитивных операций для взаимодействия с окружающей средой (считывание входных символов, переход к следующей позиции ввода и т. д.). Пользователи могут переопределять эти примитивы так, как им необходимо;
- Сохраняемое состояние[13] — re2c поддерживает как лексеры pull-модели (когда лексер работает без прерываний и при необходимости извлекает больше входных данных), так и лексеры push-модели (когда лексер периодически останавливается и возобновляется для анализа новых блоков ввода);
- Условия запуска[14] — re2c может генерировать несколько взаимосвязанных уровней, где каждый лексер запускается определенным условием в программе;
- Само-проверка[15] — re2c имеет специальный режим, в котором он игнорирует весь код интерфейса, определенный пользователем, и генерирует автономную программу-скелет. Кроме того, re2c генерирует два файла — один со строками ввода, полученными из обычной грамматики, и один со сжатыми результатами сверки, которые используются для проверки поведения лексера на всех входах. Входные строки генерируются так, чтобы они широко охватывали переходы и пути ДКА. Генерация данных происходит сразу после построения ДКА и до любых оптимизаций, но сам лексер полностью оптимизирован, поэтому программы-скелеты способны выявлять любые ошибки в оптимизации и генерации кода;
- Система предупреждений[16] — re2c выполняет статический анализ программы и предупреждает своих пользователей о возможных неопределённостях или ошибках, таких как неопределённый поток управления, недостижимый код, неправильно экранированные escape-символы и потенциальное неправильное использование примитивов интерфейса;
- Отладка — помимо создания удобочитаемых лексеров, re2c имеет ряд опций, которые выводят различные промежуточные представления сгенерированного лексера, такие как НКА, несколько этапов ДКА и результирующий программный график в формате языка DOT[17].
Синтаксис
Программа re2c может содержать любое количество блоков /*!re2c ... */
. Каждый блок состоит из последовательности правил, определений и конфигураций (их можно смешивать, но, как правило, лучше сначала размещать конфигурации, затем — определения, а затем — правила). Правила имеют вид — REGEXP { CODE }
или REGEXP := CODE;
, где REGEXP
— регулярное выражение, а CODE
— является блоком кода на языке Си. Когда REGEXP
совпадает с входной строкой, поток управления передаётся соответствующему блоку CODE
. Существует одно специальное правило: правило по умолчанию с *
вместо REGEXP
, оно срабатывает, если никакие другие правила не совпадают. re2c имеет семантику жадного соответствия — если несколько правил совпадают, предпочтительным является правило, соответствующее более длинному префиксу, если конфликтующие правила соответствуют одному и тому же префиксу, то более раннее правило имеет приоритет. Определения имеют вид NAME = REGEXP;
(и, соответственно, NAME { REGEXP }
в Flex-совместимом режиме). Конфигурации имеют вид re2c:CONFIG = VALUE;
, где CONFIG
является именем конкретной конфигурации и VALUE
является числом или строкой. Для более расширенного использования ознакомьтесь с официальным руководством re2c[18].
Регулярные выражения
re2c использует следующий синтаксис для регулярных выражений:
"foo"
строковый литерал с чувствительностью к регистру;'foo'
строковый литерал без чувствительности к регистру;[a-xyz]
,[^a-xyz]
класс символов (с возможностью отрицания);.
любой возможный символ, кроме символа новой строки;R \ S
разница в классах символов;R*
нуль или большее количество совпадений с символомR
;R+
одно или большее количество совпадений с символомR
;R?
необязательное совпадение с символомR
(нуль или одно);R{n}
повторениеR
точноn
раз;R{n,}
повторениеR
по крайней мереn
раз;R{n,m}
повторениеR
отn
доm
раз;(R)
простоR
(круглые скобки используются для переопределения приоритета или для соответствия в стиле POSIX);R S
конкатенацияR
, за которой следуетS
;R | S
альтернативаR
илиS
;R / S
поиск с опережением (Шаблон:Lang-en)R
, за которой следуетS
;name
регулярное выражение, определенное какname
(за исключением режима совместимости с Flex);@stag
s-метка (с Шаблон:Lang-en — метка или тэг) — сохраняет последнюю позицию ввода, в которой@stag
совпадает с переменной с именемstag
;#mtag
m-метка — сохраняет все позиции ввода, в которых#mtag
совпадает с переменной с именемmtag
.
Классы символов и строковые литералы могут содержать следующие escape-последовательности: \a
, \b
, \f
, \n
, \r
, \t
, \v
, \\
, восьмеричного вида \ooo
и шестнадцатеричного вида \xhh
, \uhhhh
, \Uhhhhhhhh
.
Примеры кода
Программные проекты, использующие re2c
- PHP — популярный язык сценариев общего назначения[4];
- Ninja — система сборки, ориентированная на скорость[3];
- SpamAssassin — программа для фильтрации спама электронной почты[19];
- BRL-CAD — программа 3D-моделирования (САПР)[20];
- STEPCode — имплементация стандарта ISO 10303[21];
- Yasm — модульный ассемблер, полная переработка NASM[22];
- Wake — инструмент для сборки от SiFive[23].
См. также
- Синтаксис
- Синтаксический анализ
- Лексический анализ
- Подсветка синтаксиса
- Стандарт оформления кода
- Lex
Примечания
Ссылки
- ↑ 1,0 1,1 1,2 1,3 Шаблон:Статья
- ↑ Шаблон:Cite web
- ↑ 3,0 3,1 Шаблон:Cite web
- ↑ 4,0 4,1 Шаблон:Cite web
- ↑ Шаблон:Статья
- ↑ Шаблон:Cite web
- ↑ Шаблон:Статья
- ↑ Шаблон:Cite journal
- ↑ Шаблон:Статья
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web
- ↑ Шаблон:Cite web