Несколько парсеров flex/bison
Каков наилучший способ обработки нескольких парсеров Flex/Bison внутри проекта?
Я написал парсер, и теперь мне нужен второй в том же проекте. Пока что в третьем разделе parser1.y
Я вставил main(..)
метод и называется yyparse
оттуда.
Я хочу получить два разных парсера (parser1.y
а также parser2.y
) и сможете использовать их из внешней функции (предположим, main
в main.cpp
).
Какие меры предосторожности следует использовать для экспорта yyparse
функции снаружи .y
файлы и как мне обрабатывать два парсера?
PS. Я использую g++ для компиляции, но не версии C++ Flex и Bison, и я хотел бы сохранить это таким образом (избегая инкапсуляции парсера внутри объекта).
5 ответов
Обратите внимание, что Bison предоставляет опцию '-p zz' для префикса символов с 'zz' вместо 'yy'.
Точно так же Flex предоставляет опцию '-P zz' для префикса символов с 'zz' вместо 'yy'. Он использует '-p' для отчетов о производительности. "Жаль, что они не соответствуют друг другу.
В дополнение к ответу Леффлера, я хотел бы предоставить здесь другой подход:
в .lex
файл, который вы могли бы использовать %option prefix="PREFIX"
и в .y
файл, который вы могли бы использовать %define api.prefix PREFIX
, который делает то же самое, что и прохождение -p PREFIX
Бизону и -P PREFIX
согнуть.
Обратите внимание после переопределения префикса по умолчанию yy
, вы можете получить доступ к внутренним именам через оба оригинала yy*
и ваш переопределен PREFIX*
в то время как очевидно для внешних имен вы ДОЛЖНЫ использовать свои PREFIX*
чтобы получить к ним доступ.
Если вы используете Bison 3.0 или выше, взгляните на %define api.prefix {foo_}
, который заменяет все yy
а также YY
префиксы с foo_
а также FOO_
,
Смотрите документацию о нескольких парсерах.
Между Bison 2.6 и 3.0 раньше не было скобок: %define api.prefix foo_
,
Переменная api.prefix у меня больше не работает (выдает ошибку компиляции)
%define api.prefix {PREFIX}
Я должен был использовать следующий синтаксис
%name-prefix="PREFIX"
В дополнение к тому, что уже было сказано, если вы используете "%define api.prefix {PREFIX}", он также переименует yytext && yyparse в PREFIXtext и PREFIXparse. Не забывайте {} вокруг префикса!
То же самое относится к '%option prefix="PREFIX" в lex, ваш лексер будет переименован в PREFIXlex.