首页 > 解决方案 > Flex 的正则表达式规则

问题描述

我对弹性词法分析器的规则感到困惑

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

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;
}

标签: regexflex-lexer

解决方案


为什么你认为你需要锚定你的decimal模式?它的写法,它只会匹配一个单独在一行上的数字,甚至没有任何空格。

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

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

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

你也可以考虑不依赖 flex 宏。与 C 宏一样,它们并不像最初看起来那样有用。如果您想要字符范围的有意义的名称,您会发现 flex 已经提供了它们:[[:digit:]]is [0-9]; [[:xdigit:]]is等(与 C 的标题[0-9a-fA-F]中提供的类别相同)。<ctypes.h>


推荐阅读