因此,我希望编写一个简单的flex程序,在该程序中,我想使用Regex表达式来标识整数(并将它们与任何“空白”分开)。然后,我使用C代码块,在其中分别递增 integerCount 和 evenCount (初始化为0)。我对Flex和编写正则表达式都是全新的。我正在使用Flex/Bison by O'Reilly Media这本书作为参考 用于编写flex程序。因为我一般不熟悉正则表达式,所以我求助于google进行阅读,这使我进入了以下网站:
Regexr.com帮助我更好地理解正则表达式 能够与他们玩耍并实时查看我的变化 实际上在制作。问题是我能够成功 在网站上写下我想要的正则表达式(我将其放在页面的底部,这样格式更好),但是它无法正常运行 在flex内。这使我意识到flex不使用相同的 我习惯的正则表达式的符号/规则。
This site compares the Rules of regular expressions in Perl, Grep and Lex.如您所见,我使用了许多功能 构建我的正则表达式与Lex不兼容。据我了解,我并不是说要使用 whitespace ,而是使用ASCII空间,卡式返回等。
下面是我在Regexr.com上创建的Regex表达式,用于识别杂散甚至整数。
\d+[02468]+((\n)|(\s)|($)){1}
由于这是兼容的,因此我必须进行一些更改。我可以弄清楚如何用[0-9]替换\ d,但是用回车符替换\ n到\ x0D并用空格\ x0替换\ s似乎不是正确的方法。
我正在使用flex将程序编译为lex.yy.c,并调用“ cc lex.yy.c -lfl”将其编译为a.out可执行程序。这仅适用于Linux,不适用于OSX。
Here is a link to my solution.l program at the moment.
如果您对我有任何建议,我将非常感谢您的指导。无论如何,谢谢您的阅读。
答案 0 :(得分:1)
要匹配整数,您只需要:
[[:digit:]]+ { /* handle a number */ }
如果要匹配偶数整数,可以使用
[[:digit:]]*[02468] { /* handle an even number */ }
如果要同时匹配偶数和奇数整数,并且对每个奇偶校验执行不同的操作,则可以使用两个规则:
[[:digit:]]*[02468] { /* handle an even number */ }
[[:digit:]]*[13579] { /* handle an odd number */ }
或者您可以使用前两种模式进行操作,只要按正确的顺序排列它们即可:
[[:digit:]]*[02468] { /* handle an even number */ }
[[:digit:]]+ { /* handle any other number */ }
之所以可行,是因为(f)lex在两个模式相同的情况下总是使用第一个规则。
尝试将空格或换行符作为数字的一部分是没有意义的。它们不是数字的一部分,而flex的想法是将输入分解为有意义的部分(“令牌”)。可能是您不在乎输入的其他部分,但是,即使只是显式地忽略它们,您仍然需要识别它们。例如,要忽略任何不是数字的内容,可以添加以下规则:
[^[:digit:]] ; /* Do nothing*/
因为(f)lex不允许空操作,所以必须使用分号。
现在,您的意图很可能是不对单词中间的数字进行计数,例如F29
或23skidoo
。在这种情况下,您可能想添加另一个模式来识别那些可能包含数字的字符串。然后,您可能必须明确地识别空格,而不是将其与“非数字”混为一谈。令人惊讶的是,这很简单:
[[:digit:]]*[02468] { /* handle an even number */ }
[[:digit:]]+ { /* handle any other number */ }
[[:space:]]+ ; /* Ignore whitespace */
[^[:space:]]+ ; /* Ignore everything else */
最后一个模式可能需要一些解释,因为数字也是非空格字符的序列。但是出于同样的原因,我们不需要对奇数进行显式匹配。 “最大嚼数”规则表示(f)lex始终使用具有最长匹配的模式,并且如果为最长匹配而绑定了多个模式,则使用第一个。换句话说,如果由空格分隔的字符序列恰好是一个数字,则将选择一个数字规则而不是最后一个规则。另一方面,如果数字后面紧接着是垃圾,则会使用最后一个规则,因为它的匹配时间更长。