Я пытаюсь проанализировать многострочные комментарии 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;". Если я вхожу в "a" в свою собственную строку, он все равно выдает ошибку.
Учитывая, что сообщение об ошибке является ошибкой синтаксического анализатора, а не ошибкой сканера, есть ли что-то важное в моем .y файле? Или я делаю что-то неправильно в своих правилах сканера, которые распространяются на сторону анализатора?
РЕДАКТИРОВАТЬ: По предложению @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; он не дает мне никаких предупреждений о правилах состояния, которые я пытаюсь использовать.