Несколько парсеров flex / bison - PullRequest
       39

Несколько парсеров flex / bison

6 голосов
/ 28 октября 2009

Каков наилучший способ обработки нескольких парсеров Flex / Bison внутри проекта?

Я написал парсер, и теперь мне нужен второй в том же проекте. До сих пор в третьем разделе parser1.y я вставил метод main(..) и оттуда вызвал yyparse.

Я хочу получить два разных синтаксических анализатора (parser1.y и parser2.y) и иметь возможность использовать их из внешней функции (предположим, main в main.cpp).

Какие меры предосторожности следует использовать для экспорта функций yyparse за пределы файлов .y и как обрабатывать два анализатора?

PS. Я использую g ++ для компиляции, но не версии C ++ Flex и Bison, и я хотел бы сохранить это так (избегая инкапсуляции парсера внутри объекта).

Ответы [ 5 ]

11 голосов
/ 08 ноября 2012

В дополнение к ответу Леффлера, я хотел бы предложить другой подход:

В файле .lex вы можете использовать %option prefix="PREFIX", а в файле .y вы можете использовать %define api.prefix PREFIX, что аналогично передаче -p PREFIX в Bison и -P PREFIX в Flex.

Обратите внимание, что после переопределения префикса по умолчанию yy вы можете получить доступ к внутренним именам через ОБА, исходный yy* и переопределенный PREFIX*, тогда как для внешних имен вы ДОЛЖНЫ использовать свой PREFIX* для доступа к ним.

9 голосов
/ 28 октября 2009

Обратите внимание, что Bison предоставляет опцию -p zz для префикса символов вместо zy вместо yy.

Аналогично, Flex предоставляет опцию '-P zz' для префикса символов с 'zz' вместо 'yy'. Он использует '-p' для отчетов о производительности. «Жаль, что они не согласуются друг с другом.

5 голосов
/ 09 ноября 2012

Если вы используете Bison 3.0 или выше, обратите внимание на %define api.prefix {foo_}, который заменяет все префиксы yy и YY на foo_ и FOO_.

См. Документацию о нескольких парсерах .

Между бизонами 2.6 и 3.0 раньше не было фигурных скобок: %define api.prefix foo_.

0 голосов
/ 19 марта 2018

Переменная api.prefix у меня больше не работает (выдает ошибку компиляции)

%define api.prefix {PREFIX}

Мне пришлось использовать следующий синтаксис

%name-prefix="PREFIX"
0 голосов
/ 26 февраля 2014

В дополнение к тому, что уже было сказано, если вы используете «% define api.prefix {PREFIX}», он также переименует yytext && yyparse в PREFIXtext и PREFIXparse. Не забывайте {} вокруг префикса!
То же самое относится к '% option prefix = "PREFIX" в lex, ваш лексер будет переименован в PREFIXlex.

...