我正试图解决这个问题,这是为了学校的事情,我需要一些帮助。 我试图计算如何将一行分成多个部分,因为在flex中没有分组,我试图用启动条件完成它,但它没有像我预期的那样工作。
%s LINE_NAME
%s LINE_GRADE
ws [ \t]
DNI [0-9]{7,8}-[A-Za-z]
DNIERROR [0-9A-Za-z]+-[0-9A-Za-z]+
NOTA [0-9].[0-9]{1,2}|10.[0]{1,2}
NOTAERROR [0-9]{2}.[0-9]{2,}
NOMBRE [A-Z][a-z]+
NOMBRECOMPLETO {NOMBRE}{ws}+{NOMBRE}","{ws}*{NOMBRE}
%%
<INITIAL>^{DNI} {
printf("%s;", yytext);
BEGIN LINE_NAME;}
<LINE_NAME>^{ws}*{NOMBRECOMPLETO} {
printf("%s;", yytext);
BEGIN LINE_GRADE;}
<LINE_GRADE>^{ws}*{NOTA} {
printf("%s\n", yytext);
;}
%%
int main(int argc, char* argv[]){
yylex();
}
我的输入文件类似于
11223344-Z Alonso Barreiro, Ana 5.68
01234567-B Alonso Barros, Antonio 4.8
12345678-X Alonso Calvo, Andres 2.8
13345678-X Barreiro Calvo, Luis 3.68
它应该产生类似
的输出11223344-Z;Alonso Barreiro, Ana;5.68
01234567-B;Alonso Barros, Antonio;4.8
12345678-X;Alonso Calvo, Andres;2.8
13345678-X;Barreiro Calvo, Luis;3.68
但它只识别第一个状态11223344-Z;
,并将其余部分呕吐为未解析状态。
我理解这个代码应该在一个输入上工作,该输入将每个部分分成不同的行,但是我需要知道我是否可以在一行上做我正在做的事情,所以我可以检索每个部分并将它们分开使用像“;”这样的标记或者其他什么。
提前致谢。
更新: 按照rici的回答后,我编辑了我的代码,看起来像这样
%s LINE_NAME
%s LINE_GRADE
%s LINE_OK
%s LINE_ERROR_DNI
%s LINE_ERROR_GRADE
ws [ ]
DNI [0-9]{7,8}-[A-Za-z]
DNIERROR [0-9A-Za-z]+-[0-9A-Za-z]+
NOTA [0-9].[0-9]{1,2}|10.[0]{1,2}
NOTAERROR [0-9]{2}.[0-9]{2,}
NOMBRE [A-ZÁÉÍÓÚ][a-záéíóúü]+
NOMBRECOMPLETO {NOMBRE}{ws}+{NOMBRE}","{ws}*{NOMBRE}
%option nodefault
%%
<INITIAL>^{DNI} {
printf("%s;", yytext);
BEGIN LINE_NAME;}
<INITIAL>^{DNIERROR} {
printf("%s; x;", yytext);
BEGIN LINE_ERROR_DNI;}
<LINE_NAME>^\t{NOMBRECOMPLETO} {
printf("%s;", yytext);
BEGIN LINE_GRADE;}
<LINE_GRADE>^\t{NOTA} {
printf("%s", yytext);
BEGIN LINE_OK;}
<LINE_GRADE>^\t{NOTAERROR} {
printf("%s; x", yytext);
BEGIN LINE_ERROR_GRADE;}
<LINE_ERROR_DNI>.*\n {
printf(" - DNI ERROR\n");
BEGIN(INITIAL);}
<LINE_ERROR_GRADE>.*\n {
printf(" - GRADE ERROR\n");
BEGIN(INITIAL);}
<LINE_OK>{ws}*\n {
printf(" - GOOD\n");
BEGIN(INITIAL);}
\n {
printf(" - UNEXPECTED END OF LINE\n");
BEGIN(INITIAL);}
<<EOF>> {
yyterminate();}
.* { printf(" ");}
%%
int main(int argc, char* argv[]){
yylex();
}
它仍然无法正常工作,我文件中的每一行都显示' - 意外结束文件' 我错的是什么?
当然,如果我添加这样的规则
<INITIAL>^{DNI}\t{NOMBRECOMPLETO}\t{NOTA} {
printf("%s;", yytext);
BEGIN LINE_OK;}
它认为这是一个好的路线,但这不是我想要实现的,因为这与仅仅{DNI}\t{NOMBRECOMPLETO}\t{NOTA}
然后strtoking
答案 0 :(得分:1)
您的任何模式中都没有识别换行符。因此,当flex访问换行符时,默认规则将匹配,并且您仍然处于{NOTA}
的开始条件。
我建议使用%option nodefault
,这会产生错误而不是调用默认操作。然后你必须为任何其他字符串插入自己的匹配项。一个简单的错误操作是匹配任何字符,然后跳到换行符或EOF。当你点击换行符时,不要忘记将开始条件重置为初始条件。实际上,您可能只想使用以下内容:
\n { BEGIN(INITIAL); }
虽然如果缺少成绩,则不会发出错误信号。
flex
并不是这种解析的理想工具,但您使用启动条件的方式是合理的。