Flex中的正则表达式错误

时间:2018-07-16 08:06:11

标签: regex flex-lexer

我正在学习用Flex编写词法分析器,但发现一个奇怪的问题。 我试图定义关键字 class 的正则​​表达式。

对于我的测试用例:

class T{
}

表达式1:

ws [\t\r\f\v ]
CLASS (^class$)|(^class{ws})|({ws}class{ws})|({ws}class$)

不起作用。

表达式2:

ws [\t\r\f\v ]
CLASS ^class{ws}

有效。

表达式3:

ws [\t\r\f\v ]
CLASS1 ^class{ws}
CLASS {CLASS1}

报告错误,提示 无法识别的规则

我感到很困惑,2和3之间有什么区别吗? 我指的是Flex github上的示例。它只是使用类似的表达式来定义数字。

任何帮助将不胜感激!

更新

我的脚本:

%{

/* Some include headers here */

/* The compiler assumes these identifiers. */
#define yylval cool_yylval
#define yylex  cool_yylex

/* Max size of string constants */
#define MAX_STR_CONST 1025
#define YY_NO_UNPUT   /* keep g++ happy */

extern FILE *fin; /* we read from this file */

/* define YY_INPUT so we read from the FILE fin:
 * This change makes it possible to use this scanner in
 * the Cool compiler.
 */
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
        if ( (result = fread( (char*)buf, sizeof(char), max_size, fin)) < 0) \
                YY_FATAL_ERROR( "read() in flex scanner failed");

char string_buf[MAX_STR_CONST]; /* to assemble string constants */
char *string_buf_ptr;
extern int curr_lineno;
extern int verbose_flag;
extern YYSTYPE cool_yylval;

%}

/*
 * Define names for regular expressions here.
 */
ws              [\t\r\f\v ]
CLASS1          {ws}class$
CLASS2          ^class$
CLASS3          ^class{ws}
CLASS4          {ws}class{ws}
CLASS           {CLASS2}
DARROW          =>
STRING          \"[^\n"]+\"

%%
{CLASS} {return (CLASS);}  /*returned CLASS is defined in other header files*/
%%

1 个答案:

答案 0 :(得分:0)

您所做的事情是不必要的:您可以仅使用class作为正则表达式,而无需锚定或提及空白。您可能会这样定义,因为您要避免较大标识符的正则表达式匹配部分(例如,您不希望将classOf99解释为关键字class,后跟标识符{ {1}},但这不会发生:当当前输入中有多个可以匹配的regexen时,Flex将始终采用导致最长匹配的那个(如果是平局,它将选择一个)在flex文件中排在第一位)。这被称为“最大嚼嘴规则”,可以完全避免此问题。

因此您的代码应仅为Of99,并且不需要任何定义。


也就是说,这就是您的尝试不起作用的原因:

您不能使用class { return CLASS; }^。有时这将导致“无法识别的规则”,而有时则将导致匹配失败。

因此可以解释为什么您的第一个定义不起作用。但是为什么第二个不起作用?如果在其他定义中使用定义,则会将它们隐式括在括号中,以避免出现优先级问题。因此,您也不能在其他定义中使用$^来使用定义。

因此具有涉及$^的多个替代方案的唯一方法是具有这样的单独规则:

$

但是同样,在您的情况下(甚至从未如此),这确实不是必需的。