2009-06-18 11 views
40

Ejecución de bisonte en este archivo:¿Cómo resolver bisonte advertencia "... no tiene tipo declarado"

%{ 
    #include <iostream> 
    int yylex(); 
    void yyerror(const char*); 
%} 


%union 
{ 
    char name[100]; 
    int  val; 
} 

%token NUM ID 
%right '=' 
%left '+' '-' 
%left '*' 

%% 

exp : NUM  {$$.val = $1.val;} 
    | ID  {$$.val = vars[$1.name];} 
    | exp '+' exp {$$.val = $1.val + $3.val;} 
    | ID '=' exp {$$.val = vars[$1.name] = $3.val;} 
; 

%% 

Conduce a las advertencias del tipo de:

warning: $$ of 'exp' has no declared type.

¿Qué significa y como lo soluciono?

+14

1: por aparecer en primer lugar cuando googlear 'error bisontes no ha declarado type' – INS

+0

Sólo una pequeña claridad. Tengo '% union {int intValue; int floatValue; } 'pero no me permite usar' $$. intValue' o '$ 1.intValue'. Dice 'error: solicite el miembro 'floatValue' en algo que no sea una estructura o unión'. ¿Porque? – Shashwat

Respuesta

39

La unión (% union) definida no está destinada a ser utilizada directamente. Por el contrario, debe decirle a Bison qué miembro de la unión se utiliza con qué expresión.

Esto se hace con %type directive.

una versión fija del código es:

%{ 
    #include <iostream> 
    int yylex(); 
    void yyerror(const char*); 
%} 


%union 
{ 
    char name[100]; 
    int  val; 
} 

%token NUM ID 
%right '=' 
%left '+' '-' 
%left '*' 

%type<val> exp NUM 
%type<name> ID 

%% 

exp : NUM  {$$ = $1;} 
    | ID  {$$ = vars[$1];} 
    | exp '+' exp {$$ = $1 + $3;} 
    | ID '=' exp {$$ = vars[$1] = $3;} 
; 

%% 
+1

Un pequeño punto: la notación '% type exp NUM' no significa que la reducción particular' exp NUM' tenga type 'val'; significa que 'exp' tiene el tipo' VAL' y 'NUM' tiene el tipo' val'. Esta respuesta publicada, por cierto, es más útil que la documentación oficial para la directiva tipo, que no tiene ejemplos. –

7

Como reflexión más, si quieres ser más explícito con sus reducciones (si se está haciendo annoation AST, esto puede ser muy útil), entonces se puede Haga sus punteros de valores de pila y luego maneje los valores de tipo usted mismo. Al igual que con los tipos escalares:

struct myScalar { 
    union { 
     int num; 
     char *id; 
     char *float_lexeme; 
    }payload; 

    enum { 
     TYPE_NUM, 
     TYPE_IDENTIFIER, 
     TYPE_FLOAT_CHAR 
    } type; 
    char *orig_lexeme; 
}; 

Y tener un typedef y scalar_val *val para la pila.

Al pasar a interfaces de compilación más complejas, puede ayudar a construir su AST de esta manera para que cuando recorra el árbol tenga mejores metadatos y también pueda aumentar la traducción con traducciones para semisemáticas tipos. Luego se reduce a las producciones de su hoja como ID para mezclar el lexema en la carga útil escalar correcta.

No es una explicación completa, pero entiendes la idea.

Espero que esto ayude con sus frontales de futuros bisonte/Lex y ...

buena suerte

+0

¿Puede explicarlo un poco más? No entendí cómo funcionaba el '% type'. – Jaseem

Cuestiones relacionadas