2010-11-25 82 views
8

在我的編程項目中,我想使用flex/bison解析命令行屬性。我的程序是這樣調用的:如何用flex/bison解析C字符串(char *)?

./prog -a "(1, 2, 3)(4, 5)(6, 7, 8)" filename 

是否可以使用flex/bison解析這個字符串而不寫入文件並解析該文件?

+2

我認爲編寫一個簡單的狀態機比使用Flex或Bison更容易和更簡潔。 – 2010-11-25 17:45:00

+0

如果你認爲你需要flex和bison,那麼這個語法有多複雜呢?我必須同意詹姆斯的觀點:只要用可選的空格和括號來解析用逗號分隔的整數列表,C就是最好的選擇。 – 2010-11-25 17:54:14

+0

我到目前爲止只使用flex和bison。仔細看看,只使用flex會更有意義。 – 2010-11-29 09:27:06

回答

2

我想你可以實現類似的東西(我做了類似的事情),通過使用fmemopen創建從char*流,然後替換到標準輸入

類似的東西(不知道這是否是因爲功能齊全實際上,我試圖記住可用的系統調用,但它會與此類似)

char* args = "(1,2,3)(4,5)(6,7,8)" 
FILE *newstdin = fmemopen (args, strlen (args), "r"); 
FILE *oldstdin = fdup(stdin); 

stdin = newstdin; 

// do parsing 

stdin = oldstdin; 
-1

答案是「是的」。請參閱O'Reilly出版物,名爲「lex & yacc」,Doug Brown的第二版,John Levine,Tony Mason。請參閱第6章「從字符串輸入」一節。

我也剛剛注意到John Levine在「flex and bison」第5章的「Input from Strings」一節中有一些很好的說明。注意例程yy_scan_bytes(char * bytes,int len),yy_scan_string(「string」)和yy_scan_buffer(char * base,yy_size_t size)。我自己並沒有從字符串中掃描,但很快就會嘗試。

1

這是一個完整的flex示例。

%% 

<<EOF>> return 0; 

. return 1; 

%% 

int yywrap() 
{ 
    return (1); 
} 

int main(int argc, const char* const argv[]) 
{ 
    YY_BUFFER_STATE bufferState = yy_scan_string("abcdef"); 

    // This is a flex source. For yacc/bison use yyparse() here ...  
    int token; 
    do { 
     token = yylex(); 
    } while (token != 0); 

    // Do not forget to tell flex to clean up after itself. Lest 
    // ye leak memory. 
    yy_delete_buffer(bufferState); 

    return (EXIT_SUCCESS); 
} 
0

另一個例子。這個重新定義了YY_INPUT宏:

%{ 
int myinput (char *buf, int buflen); 
char *string; 
int offset; 
#define YY_INPUT(buf, result, buflen) (result = myinput(buf, buflen)); 
%} 
%% 

[0-9]+    {printf("a number! %s\n", yytext);} 

.     ; 
%% 

int main() { 
    string = "(1, 2, 3)(4, 5)(6, 7, 8)"; 
    yylex(); 
} 

int myinput (char *buf, int buflen) { 
    int i; 
    for (i = 0; i < buflen; i++) { 
     buf[i] = string[offset + i]; 
     if (!buf[i]) { 
      break; 
     } 
    } 
    offset += i; 
    return i; 
}