2009-06-18 13 views
40

Uruchomione Bison na tego pliku:Jak rozwiązać ostrzeżenie Bison "... nie ma zadeklarowanego typu"

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

%% 

prowadzi do ostrzeżenia rodzaju:

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

Co to znaczy i jak mogę to rozwiązać?

+14

+1: pierwszy na pojawiające się podczas googlowania 'bison błąd nie zadeklarował type' – INS

+0

prostu mała klarowność. Mam '% union {int intValue; int floatValue; } 'ale nie pozwala mi używać' $$. intValue' lub '$ 1.intValue'. Mówi "błąd: żądanie dla członka" floatValue "w czymś, co nie jest strukturą lub związkiem'. Dlaczego tak? – Shashwat

Odpowiedz

39

Definicja unii (% unii) nie jest przeznaczona do bezpośredniego użycia. Trzeba raczej powiedzieć Bisonowi, który członek związku jest użyty przez które wyrażenie.

Wykonuje się to przy pomocy %type directive.

Stały wersja kodu jest:

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

Mały punkt: notacja '% type exp NUM' nie oznacza, że ​​konkretna redukcja' exp NUM' ma typ 'val'; oznacza to, że 'exp' ma typ' VAL' oraz 'NUM' ma typ' val'. Ta opublikowana odpowiedź jest bardziej przydatna niż oficjalna dokumentacja dla dyrektywy typu, która nie ma przykładów. –

7

Jako głębszego zastanowienia, jeśli chcesz być bardziej wyraźne ze swoimi redukcji (jeśli robisz AST annoation, to może być przydatne), to można utwórz wskaźniki wartości stosu, a następnie samodzielnie zarządzaj wartościami typu. Podobnie jak z typów skalarnych:

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

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

i mieć typedef i scalar_val *val na stosie.

Po przejściu na bardziej złożone interfejsy kompilatora może pomóc zbudować AST tak, aby podczas przechodzenia przez drzewo można było uzyskać lepsze meta-dane, a także można rozszerzyć tłumaczenie za pomocą tłumaczeń dla wersji przedmantycznej. typy. Następnie sprowadza się do twoich produkcji liści, takich jak ID, aby przetasować leksema do właściwego ładunku skalarnego.

Nie jest to pełne wyjaśnienie, ale masz pomysł.

Nadzieja to pomaga ze swoimi przyszłymi Bison/Lex front-end i ...

Powodzenia

+0

Czy możesz wyjaśnić to nieco więcej ... Nie rozumiem, jak działa '% typ'. – Jaseem

Powiązane problemy