2009-10-20 91 views
12

我已經找了我的答案,但我沒有得到任何一個簡單的例子的快速反應。簡單的Flex /野牛C++

我想編譯一個使用g ++的flex/bison掃描器+解析器,只是因爲我想用C++類創建AST和類似的東西。

在互聯網上搜索我發現了一些漏洞,所有說的唯一需要的是在lex文件中使用extern「C」聲明一些函數原型。

所以我shady.y文件

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

而shady.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); } 

%% 

最後,在我用G ++而不是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 

彎曲和野牛正常工作,但在連接時出現以下錯誤:

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

當然,如果我試圖改變有關野牛文件中的函數的任何東西,它說yylex沒有在yyparse範圍內聲明。

我想解決一些比看起來更復雜的東西嗎?其實我不需要一個封閉的結構來以面向對象的方式訪問解析和詞法分析器,我只是想讓它工作。

我只是想能夠在野牛文件中提前使用C++(創建AST),並從C++對象調用yyparse()..

感謝

+0

flex和bison都有標誌來生成C++,而不是C. – vonbrand 2013-01-23 17:33:49

+1

Yuck。在C++中使用帶有靜態全局變量的不純的非可重入C語言分析器並不是一個好主意。在C++模式下分別使用flex和bison會更清晰。 https://www.gnu.org/software/bison/manual/bison.html#A-Complete-C_002b_002b-Example – Barry 2014-05-12 02:56:30

回答

10

您需要extern "C" {}yylex到在shady.l

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

    #include "shady.tab.h" 
%} 

%% 

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

...etc... 

此外,添加僞語法規則後,我才得以建立,並與剛剛運行此:

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