Ваша основная проблема c в том, что вы используете символьные литералы в своей грамматике (что хорошо), но не возвращаете их в своем лексере (что плохо).
Вместо
"(" return tLPAR;
")" return tRPAR;
// etc.
Просто дайте этим символам попасть в ваше правило отката:
. { return yytext[0]; }
Тогда вы также можете избавиться от определений %token
для этих односимвольных токенов, поскольку вы используете односимвольные литералы.
К сожалению, вы не можете сделать это с более длинными токенами. Таким образом, ваши жетоны ключевых слов должны оставаться такими, какие они есть.
Кроме того, ваше правило для строк совершенно неверно. Пожалуйста, прочитайте документацию для (f) lex регулярных выражений вместо того, чтобы полагаться на какой-то другой синтаксис регулярного выражения. Flex не распознает побеги \S
и \s
. Он не реализует нежадное повторение (*?
). Он использует "
в качестве специального синтаксиса (имеется в виду литеральные строки в кавычках) - фактически, вы использовали это в других правилах, поэтому не следует ожидать, что "
будет обычным символом в вашем формате STRING
, И $
нельзя использовать в макросе (и, действительно, нет веской причины использовать макросы в этом определении сканера; я всегда рекомендую избегать их, если для этого нет веских оснований.)
Одна возможная строка Действие:
["]([^"]|\\.|\\\n)*["] { return tSTRINGVAL; }
Я настоятельно рекомендую вам прочитать главу руководства по бизонам о отладке грамматики , в частности, раздел о том, как включить трассировку парсера, что намного больше точнее и информативнее, чем вставка printf
вызовов в действия парсера. (Это фактически показало бы вашу проблему.)
Ваша проблема не связана с предупреждением, выданным компилятором, но вы должны это исправить. Это происходит потому, что вы не объявили yylex
в своем прологе бизонов. Поместите это непосредственно перед вашим определением yyerror
:
int yylex(void);
, чтобы компилятор знал, что такое прототип yylex
. (Вы должны объявить это, потому что бизон не делает этого за вас.)