奇怪的弹性行为

时间:2015-05-17 10:48:23

标签: flex-lexer lexical-analysis

我使用以下扫描仪 dice notation 扫描仪

%option debug
%option noyywrap
%option yylineno

%{    
#include <limits.h>
#include "parser.h"
%} 

%%

[0-9]+      {
    errno = 0;
#ifdef DEBUG
    printf("Scanner: NUMBER %s (%i)\n", yytext, yyleng);
#endif
    long number =  strtol( yytext, NULL, 10);
    if ( errno != 0 && errno != ERANGE && number == 0 ) {
        printf("Error: incorrect number %s\n", yytext);
        exit(EXIT_FAILURE);
    }
    // we only accept integers
    if ( number > INT_MAX ) {
        printf("Error: %s is too large\n", yytext );
        exit(EXIT_FAILURE);
    }
    yylval.int_type = (int)number;
    return NUMBER;
}

\+          { return PLUS;    }

\-          { return MINUS;   }

["*"x]      { return TIMES;   }

\/          { return DIV;     }

d|D         {
#ifdef DEBUG
    printf("Scanner: DICE\n");
#endif
    return DICE;
}

f|F         { return FUDGE;   }

h|H         { return HIGH;    }

l|L         { return LOW;     }

"("         { return LPAREN;  }

")"         { return RPAREN;  }

"{"         {
#ifdef DEBUG
    printf("Scanner: LCURLY\n");
#endif
    return LCURLY;
}

"}"         {
#ifdef DEBUG
    printf("Scanner: RCURLY\n");
#endif
    return RCURLY;
}

">"         { return GT; }
">="        { return GE; }
"<"         { return LT; }
"<="        { return LE; }
"!="        { return NE; }
"<>"        { return NE; }
"%"         { return PERCENT; }

,           {
#ifdef DEBUG
    printf("Scanner: COMMA\n");
#endif
    return COMMA;
}

[[:blank:]] {
    /* ignore spaces */
#ifdef DEBUG
    printf("Scanner: BLANK\n");
#endif
}

.           { printf("Error: unknown symbol '%s'\n", yytext); exit(EXIT_FAILURE); }

%%

当我解析4{3d6, 1d5}之类的东西时,一切正常。但是对于4{3d6,1d5},扫描程序有一个奇怪的行为并且错过了第一个大括号。

调试输出

--accepting rule at line 20 ("43")
Scanner: NUMBER 43 (2)
--accepting rule at line 47 ("d")
Scanner: DICE
--accepting rule at line 20 ("641")
Scanner: NUMBER 641 (3)
--accepting rule at line 47 ("d")
Scanner: DICE

尽管4{3中未包含43,但扫描程序仍将{[0-9]+匹配。

由于不同的行为是由表达式后面的空白触发的,我怀疑我在空间处理中遗漏了一些东西,但我不明白为什么它应该在表达式的开头混淆整数的匹配。

任何提示?

1 个答案:

答案 0 :(得分:3)

如果Unix shell正在接受您的输入4{3d6,1d5},则会扩展为43d6 41d5。你的词法分析器完全忽略了空格,然后变成43d641d5,你(你自己模拟了一些截断?)是你报告的内容。

我复制了你的代码,当我运行类似的东西时:

echo 4{3d6,1d5} | ./lex

我遇到了你的问题。如果我跑:

echo '4{3d6,1d5}' | ./lex
然后一切都很好。如果我将4{3d6,1d5}键入文件,然后在文件上运行词法分析器,那也没关系。