在我的編程項目中,我想使用flex/bison解析命令行屬性。我的程序是這樣調用的:如何用flex/bison解析C字符串(char *)?
./prog -a "(1, 2, 3)(4, 5)(6, 7, 8)" filename
是否可以使用flex/bison解析這個字符串而不寫入文件並解析該文件?
在我的編程項目中,我想使用flex/bison解析命令行屬性。我的程序是這樣調用的:如何用flex/bison解析C字符串(char *)?
./prog -a "(1, 2, 3)(4, 5)(6, 7, 8)" filename
是否可以使用flex/bison解析這個字符串而不寫入文件並解析該文件?
我想你可以實現類似的東西(我做了類似的事情),通過使用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;
答案是「是的」。請參閱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)。我自己並沒有從字符串中掃描,但很快就會嘗試。
這是一個完整的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);
}
另一個例子。這個重新定義了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;
}
我認爲編寫一個簡單的狀態機比使用Flex或Bison更容易和更簡潔。 – 2010-11-25 17:45:00
如果你認爲你需要flex和bison,那麼這個語法有多複雜呢?我必須同意詹姆斯的觀點:只要用可選的空格和括號來解析用逗號分隔的整數列表,C就是最好的選擇。 – 2010-11-25 17:54:14
我到目前爲止只使用flex和bison。仔細看看,只使用flex會更有意義。 – 2010-11-29 09:27:06