2010-05-19 3 views
1

Hy, je développe un moteur de script avec flex et bison et maintenant j'implémente les fonctions eval et load pour ce langage. Pour vous donner un exemple, la syntaxe est comme:Implémentation des fonctions eval et load dans un moteur de script avec Flex et Bison

import std.*; 

load("some_script.hy"); 

eval("foo = 123;"); 

println(foo); 

Alors, dans mon lexer j'ai mis la fonction:

void hyb_parse_string(const char *str){ 
    extern int yyparse(void); 
    YY_BUFFER_STATE prev, next; 
    /* 
    * Save current buffer. 
    */ 
    prev = YY_CURRENT_BUFFER; 
    /* 
    * yy_scan_string will call yy_switch_to_buffer. 
    */ 
    next = yy_scan_string(str); 
    /* 
    * Do actual parsing (yyparse calls yylex). 
    */ 
    yyparse(); 
    /* 
    * Restore previous buffer. 
    */ 
    yy_switch_to_buffer(prev); 
} 

Mais il ne semble pas fonctionner. Eh bien, il fait, mais quand est terminé, je reçois un SIGSEGV la chaîne (chargée à partir d'un fichier ou directement évalué):

Program received signal SIGSEGV, Segmentation fault. 
0xb7f2b801 in yylex() at src/lexer.cpp:1658 
1658   if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW) 

Comme vous pouvez le remarquer, le SIGSEGV est généré par le code Flex/Bison, pas le mien ... des conseils, ou au moins un exemple sur la façon de mettre en œuvre ce genre de fonctions? PS: J'ai implémenté avec succès la directive include, mais j'ai besoin d'eval et load pour travailler non pas au moment de l'analyse mais au moment de l'exécution (type de directives include/require de PHP).

Répondre

1

Cette erreur semble indiquer que le YY_CURRENT_BUFFER est invalide, probablement nul. Cela se produira si vous appelez yypop_buffer_state pour sortir du dernier tampon d'entrée. Si vous faites cela dans une règle <<EOF>>, (par exemple, traitant d'une directive include comme vous l'avez dit), vous devez cocher YY_CURRENT_BUFFER et si c'est nul, appelez le yyterminate, sinon il va planter comme vous voyez.

Modifier

Simone, je ne sais pas si je comprends votre commentaire. Si vous avez une règle <<EOF>>, cette action doit appeler yyterminate() ou établir une nouvelle source d'entrée d'une manière ou d'une autre, sinon vous obtiendrez un plantage similaire à celui que vous signalez. Lorsque vous voyez le crash, est-ce que c'est dans la fonction hyb_parse_string (dans l'appel yyparse) que vous avez posté? Utilisez la commande bt de gdb pour voir une trace de pile. Quelle est votre action de règle <<EOF>>?

+0

Je ne le fais dans aucune règle, c'est juste une fonction autonome appelée AFTER le script est analysé. La directive Include est facile à implémenter parce que je peux traiter avec <> comme vous l'avez dit étant dans une règle lexer, mais que faire si je dois implémenter quelque chose d'extérieur à une règle? –