2013-04-21 156 views
0

在编写Flex中的令牌生成我就遇到了这个恼人的错误: “无法识别的规则”Flex的“无法识别的错误”

我的代码是:

/* Keywords */ 

TYPE  int|double|bool|char 
LOGICAL  if|else|for|foreach|do|while|switch|return 
MACROWORD import|define|ifndef|endif|elseif|udef 
MACRO  "#"{MACROWORD} 

KEYWORD  {TYPE}|{LOGICAL}|{MACRO} 

/* Literals */ 

DIGIT  [0-9] 
DIGITS  {DIGIT}+ 
OPT_FRAC ("."{DIGITS})? 
OPT_EXP  (E(+|-){DIGITS})? 

NUMBER  {DIGITS}{OPT_FRAC}{OPT_EXP} 

LETTER  [a-zA-Z] 

/* Identifier */ 

ID   {LETTER}({LETTER}|{DIGIT})* 

/* Operators */ 

OPERATOR "+"|"-"|"*"|"/"|"^"|"=""="|"<""="|">""="|">"|"<"|"!""="" 

%% 

{KEYWORD} printf("(Keyword, %s)\n", yytext); 

{NUMBER} printf("(Numeric Literal, %s)", yytext); 

{ID} printf("(Identifier, %s)", yytext); 

{OPERATOR} printf("(Operator, %s", yytext); 

[ \n\t]  /* Ignore Whitespace */ 

"{"   printf("(L Bracket, %s)", yytext); 

"}"   printf("(R Bracket, %s)", yytext); 

"("   printf("(L Parens, %s)", yytext); 

")"   printf("(R Parens, %s", yytext); 

";"   printf("(Semicolon, %s", yytext); 

%% 

main() 
{ 
    yylex(); 
} 

可悲的是,这不仅导致:

“Scanner.lex:39:无法识别的规则” 重复19次随后的一个实例:

“Scanner.lex:43:无法识别的规则”

第39行是:

{NUMBER} printf("(Numeric Literal, %s)", yytext); 

和43号线:

{OPERATOR} printf("(Operator, %s", yytext); 

我找遍周围的互联网,发现this answer also on stackoverflow等等这些建议增加“^”到定义线的开头,因此我将第39行参考(NUMBER)更改为:

NUMBER ^{DIGITS}{OPT_FRAC}{OPT_EXP} 

这没有什么。 有什么建议吗?

回答

1

这很吓人,因为OPT_EXP中的+没有任何东西给+。 (这是一个RE +,不是文字加号。)

您的操作员定义有一个太多的双引号。

+0

糟糕!没有看到有关OPT_EXP的信息。同样对于太多的双引号,你如何解决这个问题/我说“=”“=”的正确语法是什么? – nanoprogrammer 2013-04-21 13:07:49

+0

啊,你可以使用“==”就好(我使用了太多的C++,并假设“在Flex中就像'在C/C++中一样) – nanoprogrammer 2013-04-21 13:24:12

0
OPT_EXP  ([Ee][-+]{DIGITS})? 
OPERATOR1 [-+*/=^><] 
OPERATOR2 ==|<=|>=|==|!= 

如果我们只对操作符使用一个定义会有问题。原因是,如果flex看到<=它与它匹配的是什么?作为<,然后=或作为<=所有togeather ?.我不认为lex支持向前看。为此,我决定将OPERATOR分成两个定义OPERATOR1OPERATOR2。然后在规则部分,您有2规则

{OPERATOR2} printf("(Operator, %s", yytext); 
{OPERATOR1} printf("(Operator, %s", yytext); 

我们知道,法会preffer最长匹配规则,以便在<=的情况下,{OPERATOR2}规则将触发

  • 注1:当我将-作为字符类中的第一个字符,例如[-+*/]将其视为常规字符而不是特殊字符指示范围。例如[+-*/]将是错误的,因为-+*之间意味着在+*之间的所有字符。
  • 注意2:我确定^不是字符类中的第一个字符,因为^作为字符类中的第一个字符表示否定。例如,[^0-9]表示匹配除数字以外的每个字符。