2014-09-05 57 views
0

這是一個使用Flex的詞法分析器。Bison Stack語義值

#include <iostream> 
#include <cstdio> 

#define YY_DECL extern "C" int yylex() 

#include "conv.tab.h" 
using namespace std; 

%} 
eq [ \t]*= 
%% 

[ \t]   ; 
(?:POINT|LINE) { yylval.ename = strdup(yytext); return ENAME; } 
x{eq}   { yylval.xval = atof(yytext); 
        return XVAL; } 
y{eq}   { yylval.yval = atof(yytext); 
        return YVAL; } 
.    ; 
%% 

而另一個文件是野牛語法文件

%{ 
#include <iostream> 
#include <cstdio> 
#include <stdio.h> 
using namespace std; 

extern "C" int yylex(); 
extern "C" int yyparse (void); 
extern "C" FILE *yyin; 
extern int line_no; 

void yyerror(const char *s); 

%} 

%union{ 
    float xval; 
    float yval; 
    char *ename; 
} 

%token <ename> ENAME 
%token XVAL 
%token YVAL 

%% 

converter: 
    converter ENAME { cout << "entity = " << $2 << endl; } 
    | converter XVAL {// x -> xval = $2; 
     cout << "x value = " << endl; } 
    | converter YVAL {// y -> yval = $2; 
     cout << "y value = " << endl; } 
    | ENAME { cout << "entity = " << $1 << endl; } 
    | XVAL { cout << "xvalue " << endl; } 
    | YVAL { cout << "yvalue " << endl; } 

%% 
main() { 
    FILE *myfile = fopen("conv.aj", "r"); 

    if (!myfile) { 
      cout << "I can't open file" << endl; 
      return -1; 
    } 

    yyin = myfile; 

    do{ 
      yydebug = 1; 
      yyparse(); 
    } while (!feof(yyin)); 
    yydebug = 2; 
} 

void yyerror(const char *s) { 
    cout << "Parser error! Message: " << s << endl; 
    exit(-1); 
} 

其實,我想從一個文件中檢索值。我使用了Bison Debugger,並且知道這些值無法推送到Bison Stack。所以基本上我要到stack.My文件就像推這些值: POINT X = 38 Ÿ在你的詞法分析器= 47

回答

1

沒有一個號碼匹配,因此從輸入3847都將由您的默認規則(. ;)處理,這將導致它們被忽略。在你的XVALYVAL的規則中,你可以撥打atoiyytext,這將是x=(或y=);這顯然不是一個數字,atoi可能會返回0

我不清楚你的意思是「那些值不能推到Bison Stack上」,但我認爲這個問題與野牛或它的堆棧沒有任何關係。

順便說一句:

  1. 沒有必要在你的語義型兩種不同的成員xvalyval。類型是union,而不是struct,因此具有相同類型的兩個成員(float)是多餘的。

  2. flex不會執行正則表達式捕獲。因此,避免使用(?:...)進行捕捉確實沒有意義;它只是掩蓋了你的語法。你可以使用:

    POINT | LINE:{yylval.ename = strdup(yytext);返回ENAME; }

    另一方面,您最好定義兩種不同的標記類型,這樣可以避免需要strdup。 (你似乎並不被free荷蘭國際集團複製的字符串,所以strdup也是內存泄漏。)或者,你可以在你的語義類型使用的枚舉值:

    POINT { yylval.ename_enum=POINT; return ENAME; } 
    LINE { yylval.ename_enum=LINE; return ENAME; } 
    
  3. . ;是不是一個真正的好主意,特別是在開發過程中,因爲它隱藏了錯誤(比如你擁有的錯誤)。您可以使用%option nodefault來避免flex的默認規則,然後當檢測到非法字符時,flex會顯示錯誤。

  4. 除非您使用的是舊版本的bisonflex,否則您可以將生成的代碼編譯爲c++。不應該需要使用extern "C"