Flex 描述导致不匹配的规则
Flex description causing unmatched rule
在我更具体的案例之前,我的 flex 描述似乎已经涵盖了所有内容。我确定这是我的错字,但我无法判断是哪条规则导致我的其余规则无法匹配。我相信很可能是我创建的字符串描述。但是我仍然不确定,正在寻找答案。
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。
BEGIN
将同时匹配 {identifier}
和 "BEGIN"
。在这种情况下,flex 将(如文档所示)匹配文件中的第一条规则,即 {identifier}
。因此,"BEGIN"
将永远不会被匹配。
坦率地说,我会放弃大部分(如果不是全部)这些宏定义。您可以使用 [[:alpha:]_]
代替 {alpha}
,使用 [[:digit:]]
代替 {digit}
(实际上,[[:alnum:]]*
代替 ({alpha}|{digit})*
)。在大多数情况下,使用宏仅用于将模式与规则操作分开,使代码更难阅读(恕我直言)。
如果您有非常复杂的模式或多次使用但很少应用的模式,宏可能会很有用。
在我更具体的案例之前,我的 flex 描述似乎已经涵盖了所有内容。我确定这是我的错字,但我无法判断是哪条规则导致我的其余规则无法匹配。我相信很可能是我创建的字符串描述。但是我仍然不确定,正在寻找答案。
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。
BEGIN
将同时匹配 {identifier}
和 "BEGIN"
。在这种情况下,flex 将(如文档所示)匹配文件中的第一条规则,即 {identifier}
。因此,"BEGIN"
将永远不会被匹配。
坦率地说,我会放弃大部分(如果不是全部)这些宏定义。您可以使用 [[:alpha:]_]
代替 {alpha}
,使用 [[:digit:]]
代替 {digit}
(实际上,[[:alnum:]]*
代替 ({alpha}|{digit})*
)。在大多数情况下,使用宏仅用于将模式与规则操作分开,使代码更难阅读(恕我直言)。
如果您有非常复杂的模式或多次使用但很少应用的模式,宏可能会很有用。