2015-05-17 69 views
3

我有一个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 

虽然{[0-9]+包括该扫描器是匹配4{3作为43

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

任何提示?

+0

你在调用代码中用'yytext'做些奇怪的事情吗? – EJP

+0

@EJP我不会在任何地方修改它。当表达式 – Matteo

+0

中没有空格时,问题就出现了。注意'641'也有错误。我的下一个问题是,你是否确定输入的确看起来像你的想法? – EJP

回答

3

如果一个Unix shell获得您的输入4{3d6,1d5}将被扩展为43d6 41d5。你的词法分析器完全忽略了空白,所以这就变成了43d641d5,这是你的报告模式(模块化了一些截断?)。

我复制你的代码,当我运行类似:

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

我明白你的问题。如果我运行:

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

然后一切都很好。如果我在文件中输入4{3d6,1d5},然后在该文件上运行词法分析器,也很好。

+0

同意 - 我认为这是正确的诊断(我也可以重现行为)。 –

+0

哦,我......我觉得很蠢。我试图在不考虑shell扩展的情况下调试代码。 ... 谢谢! – Matteo