Доступ к yyout в реентерабельном синтаксическом анализаторе, сгенерированном Bison

Есть ли обычный способ доступа к функции yyget_out(scanner) или переменной yyout из реентерабельного синтаксического анализатора, созданного Bison?

Я хочу написать сообщение лексеру yyout, находясь в синтаксическом анализаторе, используя либо

fprintf(yyout, message);

or

fprintf(yyget_out(scanner), message);

Последнее на самом деле работало, но мне пришлось предоставить прототип FILE* yyget_out(yyscan_t), и мне кажется странным делать это вручную, а не включать заголовочный файл.


person DYZ    schedule 13.02.2020    source источник


Ответы (1)


Вы можете попросить Flex сгенерировать файл заголовка с помощью --header-file=FILE в командной строке или %option header-file="FILE" в прологе.

Однако, когда вы попытаетесь использовать этот заголовочный файл, вы обнаружите, что для него требуются определения YYSTYPE и YYLTYPE, которые определены в заголовочном файле, сгенерированном Bison. Этот файл заголовка не включен в файл заголовка, сгенерированный Flex, поэтому вы должны убедиться, что он уже включен, или (мое предпочтение) обернуть файл заголовка внутри вашего собственного файла заголовка, который включает заголовки, созданные как Bison, так и Flex.

Это нормально для других единиц перевода, но круговая зависимость между файлами заголовков, сгенерированными Bison и Flex, по-прежнему будет вызывать проблемы в самом C-файле, сгенерированном Bison. Мое предпочтительное решение — обернуть функции, которые используют средства, предоставляемые кодом, сгенерированным Flex, и поместить обернутые функции в отдельную единицу перевода, содержащую утилиты. (Обертывание может служить и другим целям, например, скрывать специфичные для Flex и Bison объекты контекста внутри более общего объекта контекста, который также содержит контекст, необходимый вашему проекту.) Попытка #include сгенерированного Flex заголовка непосредственно в вашем файле Bison может привести к сводить тебя с ума.

По-прежнему существует неразрешимая цикличность, поскольку файл C, сгенерированный Bison, скорее всего, будет зависеть от yyscan_t, объявленного в заголовке, сгенерированном Flex. Кажется, нет другого способа обойти это, кроме как поставить

typedef void* yyscan_t;

в пролог кода Bison (но не в то место, где он будет добавлен в заголовочный файл).

В моем ответе на этот вопрос.

person rici    schedule 13.02.2020