正则表达式意外模式匹配

Regular expression unexpected pattern matching

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

  1. Must start with any digit in range 1-9 and followed by any number of digits in range 0-9. (ex. Correct: 1,12,11024 | Incorrect: 012)

  2. Can be signed (ex. +2,-5)

  3. The number 0 must not be followed by any digit (0-9) and must not signed. (ex. Correct: 0 | Incorrect: 012,+0,-0)

这是我创建的用于执行匹配的正则表达式: [^+-]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] 它与 ')' 不匹配。

匹配10(,因为1匹配[^+-]0匹配0(匹配[^0-9]

The reason I used the above expression, instead of the much simpler one, (0|[+-]?[1-9][0-9]*) is due to inability of the parser to recognise incorrect expressions such as 012.

怎么会这样?使用上面的正则表达式,012 将被识别为两个标记:012。这不会导致您的解析器出错吗?

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

除了在操作中检查,您还可以保留正则表达式,然后为带前导零的整数添加另一个正则表达式(如 0[0-9]+ { warn("Leading zero"); return INT; }),但我会在操作中进行检查因为这是一个简单的检查,它使正则表达式简短。

PS:如果将 -+ 作为整数标记的一部分,则 2+3 之类的东西将被视为整数 2,后跟整数 +3,而不是整数 23,中间有一个 + 标记。因此,通常最好不要让符号成为整数标记的一部分,而是在解析器中允许使用前缀 +- 运算符。