2016-04-29 8 views
-1

Я пишу парсер для довольно простого языка. Язык позволит описать игру, в которой есть комнаты. Номера содержат «персонажи» и «вещи». У персонажей есть «варианты», которые позволяют вам взаимодействовать с ними; параметры могут формировать дерево, разрешающее несколько ветвей после начала взаимодействия с символом.Lex/Flex: Почему я получаю ошибку: запрос для члена 'str' в чем-то не структура или объединение "при использовании --bison-locations

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

Я использовал свой google-fu и нашел флаг -bison-location, который должен генерировать код, который будет содержать yylloc, заполненный текущим номером строки.

Но когда я включаю этот флаг, я начинаю получать "запрос для члена 'str' в чем-то не структура или объединение" сообщений.

С выключенным флагом мой синтаксический анализатор компилируется, но не сообщает мне, где синтаксические ошибки.

Как получить информацию о местоположении в yylloc, не нарушая связь между моим соединением и моим {семантическим кодом ...}?

Мой источник и журнал от макияжа находится по адресу: http://apdamien.info/code/GHparser.zip

+1

Мы не собираемся загружать произвольный файл '.zip'. Найдите способ воспроизвести проблему с наименьшим количеством кода. –

ответ

1

Если вы просто хотите получить информацию номер строки, а затем указать %option yylineno в вашем (F) ЛЕКС файл и объявить extern int yylineno в вашем YACC/зубров файл. Flex автоматически заполнит yylineno. Если вам нужна полная информация о номере строки/столбце, как в структуре yylloc, и вы хотите, чтобы она была связана с каждым маркером, где вы можете получить его в бизоне, используя @n, вам придется много работать, потому что flex не заполняет (или даже не вычисляет) номера столбцов.

Так что --bison-bridge не делает то, что вы думаете, и это, вероятно, не делает то, что вы хотите. Возможно, Google запустил вас на страницу Taco Joe's Enchiladas и Flex Misconceptions вместо appropriate section of the Flex manual, или, может быть, он просто подтолкнул вас к appendix on bison-bridge, который вам нужно будет прочитать очень внимательно, потому что, хотя это действительно что --bison-locations изменяет соглашение о вызове на yylex, важное различие не подчеркивается так сильно, как могло бы быть.

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

Во всяком случае, важным моментом является:

Note that the macros 'yylval' and 'yylloc' evaluate to pointers.

Другими словами, при указании --bison-bridge, yylval больше не является глобальной переменной, (или --bison-locations что подразумевает --bison-bridge.) вместо этого yylex вызывается с указателем объекту семантического значения, а yylval имеет тип YYSTYPE*, а не YYSTYPE.Это означает, что вам нужно изменить любое использование yylval в гибких действиях со стороны, например,

yylval.str = strdup(yytext); 

в

yylval->str = strdup(yytext); 

(Кстати, если ваше действие говорит yylval.str = yytext;, вы должны искать для одного из многих ответов SO на такие вопросы, как «почему значение строки моего токена изменяется в парсере?» или читайте this bison FAQ. Или вы можете просто использовать strdup, как указано выше, но у меня есть старомодная идея о том, что один должен понимать инструменты, которые используются, а не просто вслепую копирование кода от анонимных незнакомцев.)

+0

Спасибо, rici. Это полностью решило проблему. И я прочитаю FAQ и начну использовать strdup, спасибо. –