%{
int count=0;
%}
%%
[0-9]*[1|3|5|7|9]|[0-9]*[" "][1|3|5|7|9] {count ++;}
.+ {}
%%
int main(){
yyin=fopen("abc.txt","r");
yylex();
printf("no are %d",count);
return 0;
}档案内容如下:
答案应该是三个,即15311,15和21。怎么做?
发布于 2017-09-21 22:45:47
这里最有效的方法不是让正则表达式识别奇数整数,而是识别整数,然后测试yytext的最后一个数字。
[0-9]+ {
/* insert slick trick here exploiting ASCII digit representation */
switch (yytext[yyleng-1]) {
case '1': '3': '5': '7': '9':
count++;
break;
}
}例如,如果我们做天真的事情,只提取以奇数结尾的数字序列,如下所示:
[0-9]*[13579] { ... }我们遇到了这样的问题:给出像1234这样的输入,上面的提取令牌123并将4留在输入流中!然后,这个4成为.+规则的牺牲品,该规则会吃掉其他所有东西。
要用正则表达式来实现这一点,我们基本上必须有两个规则:一个识别奇数十进制数,另一个识别偶数。这些必须是相互排斥的:
[0-9]*[13579] { count++; }
[0-9]*[02468] { }而且,“全抓”的规则是完全错误的。绝对不能是.+!.+的问题是,假设输入是这个JUNK1234。好吧,这不符合数字的规则,所以它可以归结为.+。但是,哎呀,.+吃掉了所有该死的东西,包括1234。也许我们只是想跳过JUNK并识别1234
作为经验法则,在不匹配的情况下尝试恢复的lexer中的所有捕获规则应该只消耗一个字符:
. {}注意,在Lex中,.与换行符不匹配。因此,为了跳过换行符,我们最好这样做:
(.|\n) {}否则,换行符将与我们的规则不匹配,而是会成为Lex自己的默认规则的牺牲品,它匹配一个字符并打印它。程序将响应输入中的所有换行符。
发布于 2017-09-21 22:16:42
.+匹配一个完整的行。如果这一行包含几个数字,flex将选择.+规则,因为最大munch规则。在编写文件时,.+规则还将用于包含一个数字的行,因为您的其他模式匹配一个奇数后面跟着一个奇数的空格,再加上将|和"放入字符类中的其他一些东西,它们在这些类中充当普通字符。
因此,修正奇数的模式,并将回退模式从.+更改为.|\n,以便它只匹配一个字符。(之所以需要换行符,是因为在flex中,通配符模式.与换行符不匹配)。有关详细信息,请参阅rhe 挠曲手册。
如果希望查看flex正在做什么,在使用flex创建扫描仪时使用-d调试选项。这将跟踪每个模式匹配;它也在调试选项部分的flex手册中进行了描述。
https://stackoverflow.com/questions/46347992
复制相似问题