2010-02-14 8 views
1

J'ai un fichier lex/flex relativement simple et je l'ai exécuté avec l'indicateur de débogage de flex pour m'assurer qu'il est correctement segmenté. Malheureusement, je suis toujours confronté à l'un des deux problèmes suivants: soit le programme généré par flex arrête tout simplement après deux jetons, soit la règle que j'utilise pour reconnaître les caractères et les chaînes n'est pas appelée et la règle par défaut est appelé à la place.lex (flex) le programme généré n'analyse pas l'entrée entière

Quelqu'un peut-il me diriger dans la bonne direction? J'ai attaché mon dossier flexible et échantillon d'entrée/sortie. Edit: J'ai trouvé que le lexer généré s'arrête après une règle spécifique: "cdr". C'est plus détaillé, mais aussi beaucoup plus déroutant. J'ai posté un fichier lex modifié en court-circuit.

/* lex file*/ 
%option noyywrap 
%option nodefault 

%{ 
     enum tokens{ 
       CDR, 
       CHARACTER, 
       SET 
     }; 
%} 

%% 

"cdr"            { return CDR; } 
"set"            { return SET; } 

[ \t\r\n]           /*Nothing*/ 
[a-zA-Z0-9\\[email protected]#$%^&*()\-_+=~`:;"'?<>,\.]  { return CHARACTER; } 

%% 

entrée de l'échantillon:

set c cdra + cdr b +() ; 

sortie complète de l'exécution de l'entrée par l'analyseur généré:

--(end of buffer or a NUL) 
--accepting rule at line 16 ("set") 
--accepting rule at line 18 (" ") 
--accepting rule at line 19 ("c") 
--accepting rule at line 18 (" ") 
--accepting rule at line 15 ("cdr") 

Toute pensée? Le programme généré abandonne après la moitié de l'entrée! (pour référence, je fais une entrée en redirigeant le contenu d'un fichier vers le programme généré).

Répondre

3

Lors de la génération d'un lexer qui est autonome (c'est pas un avec des jetons qui sont définis dans le bison/yacc, vous écrivez généralement un ENUM en haut du fichier définissant vos jetons. Cependant, la boucle principale de un programme lex, y compris la boucle principale générée par défaut, ressemble à quelque chose comme ceci:

while(token = yylex()){ 
    ... 

cela est bien, jusqu'à ce que votre lexer correspond à la règle qui apparaît d'abord dans le ENUM - dans ce cas précis CDR Depuis énumérations par. par défaut démarrer à zéro, cela provoque la fin de la boucle while Renuméroter votre enum - va résoudre le problème

enum tokens{ 
      CDR = 1, 
      CHARACTER, 
      SET 
    }; 

Version courte: lors de la définition des jetons à la main pour un lexer, commencez par 1 pas 0.

0

Cette règle

[-+]?([0-9*\.?[0-9]+|[0-9]+\.)([Ee][-+]?[0-9]+)? 
      | 

semble manquer un support de fermeture juste après la première 0-9, j'ai ajouté | ci-dessous où je pense que cela devrait être. Je ne pouvais pas commencer à deviner comment le flex répondrait à cela. La règle que j'utilise habituellement pour les noms de symboles est [a-zA-Z$_], c'est comme vos chaînes non cotées sauf que j'autorise généralement les nombres à l'intérieur des symboles tant que le symbole ne commence pas par un nombre.

[a-zA-Z$_]([a-zA-Z$_]|[0-9])* 

Un caractère est juste un symbole court. Je ne pense pas qu'il doit avoir sa propre règle, mais si c'est le cas, alors vous devez vous assurer que la règle de la chaîne nécessite au moins 2 caractères.

[a-zA-Z$_]([a-zA-Z$_]|[0-9])+ 
+0

fixe les crochets ne correspondent pas, mais pas de chance. Cependant, j'ai réussi à dupliquer le problème avec un ensemble de règles plus court. – Zxaos

+0

Pour répondre à la façon dont lex réagirait, il échouerait simplement la règle et s'arrêterait. Étant donné que les crochets ne correspondent jamais, une règle valide n'est jamais indiquée. (le 9 * agira juste sur le 9, et ne blesse pas trop le programme) – Stegosaurus