2009-10-20 34 views
12

Tôi đã tìm câu trả lời của mình nhưng tôi không nhận được phản hồi nhanh nào cho một ví dụ đơn giản.Simple Flex/Bison C++

Tôi muốn biên dịch trình quét phân tích cú pháp/bison bằng cách sử dụng g ++ chỉ vì tôi muốn sử dụng các lớp C++ để tạo AST và những thứ tương tự.

Tìm kiếm trên internet Tôi đã tìm thấy một số khai thác, tất cả đều nói rằng điều duy nhất cần thiết là khai báo một số nguyên mẫu chức năng sử dụng extern "C" trong tệp lex.

Vì vậy, tập tin shady.y của tôi là

%{ 
#include <stdio.h> 
#include "opcodes.h" 
#include "utils.h" 

void yyerror(const char *s) 
{ 
    fprintf(stderr, "error: %s\n", s); 
} 

int counter = 0; 

extern "C" 
{ 
     int yyparse(void); 
     int yylex(void); 
     int yywrap() 
     { 
       return 1; 
     } 

} 

%} 

%token INTEGER FLOAT 
%token T_SEMICOL T_COMMA T_LPAR T_RPAR T_GRID T_LSPAR T_RSPAR 
%token EOL 

%token T_MOV T_NOP 


%% 

... GRAMMAR OMITTED ... 

%% 

main(int argc, char **argv) 
{ 
    yyparse(); 
} 

trong khi tập tin shady.l là

%{ 
    #include "shady.tab.h" 
%} 

%% 

"MOV"|"mov" { return T_MOV; } 
"NOP"|"nop" { return T_NOP; } 

";" { return T_SEMICOL; } 
"," { return T_COMMA; } 
"(" { return T_LPAR; } 
")" { return T_RPAR; } 
"#" { return T_GRID; } 
"[" { return T_LSPAR; } 
"]" { return T_RSPAR; } 
[1-9][0-9]? { yylval = atoi(yytext); return INTEGER;} 
[0-9]+"."[0-9]+ | "."?[0-9]? { yylval.d = atof(yytext); return FLOAT; } 
\n { return EOL; } 
[ \t] { /* ignore whitespace */ } 
. { printf("Mystery character %c\n", *yytext); } 

%% 

Cuối cùng trong makefile tôi sử dụng g ++ thay vì gcc:

shady: shady.l shady.y 
bison -d shady.y -o shady.tab.c 
flex shady.l 
g++ -o [email protected] shady.tab.c lex.yy.c -lfl 

flex và bò rừng hoạt động chính xác nhưng khi liên kết tôi nhận được lỗi sau:

Undefined symbols: 
    "_yylex", referenced from: 
    _yyparse in ccwb57x0.o 

Tất nhiên nếu tôi cố gắng thay đổi bất cứ điều gì về hàm trong tệp bison, nó nói rằng yylex không được khai báo trong phạm vi yyparse.

Tôi đang cố gắng giải quyết một thứ đơn giản phức tạp hơn? Trên thực tế tôi không cần một cấu trúc khép kín để có quyền truy cập vào phân tích cú pháp và lexer theo một cách thức hướng đối tượng, tôi chỉ muốn làm cho nó hoạt động.

Tôi chỉ muốn để có thể sử dụng C++ trong file bò rừng (để tạo AST) và kêu gọi yyparse() từ đối tượng C++ ..

Cảm ơn trước

+0

Cả flex và bison đều có cờ để tạo C++, chứ không phải C. – vonbrand

+1

Yuck. Không nên sử dụng các trình phân tích cú pháp C không thuần khiết, không lặp lại với các biến toàn cầu tĩnh trong C++. Nó sạch hơn nhiều để sử dụng flex và bison trong chế độ C++ tương ứng. https://www.gnu.org/software/bison/manual/bison.html#A-Complete-C_002b_002b-Example – Barry

Trả lời

10

Bạn cần extern "C" {} cho yylex để được shady.l:

%{ 
    extern "C" 
    { 
     int yylex(void); 
    } 

    #include "shady.tab.h" 
%} 

%% 

"MOV"|"mov" { return T_MOV; } 
"NOP"|"nop" { return T_NOP; } 

...etc... 

Ngoài ra, sau khi thêm một quy tắc ngữ pháp giả, tôi đã có thể xây dựng và chạy này với chỉ:

559 flex shady.l 
    560 bison -d shady.y 
    561 g++ shady.tab.c lex.yy.c