2009-09-16 7 views
15

Je suis en train d'inclure une struct dans le cadre de l'union avec Bison, mais je reçois une erreur sur le 'nœud struct args' en% union:Include struct dans le% union def avec Bison/Yacc

parser.y:17: error: field ‘args’ has incomplete type 

Le code:

struct node { 
    char * val; 
    struct node * next; 
}; 

%} 

%union { 
    char * string; 
    struct node args; 
} 

%token <string> CD WORD PWD EXIT 

%type <args> arg_list 

Quelqu'un sait ce que je fais mal?

Répondre

13

Il revient à la sortie lame y.tab.h que vous obtenez.

Vous devez résoudre ce problème en vous assurant que «struct node» est défini avant d'y inclure y.tab.h. Pour cela, créez un fichier node.h avec la définition de structure.

Ensuite, incluez node.h avant y.tab.h dans votre fichier parser.l, le fichier parser.y ainsi que tous les fichiers c dont vous disposez y.tab.h. C'est un peu ennuyeux. Vous pouvez également remplacer "struct node args" par "struct node * args" car vous n'aurez pas besoin de connaître le type complet tant que vous ne l'utiliserez pas. Je ne sais pas si cela correspondrait à votre code.

L'un ou l'autre devrait fonctionner.

22

Mieux encore, utilisez la directive% de code avec la « exige » l'option, à savoir:

%code requires { 
    struct node { 
     char * val; 
     struct node * next; 
    }; 
} 

%union { 
    char * string; 
    struct node args; 
} 

Cela comprendra le code dans le « exige » bloc dans le fichier tab.h ainsi que l'analyseur fichier source.

De la documentation: http://www.gnu.org/software/bison/manual/html_node/Decl-Summary.html#Decl-Summary

  • nécessite
    • Objet: Ceci est le meilleur endroit pour écrire du code de dépendance requis pour YYSTYPE et YYLTYPE. En d'autres termes, c'est le meilleur endroit pour définir les types référencé dans% union directives, et c'est le meilleur endroit pour remplacer les définitions YYSTYPE et YYLTYPE par défaut de Bison.
1

Peut-être plus simple (je pense) - utilisé moi-même:

%union { 
    char c; 
    struct { 
    char name[30]; 
    int type; 
    } s; 
} 

Ensuite, flex vous pouvez utiliser "yylval.s.name" ou « yylval.s. tapez ", etc .. tandis que dans le bison, au lieu de $$=0, $1=bla ... vous pouvez maintenant écrire $<s.type>$=0 , $<s.type>1=bla...