Flex的正则表达式规则

问题描述

我对flex lexer的规则感到困惑

我的词法分析器可以识别十进制和十六进制,但是当我想将它们两者都作为整数时进行合并。

flex告诉我是test.l:13: unrecognized rule

这是我的词法分析器文件

test.l

%{  
    #include <stdio.h>
    #include <string.h>
    int yylval;
%}

digit       [0-9]
decimal     ^({digit}|[1-9]{digit}+)$
hex         0[xX][0-9a-fA-F]+
integer     {hex}|{decimal}

%%
{integer}     {printf("integer - %s \n",yytext);}
%%

// run function
int yywrap(void) { 
    return 1; 
}

int main(void) {
    yylex();
    return 0;
}

解决方法

您为什么认为需要锚定decimal模式?编写方式将只匹配一行上的数字,甚至没有空格。

无论如何,造成问题的是锚点。在(f)lex中,^只能出现在模式的开头,而{hex}|{decimal}的宏扩展在中间有^

将其更改为{decimal}|{hex}将无济于事,因为flex通常用括号将宏扩展括起来,以避免错误的运算符分组。 (如果宏以$结尾,则不会插入括号,但{integer}的立即替换主体不会以$结尾。)

这实际上使得不可能在宏中使用^锚,并且很难使用$。您可能根本不需要这些锚,因此最简单的解决方案可能就是摆脱它们。但是,如果您确实需要锚定模式,则必须在任何宏之外的规则本身中进行锚定。

您可能还会考虑不依赖flex宏。像C宏一样,它们的作用不如最初出现时有用。如果您想要有意义的字符范围名称,您会发现flex已经提供了它们:[[:digit:]][0-9][[:xdigit:]][0-9a-fA-F],依此类推(与C的<ctypes.h>标头中提供的类别相同)。