我正在尝试使用C-Bison和Flex创建语法解析器。在Flex中,我有一个正则表达式,它根据以下内容匹配整数:
必须以1-9范围内的任何数字开头,然后以0-9范围内的任何数字开头。 (例如,正确:1,12,11024 |错误:012)
可以签名(例如+ 2,-5)
数字0后面不能有任何数字(0-9),也不能签名。 (例如正确:0 |错误: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],则它与')'不匹配。
答案 0 :(得分:3)
它与10(
相匹配,因为1
与[^+-]
相匹配,0
与0
相匹配,而(
与[^0-9]
相匹配。
之所以使用上面的表达式而不是简单的表达式(0 | [+-]?[1-9] [0-9] *)是因为解析器无法识别诸如如012。
如何?使用上述正则表达式,012
将被识别为两个令牌:0
和12
。这不会在您的解析器中引起错误吗?
诚然,这不会产生非常好的错误消息,因此更好的方法可能是仅使用[0-9]+
作为正则表达式,然后使用该操作检查前导零。这样,012
将是单个标记,而词法分析器可能会产生有关前导零的错误或警告(我在这里假设您实际上是要禁止前导零-请勿将它们用于八进制文字)。>
您也可以保留正则表达式,然后为前导零的整数添加另一个(例如0[0-9]+ { warn("Leading zero"); return INT; }
),而不是执行该操作,但是我将继续执行该操作,因为它是轻松检查,使正则表达式简短明了。
PS:如果将-
和+
用作整数令牌的一部分,则类似2+3
的事物将被视为整数2
,后跟整数{{ 1}},而不是整数+3
和2
之间带有3
标记的整数。因此,通常最好不要将符号作为整数令牌的一部分,而应在解析器中使用前缀+
和+
运算符。