Доступ к yyout в повторяющемся парсере Bison - PullRequest
1 голос
/ 13 февраля 2020

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

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

fprintf(yyout, message);

или

fprintf(yyget_out(scanner), message);

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

1 Ответ

0 голосов
/ 13 февраля 2020

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

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

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

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

typedef void* yyscan_t;

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

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

дольше обсуждается проблема циклической зависимости и способы ее решения.
...