Flex描述导致无与伦比的规则

时间:2017-10-08 20:31:08

标签: parsing flex-lexer

在我更具体的案例之前,我的弹性描述似乎有一个问题。我确定这是我的错字,但我不知道哪条规则导致我的其余规则无法比拟。我相信可能怀疑是我创建的字符串描述。但是我仍然不确定并且正在寻找答案。

branch.l文件:

%option noyywrap

%{
#include "global.h"
%}

delim           [\t ]
ws              {delim}+
digit           [0-9]
num             {digit}+
alpha           [_a-zA-Z]
identifier      {alpha}({alpha}|{digit})*
relation        [<]|[>]|[>][=]|[<][=]|[=][=]|[!][=]
string          ["][a-zA-Z0-9]*["]

%%

{ws}            {/* skip blanks and tabs */}
{num} {
  tokenval = atoi(yytext);
  return NUM;
}

{identifier} {
  if (strlen(yytext) >= BSIZE) {
    error("compiler error");
  }
  tokensym = lookup(yytext, ID);
  tokensym->count += 1;
  return (int)tokensym->token;
}

"BEGIN"         {return BEGN;}
"IF"            {return IF;}
"THEN"          {return THEN;}
"ELSE"          {return ELSE;}
"GOTO"          {return GOTO;}
"NULL"          {return NUL;}
"READ"          {return READ;}
"PRINT"         {return PRINT;}
"*"             {return '*';}
"+"             {return '+';}
"-"             {return '-';}
"/"             {return '/';}
"("             {return '(';}
")"             {return ')';}
"="             {return '=';}
"."             {return '.';}
"\n"            {lineno++;}
";"             {return ';';}
"END"           {return DONE;}
<<EOF>>         {return DONE;}

{relation} {return RELATION;}
{string} {return STRING;}`

这些是无与伦比的规则......

branch.l:33: warning, rule cannot be matched
branch.l:34: warning, rule cannot be matched
branch.l:35: warning, rule cannot be matched
branch.l:36: warning, rule cannot be matched
branch.l:37: warning, rule cannot be matched
branch.l:38: warning, rule cannot be matched
branch.l:39: warning, rule cannot be matched
branch.l:40: warning, rule cannot be matched
branch.l:51: warning, rule cannot be matched

我无法轻易弄清楚如何添加行号。但警告是指BEGIN - PRINT和ELSE进一步向下的行。

1 个答案:

答案 0 :(得分:1)

BEGIN将同时匹配{identifier}"BEGIN"。在这种情况下,flex将(如文档所述)匹配文件中的第一个规则{identifier}。因此,"BEGIN"永远不会匹配。

坦率地说,我会抛弃那些宏定义中的大多数(如果不是全部)。您可以使用[[:alpha:]_]代替{alpha}[[:digit:]]代替{digit}(实际上,[[:alnum:]]*代替({alpha}|{digit})*)。在大多数情况下,使用宏只能将模式与规则操作分开,使代码更难阅读(恕我直言)。

如果你有多次使用非常复杂的模式或模式,宏可能会很有用,但很少适用。