flex同一行中的启动条件

时间:2014-11-08 13:33:23

标签: flex-lexer

我正试图解决这个问题,这是为了学校的事情,我需要一些帮助。 我试图计算如何将一行分成多个部分,因为在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

没有什么不同

1 个答案:

答案 0 :(得分:1)

您的任何模式中都没有识别换行符。因此,当flex访问换行符时,默认规则将匹配,并且您仍然处于{NOTA}的开始条件。

我建议使用%option nodefault,这会产生错误而不是调用默认操作。然后你必须为任何其他字符串插入自己的匹配项。一个简单的错误操作是匹配任何字符,然后跳到换行符或EOF。当你点击换行符时,不要忘记将开始条件重置为初始条件。实际上,您可能只想使用以下内容:

\n { BEGIN(INITIAL); }

虽然如果缺少成绩,则不会发出错误信号。

flex并不是这种解析的理想工具,但您使用启动条件的方式是合理的。