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