Я пытаюсь проанализировать многострочные комментарии в стиле C в моем файле flex (.l):
%s ML_COMMENT
%%
...
<INITIAL>"/*" BEGIN(ML_COMMENT);
<ML_COMMENT>"*/" BEGIN(INITIAL);
<ML_COMMENT>[.\n]+ { }
Я не возвращаю никаких токенов, и моя грамматика (.y) никоим образом не касается комментариев.
Когда я запускаю свой исполняемый файл, я получаю ошибку синтаксического анализа:
$ ./a.out
/*
abc
def
Parse error: parse error
$ echo "/* foo */" | ./a.out
Parse error: parse error
(Моя функция yyerror выполняет printf("Ошибка синтаксического анализа: %s\n"), откуда появляется первая половина избыточного сообщения об ошибке).
Я понимаю, почему второй пример терпит неудачу, поскольку все входные данные являются комментариями, а поскольку комментарии игнорируются грамматикой, в нем нет утверждений. Таким образом, ввод не является допустимой программой. Но первая часть выдает ошибку синтаксического анализа еще до того, как я закончу комментарий.
Также сбивает с толку:
$ ./a.out
/* foo */
a = b;
Parse error: parse error
В этом случае комментарий закрывается до фактического действительного ввода (который без комментария анализируется просто отлично). На самом деле сбой происходит после синтаксического анализа "a", а не после попытки синтаксического анализа присваивания "a = b;". Если я ввожу «а» в отдельной строке, все равно выдает ошибку.
Учитывая, что сообщение об ошибке является ошибкой синтаксического анализатора, а не ошибкой сканера, есть ли что-то важное, что мне не хватает в моем файле .y? Или я делаю что-то не так в правилах сканера, которые распространяются на сторону парсера?
EDIT: По предложению @Rudi я включил отладку и обнаружил:
$ ./a.out
Starting parse
Entering state 0
Reading a token: /*
foo
Next token is 44 (IDENTIFER)
Shifting token 44 (IDENTIFER), Entering state 4
Reducing via rule 5 (line 130), IDENTIFER -> identifier
state stack now 0
Entering state 5
Я отключил отладку и обнаружил, что /* foo */ = bar;
действительно анализирует то же самое, что и foo = bar;
. Я использую Flex 2.5.4; он не дает мне никаких предупреждений о правилах с отслеживанием состояния, которые я пытаюсь использовать.
--debug
к своему вызову bison и устанавливаетеyydebug=1
перед вызовомyyparse()
, синтаксический анализатор выдает отладочную информацию для каждого токена, который он видит из лексера. - person Rudi   schedule 10.11.2010