正则表达式初学者;编写与Lex / Flex兼容的正则表达式(专门用于识别偶数)

时间:2018-09-20 23:26:19

标签: regex compilation bison flex-lexer lex

因此,我希望编写一个简单的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.

如果您对我有任何建议,我将非常感谢您的指导。无论如何,谢谢您的阅读。

1 个答案:

答案 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不允许空操作,所以必须使用分号。

现在,您的意图很可能是不对单词中间的数字进行计数,例如F2923skidoo。在这种情况下,您可能想添加另一个模式来识别那些可能包含数字的字符串。然后,您可能必须明确地识别空格,而不是将其与“非数字”混为一谈。令人惊讶的是,这很简单:

[[:digit:]]*[02468]        { /* handle an even number */ }
[[:digit:]]+               { /* handle any other number */ }
[[:space:]]+               ; /* Ignore whitespace */
[^[:space:]]+               ; /* Ignore everything else */

最后一个模式可能需要一些解释,因为数字也是非空格字符的序列。但是出于同样的原因,我们不需要对奇数进行显式匹配。 “最大嚼数”规则表示(f)lex始终使用具有最长匹配的模式,并且如果为最长匹配而绑定了多个模式,则使用第一个。换句话说,如果由空格分隔的字符序列恰好是一个数字,则将选择一个数字规则而不是最后一个规则。另一方面,如果数字后面紧接着是垃圾,则会使用最后一个规则,因为它的匹配时间更长。