2013-10-05 123 views
0

如何使yyparse函數從C字符串讀取其輸入?使用Bison從char *字符串解析

試圖yy_scan_buffer(使用 「FP」 的前綴,而不是 「YY」):

extern YY_BUFFER_STATE fs_scan_string (const char *str); 

struct fs *parse(char *s) 
{ 
fp_scan_buffer(s); 
int r = fpparse(); 
return r == 0 ? AST : NULL; 

} 

但是:

h1.cpp:27: error: ‘YY_BUFFER_STATE’ does not name a type 
h1.cpp: In function ‘fs* parse(char*)’: 
h1.cpp:32: error: ‘fp_scan_buffer’ was not declared in this scope 

使用yy_delete_buffer,同樣的結果嘗試:在未聲明這個範圍。

fp.y

%{ 
#include "ft.h" 
#include <map> 
#include <iostream> 

int fplex(); 
int fperror(char *p); 
int fperror(char *p) { } 

using namespace std; 

struct fs *AST; 
bool fpworking = true; 
%} 

%union { 
    struct fs *f; 
    struct ts *t; 
    std::list<struct ts *> *tl; 
    std::string *s; 
} 

%token END_OF_FILE 
MORE TOKEN HERE... 

%% 

s : formula '\n' { AST = $1; fpworking = true; YYACCEPT; } 
MORE RULE HERE... 

FP.L

%{ 
#include <iostream> 
#include <list> 
using namespace std; 
#include "fp.tab.h" 
%} 

%option noyywrap 

%% 
[a-z][a-zA-Z0-9]*  { fplval.s = new std::string(fptext); return (TERM_ID); } 
MORE PATTERN HERE... 

h1.cpp

#include <iostream> 
#include <list> 
#include <string> 
#include <map> 
#include <stdlib.h> 
#include <fstream> 
#include "ft.h" 

int fpparse(); 
int signparse(); 

extern bool fpworking; 
extern struct fs *AST; 

int main(int argc, char **argv) 
{ 
    MORE CODE HERE... 
} 
+0

請注意正確的標記。 Flex用於Adobe/Apache UI框架。 Flex-lexer用於詞法分析器。 – JeffryHouser

+0

問題出在您顯示的代碼與您未顯示的代碼之間的交互中。請構建一個完整的,自包含的,精簡的.y文件,演示相同的問題。 – zwol

回答

1

爲了使用各種靈活定義的符號(如YY_BUFFER_STATEyy_scan_buffer),代碼必須放在.l文件的第三部分。

問題是這些符號只能在lex.yy.c文件中定義,而不能在任何其他地方可以使用的頭文件中定義。

因此,所有你需要做的就是把你的parse代碼(上面的第一個塊)在.L文件的末尾(第二%%行之後),並從main調用它,它應該工作的罰款。

2

通過bison產生的解析器不進行I/O。讀取(或以其他方式獲取)輸入的責任由掃描儀提供,通常由(f)lex生成。您所指的緩衝區管理功能是flex框架的一部分。它們不會被導出到任何頭文件中,因此您需要在插入到flex輸入文件的代碼中使用它們,或者將它們明確地添加到您自己的頭文件中。

傳統使用的flexbison(的lexyacc或,一般地,衍生物)很大程度上依賴於全局狀態變量,使得難以多個語法分析器和/或掃描儀集成到單個可執行文件。修改yy前綴並不能真正解決這個問題,但它確實允許多個單身人士。代碼生成器的更新版本允許生成pure解析器和掃描器,它們將包含該狀態的結構作爲附加參數。可以將這些狀態添加到這些結構中,甚至可以將它們組合到一個單一結構中。這可以產生一個更優雅的界面,但這些工具對API設計無助。無論如何,使用純粹的解析器和掃描器,更少的狀態訪問是外部可用的。簡而言之,您應該將自己的緩衝區管理API添加到您的flex文件中,將其接口導出到您自己的頭文件中,然後在掃描程序,解析器和消費者中導入該文件。