问题描述
我对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>
标头中提供的类别相同)。