2009-06-18 8 views
40

Bison Laufen auf diese Datei:Wie Bison Warnung lösen „... hat keinen deklarierten Typ“

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

%% 

führt zu Warnungen der Art von:

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

Was ist das und wie löse ich es?

+14

+1: für den ersten erscheinen, wenn googeln 'Bison Fehler kein Baumuster zur – INS

+0

erklärt hat gerade ein kleine Klarheit. Ich habe '% union {int intValue; int FloatWert; } 'aber es erlaubt mir nicht,' $$. intValue' oder '$ 1.intValue' zu ​​verwenden. Es heißt 'error: Anfrage für Mitglied 'floatValue' in etwas nicht eine Struktur oder Union. Warum? – Shashwat

Antwort

39

Die definierte Union (% union) ist nicht zur direkten Verwendung bestimmt. Stattdessen müssen Sie Bison mitteilen, welches Mitglied der Gewerkschaft von welchem ​​Ausdruck verwendet wird.

Dies geschieht mit der %type directive.

Eine feste Version des Codes ist:

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

Ein kleiner Punkt: Die Schreibweise '% type exp NUM' bedeutet nicht, dass die spezielle Reduktion' exp NUM' den Typ 'val' hat; es bedeutet, dass 'exp' den Typ' VAL' hat und 'NUM' den Typ' val' hat. Diese gepostete Antwort, übrigens, ist nützlicher als die offizielle Dokumentation für die Typ-Direktive, die keine Beispiele hat. –

7

Als weiterer Gedanke, wenn Sie mehr explizit mit Kürzungen sein wollen (wenn Sie AST annoation tun, kann dies sehr nützlich sein), dann können Sie Machen Sie Ihre Stack-Werte Zeiger und dann selbst mit Typ-Werten. Ähnlich wie skalare Typen mit:

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

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

Und haben eine typedef und scalar_val *val für den Stapel.

Wenn Sie zu komplexeren Compiler-Frontends übergehen, kann es hilfreich sein, Ihre AST so zu erstellen, dass Sie beim Überqueren der Baumstruktur bessere Metadaten haben und die Übersetzung mit Übersetzungen für präsemantisch erweitern können Arten. Dann läuft es auf Ihre Blattproduktionen wie ID hinaus, um das Lexem in die rechte skalare Nutzlast zu mischen.

Keine vollständige Erklärung, aber Sie bekommen die Idee.

hoffe, das hilft mit Ihrem zukünftigen Bison/Lex-Frontends und ...

Good Luck

+0

Können Sie es ein bisschen mehr erklären .. Ich habe nicht verstanden, wie der '% Typ' funktioniert. – Jaseem