2009-06-18 24 views
40

Chạy Bison trong hồ sơ này:Làm thế nào để giải quyết Bison cảnh báo "... không có kiểu tuyên bố"

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

%% 

Dẫn đến cảnh báo về các loại:

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

có nghĩa là gì và làm thế nào để giải quyết nó?

+14

1: cho xuất hiện đầu tiên khi googling 'lỗi bò rừng đã không tuyên bố type' – INS

+0

Chỉ cần một nhỏ rõ ràng. Tôi có '% union {int intValue; int floatValue; } 'nhưng nó không cho phép tôi sử dụng' $$. intValue' hoặc '$ 1.intValue'. Nó nói 'lỗi: yêu cầu cho thành viên' floatValue 'trong một cái gì đó không phải là một cấu trúc hoặc union'. Tại sao như vậy? – Shashwat

Trả lời

39

Công đoàn (% union) được xác định không có ý định sử dụng trực tiếp. Thay vào đó, bạn cần phải nói với Bison rằng thành viên của công đoàn được sử dụng bởi biểu thức nào.

Việc này được thực hiện với %type directive.

Một phiên bản cố định của mã này là:

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

Một điểm nhỏ: ký hiệu '% type exp NUM' không có nghĩa là giảm cụ thể' exp NUM' có loại 'val'; nó có nghĩa là 'exp' có kiểu' VAL' và 'NUM' có kiểu' val'. Câu trả lời được đăng này, btw, hữu ích hơn, so với tài liệu chính thức cho chỉ thị loại, không có ví dụ. –

7

Như một ý nghĩ xa hơn, nếu bạn muốn trở thành rõ ràng hơn với giảm của bạn (nếu bạn đang làm AST annoation, điều này có thể có ích) sau đó bạn có thể tạo các con trỏ giá trị ngăn xếp của bạn và sau đó tự xử lý các giá trị kiểu. Giống như các loại vô hướng với:

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

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

Và có typedef và scalar_val *val cho ngăn xếp.

Khi bạn di chuyển lên phần đầu biên dịch phức tạp hơn, nó có thể giúp xây dựng AST của bạn như thế này khi bạn duyệt cây bạn có siêu dữ liệu tốt hơn và bạn cũng có thể tăng thêm bản dịch với bản dịch trước ngữ nghĩa loại. Sau đó, nó sẽ chuyển thành các sản phẩm lá của bạn chẳng hạn như ID để trộn lexeme vào tải trọng vô hướng đúng.

Không giải thích đầy đủ, nhưng bạn có ý tưởng.

Hope this helps với tương lai Bison/Lex phía trước đầu của bạn và ...

Good Luck

+0

Bạn có thể giải thích thêm một chút không .. Tôi không hiểu cách '% type' hoạt động như thế nào. – Jaseem

Các vấn đề liên quan