c - 正则表达式意外模式匹配
问题描述
我正在尝试使用 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] 它与')'不匹配。
解决方案
它匹配,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
,然后是整数+3
,而不是整数2
,并且3
中间有一个+
标记。因此,通常最好不要将符号作为整数标记的一部分,而是在解析器中允许前缀+
和运算符。-
推荐阅读
- javascript - Node js暂停而循环等待内部函数完全执行?
- javascript - 每次鼠标点击时交替一个变量值
- android - Android Gradle Build:重复条目:META-INF/app_release.kotlin_module
- python - 此代码仅查看我日历中的第一个事件
- java - 当我尝试@Autowired 给出这样的错误时,为什么会发生这种情况?
- postgresql - 如何用postgres中的子字符串替换字符串?
- c# - 如何进行动态授权?
- mysql - MySQL 1 个 4GB 表或 80 个小表
- c++ - 为什么即使不涉及虚函数,虚继承也需要 vtable?
- c++ - rapidjson修改文档创建对象和删除成员导致写入文档时断言