2009-09-16 18 views
15

Estoy tratando de incluir una estructura como parte de la unión con bisonte, pero me da un error en el 'struct nodo args' en% union:Incluir struct en el def% la unión con bisonte/Yacc

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

El Código:

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

%} 

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

%token <string> CD WORD PWD EXIT 

%type <args> arg_list 

Alguien sabe lo que estoy haciendo mal?

Respuesta

13

Se trata de la salida cojo y.tab.h que obtienes.

Debe solucionar esto asegurándose de que se define "struct node" antes de incluir y.tab.h en cualquier lugar.

Para hacer esto, cree un archivo node.h con la definición de estructura.

Luego incluya node.h before y.tab.h en su archivo parser.l, archivo parser.y así como cualquier archivo c que tenga que incluya y.tab.h. Esto es un poco molesto

Alternativamente podría cambiar "struct node args" por "struct node * args" ya que no necesitaría saber el tipo completo hasta que vaya a usarlo en alguna parte. No estoy seguro si esto encajaría con su código.

Cualquiera de los dos debería funcionar.

22

Mejor aún, utilice el código de directiva% con la opción "requiere", es decir:

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

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

Esto incluirá el código en el "requiere" bloque en el archivo tab.h, así como el analizador archivo fuente.

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

  • requiere
    • Propósito: Este es el mejor lugar para escribir código de la dependencia requerida para YYSTYPE y YYLTYPE. En otras palabras, es el mejor lugar para definir los tipos a los que se hace referencia en directivas% union, y es el mejor lugar para anular las definiciones YySTYPE y YYSTTYPE predeterminadas de YYLTYPE de Bison.
1

Quizás más simple (creo) - utilizado este mismo:

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

Luego, en la flexión puede utilizar "yylval.s.name", o "yylval.s. escriba ", etc. mientras está en bison, en lugar de $$=0, $1=bla ... ahora puede escribir $<s.type>$=0 , $<s.type>1=bla...