2009-06-18 6 views
40

Exécution Bison sur ce fichier:Comment résoudre avertissement Bison "... n'a pas de type déclaré"

%{ 
    #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;} 
; 

%% 

Leads aux avertissements du genre de:

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

Qu'est-ce que cela signifie et comment puis-je le résoudre?

+14

+1: pour apparaître en premier lorsque googler 'erreur bison n'a pas déclaré type' – INS

+0

Juste un petite clarté. J'ai '% union {int intValue; int floatValue; } 'mais cela ne me permet pas d'utiliser' $$. intValue' ou '$ 1.intValue'. Il dit 'error: demande de membre 'floatValue' dans quelque chose qui n'est pas une structure ou une union'. Pourquoi ça? – Shashwat

Répondre

39

L'union (% union) définie n'est pas destinée à être utilisée directement. Au contraire, vous devez dire à Bison quel membre de l'union est utilisé par quelle expression. Ceci est fait avec le %type directive.

Une version fixe du code est:

%{ 
    #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 petit point: la notation «% type exp NUM» ne signifie pas que la réduction «exp NUM» a le type «val»; cela signifie que 'exp' a le type' VAL' et 'NUM' a le type' val'. Cette réponse publiée, btw, est plus utile que la documentation officielle pour la directive de type, qui ne contient aucun exemple. –

7

Comme autre pensée, si vous voulez être plus explicite avec vos réductions (si vous faites AST annoation, cela peut être à portée de main), vous pouvez faites vos pointeurs de valeurs de pile et ensuite manipulez vous-même les valeurs de type. Tout comme les types scalaires avec:

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

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

Et un typedef et scalar_val *val pour la pile. Lorsque vous vous déplacez vers des interfaces de compilation plus complexes, vous pouvez construire votre AST de cette manière afin que vous ayez de meilleures méta-données quand vous traversez l'arbre et que vous puissiez aussi augmenter la traduction avec des traductions pré-sémantiques les types. Ensuite, il se résume à vos productions de feuilles telles que ID pour mélanger le lexème dans la charge utile scalaire droite.

Pas une explication complète, mais vous avez l'idée.

Hope this helps avec vos futurs frontaux Bison/Lex et ...

Bonne chance

+0

Pouvez-vous expliquer un peu plus .. Je n'ai pas compris comment fonctionnait le '% type'. – Jaseem

Questions connexes