正则表达式意外的模式匹配

时间:2019-06-02 12:54:18

标签: c regex bison flex-lexer

我正在尝试使用C-Bison和Flex创建语法解析器。在Flex中,我有一个正则表达式,它根据以下内容匹配整数:

  
      
  1. 必须以1-9范围内的任何数字开头,然后以0-9范围内的任何数字开头。 (例如,正确:1,12,11024 |错误:012)

  2.   
  3. 可以签名(例如+ 2,-5)

  4.   
  5. 数字0后面不能有任何数字(0-9),也不能签名。 (例如正确:0 |错误:012,+ 0,-0)

  6.   

这是我为执行匹配而创建的正则表达式: [^ +-] 0 [^ 0-9] | [+-]?[1-9] [0-9] *

这是我正在测试的表达式: (1 +1 + 10)

比赛:

  

1
  1
  10)

这是我的问题,为什么它与'10)匹配?

之所以使用上面的表达式,而不是简单得多的表达式, (0 | [+-]?[1-9] [0-9] *)是由于解析器无法识别不正确的表达式,例如012。

似乎仅在数字'0'之前的')'之前出现问题。但是,如果“ 0”前面有两个或多个数字(例如100),则“)”不匹配。

我知道,如果我从正则表达式中删除[^ 0-9],则它与')'不匹配。

1 个答案:

答案 0 :(得分:3)

它与10(相匹配,因为1[^+-]相匹配,00相匹配,而([^0-9]相匹配。

  

之所以使用上面的表达式而不是简单的表达式(0 | [+-]?[1-9] [0-9] *)是因为解析器无法识别诸如如012。

如何?使用上述正则表达式,012将被识别为两个令牌:012。这不会在您的解析器中引起错误吗?

诚然,这不会产生非常好的错误消息,因此更好的方法可能是仅使用[0-9]+作为正则表达式,然后使用该操作检查前导零。这样,012将是单个标记,而词法分析器可能会产生有关前导零的错误或警告(我在这里假设您实际上是要禁止前导零-请勿将它们用于八进制文字)。

您也可以保留正则表达式,然后为前导零的整数添加另一个(例如0[0-9]+ { warn("Leading zero"); return INT; }),而不是执行该操作,但是我将继续执行该操作,因为它是轻松检查,使正则表达式简短明了。

PS:如果将-+用作整数令牌的一部分,则类似2+3的事物将被视为整数2,后跟整数{{ 1}},而不是整数+32之间带有3标记的整数。因此,通常最好不要将符号作为整数令牌的一部分,而应在解析器中使用前缀++运算符。