%{
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。 怎么办?
答案 0 :(得分:0)
.+
匹配完整的一行。如果该行包含多个数字,则flex将选择.+
规则,因为最大的munch规则。在您的文件被写入时,.+
规则也将用于包含一个数字的行,因为您的其他模式匹配一个奇数后跟一个空格后跟一个奇数位,加上其他一些东西因为你的推杆<{1}}和|
在角色类中,它们充当普通角色。
因此,修复奇数的模式,并将后备模式从"
更改为.+
,以便它只匹配一个字符。 (需要换行符,因为在flex中,通配符模式.|\n
与换行符不匹配)。有关详细信息,请参阅rhe flex manual。
如果要查看flex正在执行的操作,请在使用flex创建扫描程序时使用.
调试选项。这将跟踪每个模式匹配;它也在调试选项部分的flex手册中进行了描述。
答案 1 :(得分:0)
这里最傻瓜的方法不是试图让正则表达式识别奇数整数,而是识别整数,然后测试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
?
根据经验,词法分析器中的一个包罗万象的规则试图在不匹配的情况下恢复它应该只消耗一个字符:
. {}
请注意,在Lex中,.
与新行不匹配。因此,为了跳过换行符,我们最好这样做:
(.|\n) {}
否则新行不符合我们的规则,而是成为Lex自己的默认规则的受害者,该规则匹配一个字符并打印出来。该程序将回显输入中的所有换行符。