J'essaie d'analyser des commentaires de fichier multi-ligne C-style dans mon flex (.L):Pourquoi les commentaires multi-lignes dans flex/bison sont-ils si évasifs?
%s ML_COMMENT
%%
...
<INITIAL>"/*" BEGIN(ML_COMMENT);
<ML_COMMENT>"*/" BEGIN(INITIAL);
<ML_COMMENT>[.\n]+ { }
Je ne renvoie aucun jeton et ma grammaire (.y) ne traite pas de commentaires de quelque manière que.
Quand je lance mon exécutable, je reçois une erreur d'analyse:
$ ./a.out
/*
abc
def
Parse error: parse error
$ echo "/* foo */" | ./a.out
Parse error: parse error
(Ma fonction yyerror fait un printf ("Parse error:% s \ n"), qui est l'endroit où la première moitié du message d'erreur redondant vient de).
Je peux voir pourquoi le deuxième exemple échoue puisque l'intégralité de l'entrée est un commentaire, et puisque les commentaires sont ignorés par la grammaire, il n'y a pas d'instructions. Ainsi, l'entrée n'est pas un programme valide. Mais la première partie jette une erreur d'analyse avant même que je termine le commentaire.
Aussi confus:
$ ./a.out
/* foo */
a = b;
Parse error: parse error
Dans ce cas, le commentaire est fermé avant l'entrée en cours de validité réelle (qui, sans commentaire, parse très bien). L'échec se produit réellement après l'analyse de "a", pas après avoir tenté d'analyser l'affectation "a = b;". Si j'applique "a" sur sa propre ligne, cela génère une erreur. Étant donné que le message d'erreur est une erreur d'analyseur et non une erreur de scanner, y a-t-il quelque chose de crucial qui me manque dans mon fichier .y? Ou est-ce que je fais quelque chose de mal dans mes règles de scanner qui se propagent du côté de l'analyseur?
EDIT: @ Per suggestion de Rudi, je me tournai le débogage et trouvé:
$ ./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
Je me suis tourné le débogage et a constaté que /* foo */ = bar;
parse fait la même chose que foo = bar;
. J'utilise flex 2.5.4; il ne me donne aucun avertissement sur les règles d'état que je tente d'utiliser.
I retagged flex à gnu-flex. Les règles de votre scanner semblent correctes. L'erreur d'analyse indique une entrée de jeton non valide dans l'analyseur. Vous voudrez peut-être poster quelques règles Bison correspondantes. De plus, il peut être judicieux de placer des instructions printf() dans vos règles de bison, de cette façon vous pouvez voir quelles règles l'analyseur essaie pendant l'analyse du jeton. – Kizaru
Ce serait également une bonne idée de créer un faisceau de test séparé pour votre scanner. De cette façon, vous pouvez isoler les défauts du scanner des défauts de l'analyseur. Tout système de scanner-analyseur est suffisamment complexe pour que vous n'ayez pas besoin d'injecter de la complexité supplémentaire en effectuant des tests d'intégration lorsque vous voulez effectuer des tests unitaires ... – bstpierre
Lorsque vous ajoutez le drapeau '--debug' à votre bison invocation et définissez 'yydebug = 1' avant l'appel' yyparse() ', puis l'analyseur émet des informations de débogage pour chaque jeton qu'il voit à partir de la lexer. – Rudi