我正在使用flex + bison C++編寫一個mgf文件解析器(語法:http://www.matrixscience.com/help/data_file_help.html)。flex和野牛:解析字符串不用引號
我意識到了詞法分析器(lex)和解析器(yacc)。但是我有一個我無法解決的問題:當我嘗試解析字符串時。
重要的:不存在「或」串繞
下面是輸入的一個例子:
CHARGE=1+, 2+ and 3+
#some comments
BEGIN IONS
TITLE= Cmpd 1, +MSn(417.2108), 10.0 min //line 20
PEPMASS=417.21083 35173
CHARGE=3+
123.79550 20
285.16455 56
302.14335 146 1+
[other datas ...]
END IONS
BEGIN IONS
[an other one ... ]
在這裏,(最小)詞法分析: MGF_TOKEN_DEBUG是中庸之道打印的宏線
#define MGF_TOKEN_DEBUG(val) std::cout<<"token: "<<val<<std::endl
\n {
MGF_TOKEN_DEBUG("T_EOL");
return token::T_EOL;
}
^[#;!/][^\n]* {
MGF_TOKEN_DEBUG("T_COMMENT");
return token::T_COMMENT;
}
[[:space:]] {}
/** values **/
[0-9]+ {
MGF_TOKEN_DEBUG("V_INTEGER"<<" (="<<yytext<<")");
return token::V_INTEGER;
}
[0-9]+"."[0-9]* {
MGF_TOKEN_DEBUG("V_DOUBLE"<<" (="<<yytext<<")");
return token::V_DOUBLE;
}
[0-9]+("."[0-9]+)?[eE][+-][0-9]+ {
MGF_TOKEN_DEBUG("V_DOUBLE"<<" (="<<yytext<<")");
return token::V_DOUBLE;
}
"+" {
MGF_TOKEN_DEBUG("T_PLUS");
return token::T_PLUS;
}
"=" {
MGF_TOKEN_DEBUG("T_EQUALS");
return token::T_EQUALS;
}
"," {
MGF_TOKEN_DEBUG("T_COMA");
return token::T_COMA;
}
"and" {
MGF_TOKEN_DEBUG("T_AND");
return token::T_AND;
}
/*** keywords */
^"CHARGE" {
MGF_TOKEN_DEBUG("K_CHARGE");
return token::K_CHARGE;
}
^"TITLE" {
MGF_TOKEN_DEBUG("K_TITLE");
return token::K_TITLE;
}
[ others keywords ...]
/**** string : problem here **/
[A-Za-z]([:;,()A-Za-z0-9_.-]|[[:space]])* {
MGF_TOKEN_DEBUG("V_STRING"<<" (="<<yytext<<")");
return token::V_STRING;
}
而(最小化)的解析器。
start : headerparams blocks T_END;
headerparams : /* empty */| headerparams headerparam;
headerparam : K_CHARGE T_EQUALS charge_list T_EOL | [others ...];
blocks : /* empty */ | blocks block;
block : T_BEGIN_IONS T_EOL blockparams ions T_END_IONS T_EOL| T_BEGIN_IONS T_EOL blockparams T_END_IONS T_EOL;
blockparam : K_CHARGE T_EQUALS charge T_EOL | K_TITLE T_EQUALS V_STRING T_EOL | [others...];
ion : number number T_EOL| number number charge T_EOL;
ions : ions ion| ion;
number : V_INTEGER | V_DOUBLE;
charge : V_INTEGER T_PLUS | V_INTEGER T_MINUS;
charge_list : charge| charge_list T_COMA charge | charge_list T_AND charge;
我的問題是,我得到的下一個標記:
[...]
[line 20]
token: K_TITLE
token: T_EQUALS
token: v_STRING (= Cmpd)
token: V_INTEGER (= 1)
Error line 20: syntax error, unexpected integer, expecting end of line
我想有:
[...]
[line 20]
token: K_TITLE
token: T_EQUALS
token: v_STRING (Cmpd 1, +MSn (417.2108), 10.0 min)
token: T_EOL
如果有人能幫助我...
編輯#1 我使用標記串聯「解決」了問題:
法:
[A-Za-z][^\n[:space:]+-=,]* {
MGF_TOKEN_DEBUG("V_STRING"<<" (="<<yytext<<")"))
return token::V_STRING;t
}
YACC:
string_st : V_STRING
| string_st V_STRING
| string_st number
| string_st T_COMA
| string_st T_PLUS
| string_st T_MINUS
;
blockparam : K_CHARGE T_EQUALS charge T_EOL | K_TITLE T_EQUALS string_st T_EOL | [others...];
適當的標籤是'flex-lexer',因爲'flex'與Adobe有關。 – crashmstr