我使用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
,它应该是一个无效的标识符。
我哪里出错了?!! 我应该制定规则来明确地检测到这种情况吗?
答案 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
答案 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})