首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用空格分隔的文件中计数奇数整数的lex程序

用空格分隔的文件中计数奇数整数的lex程序
EN

Stack Overflow用户
提问于 2017-09-21 15:37:19
回答 2查看 1.8K关注 0票数 0
代码语言:javascript
复制
%{
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;
}

档案内容如下:

  1. 15311
  2. 2
  3. 15 21
  4. 2

答案应该是三个,即15311,15和21。怎么做?

EN

回答 2

Stack Overflow用户

发布于 2017-09-21 22:45:47

这里最有效的方法不是让正则表达式识别奇数整数,而是识别整数,然后测试yytext的最后一个数字。

代码语言:javascript
复制
[0-9]+ {
   /* insert slick trick here exploiting ASCII digit representation */
   switch (yytext[yyleng-1]) {
   case '1': '3': '5': '7': '9':
     count++;
     break;
   }
}

例如,如果我们做天真的事情,只提取以奇数结尾的数字序列,如下所示:

代码语言:javascript
复制
[0-9]*[13579] { ... }

我们遇到了这样的问题:给出像1234这样的输入,上面的提取令牌123并将4留在输入流中!然后,这个4成为.+规则的牺牲品,该规则会吃掉其他所有东西。

要用正则表达式来实现这一点,我们基本上必须有两个规则:一个识别奇数十进制数,另一个识别偶数。这些必须是相互排斥的:

代码语言:javascript
复制
[0-9]*[13579] { count++; }
[0-9]*[02468] { }

而且,“全抓”的规则是完全错误的。绝对不能是.+.+的问题是,假设输入是这个JUNK1234。好吧,这不符合数字的规则,所以它可以归结为.+。但是,哎呀,.+吃掉了所有该死的东西,包括1234。也许我们只是想跳过JUNK并识别1234

作为经验法则,在不匹配的情况下尝试恢复的lexer中的所有捕获规则应该只消耗一个字符:

代码语言:javascript
复制
. {}

注意,在Lex中,.与换行符不匹配。因此,为了跳过换行符,我们最好这样做:

代码语言:javascript
复制
(.|\n) {}

否则,换行符将与我们的规则不匹配,而是会成为Lex自己的默认规则的牺牲品,它匹配一个字符并打印它。程序将响应输入中的所有换行符。

票数 1
EN

Stack Overflow用户

发布于 2017-09-21 22:16:42

.+匹配一个完整的行。如果这一行包含几个数字,flex将选择.+规则,因为最大munch规则。在编写文件时,.+规则还将用于包含一个数字的行,因为您的其他模式匹配一个奇数后面跟着一个奇数的空格,再加上将|"放入字符类中的其他一些东西,它们在这些类中充当普通字符。

因此,修正奇数的模式,并将回退模式从.+更改为.|\n,以便它只匹配一个字符。(之所以需要换行符,是因为在flex中,通配符模式.与换行符不匹配)。有关详细信息,请参阅rhe 挠曲手册

如果希望查看flex正在做什么,在使用flex创建扫描仪时使用-d调试选项。这将跟踪每个模式匹配;它也在调试选项部分的flex手册中进行了描述。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46347992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档