C标识符的正则表达式

时间:2014-12-18 23:14:01

标签: regex flex-lexer

我使用Flex来标记输入文件,这样我最终也可以使用Bison创建一个简单的C编译器。

所以我仍然在使用Flex,我试图提取数字并忽略标识符和空格

%{

#include "stdio.h"

%}

dgt [0-9]
letter [A-Za-z]
white [ \r\t]+
id {letter}({letter}|{dgt})*
number {dgt}+

%%
{number} return atoi(yytext);
{id} { }
{white} { }

%%

void main(){
    int val=0;
    while( (val=yylex())>0)
    printf("You Entered %d\n",val); 
}

这里的问题是输入文件如下:

 hello 123 test assadf507ascv 123asd 0

我得到了这个输出:

You Entered 123
You Entered 123

我需要它才能识别数字,第二个输出来自123asd,它应该是一个无效的标识符。

我哪里出错了?!! 我应该制定规则来明确地检测到这种情况吗?

2 个答案:

答案 0 :(得分:3)

您的号码定义只是查找一个或多个数字,这些数字将匹配任何地方的数字组,即使它们与非数字字符连接在一起。

number {dgt}+

这是RegEx的等价物:

[0-9]+

听起来你需要测试数字字符后面没有不需要的字符来提取有效数字。我这样做是通过创建另一个规则来明确匹配这些不良术语,这导致它们被忽略为"数字"。

示例:test.flex:

%{

#include "stdio.h"

%}

letter [A-Za-z]
white [ \r\t]+
id {letter}({letter}|{dgt})*
dgt [0-9]
number {dgt}+
invalid [0-9]+[a-zA-Z_]+

%%

{id} { }
{white} { }
{invalid} { }
{number} return atoi(yytext);

%%

void main(){
    int val=0;
    while( (val=yylex())>0)
    printf("You Entered %d\n",val);
}

您可能想要更改invalid定义的后半部分,具体取决于您不想跟随数字的字符。另请注意,invalid规则必须位于number规则之前,因此它将首先匹配并丢弃无效的条款。

hello 123 test assadf507ascv 234asdf 456 0   
You Entered 123
You Entered 456

请参阅Flex manual chapter on Patterns

答案 1 :(得分:0)

我不熟悉flex,但也许你可以试试这个:

dgt [0-9]
letter [A-Za-z]
white [ \r\t]+
id {letter}({letter}|{dgt})*
number \b{dgt}+\b

我不知道是否支持\b,但在正则表达式中它意味着“字边界”。如果不支持,您也可以尝试:

number {white}{dgt}+{white}

但请注意,这不会捕获出现在行首或行尾的数字。也许

number (^|{white}){dgt}+($|{white})