我是flex的新手,我想使用flex设计扫描仪。
在这一步,我想使正则表达式与id匹配,但这里有一些条件:
下划线可以存在于id
您可以随时使用_,但如果您正在使用它们 因此,它最多可以是2个下划线,例如:
a_b_c»»»»
a ___ b»»»»false
123abv»»»»false
整数不能位于id的开头
下划线不能存在于id
我为此写的正则表达式是:
(\b(_{0,2}[A-Za-z][0-9A-Za-z]*(_{0,2}[0-9A-Za-z]+)*)\b)
但现在我有两个问题:
正则表达式是真的吗?我已经在rubular.com进行了测试,我认为这是真的,但我不确定?
另一个重要的问题是,当我在我的flex文件中写这个时,很遗憾没有识别出id。但我不知道为什么它不被认可
有人可以帮助我吗?
答案 0 :(得分:1)
这里的问题是你的ID
正则表达式。您正在使用\b
来匹配单词边界,但Flex的正则表达式没有内置支持来匹配单词边界。除此之外,你的正则表达式是合理的。我能够使用您的这个修改版本来使用您的代码:_{0,2}[A-Za-z][0-9A-Za-z]*(_{0,2}[0-9A-Za-z]+)*
。 (我刚刚摆脱了\b
,以及一些困扰我的括号。)
不幸的是,这会导致轻微的问题。假设你是lexing并遇到类似12_345
的东西。 Flex会阅读12
,假设它找到IC
,然后阅读_
。找不到匹配项,它会将其打印到stdout,然后将345
视为另一个IC
。
为了避免这个问题(由Flex缺少单词边界引起),你可以做以下两件事之一:
_
时停止Flex。[_0-9A-Za-z]+
)组合的规则。如果匹配,则给出错误。这将导致Flex在上面的示例中将整个令牌12_345
作为错误返回。 另一个问题: ID
正则表达式仍然不会匹配任何带有下划线的内容。这意味着您当前的正则表达式并不完美,您需要对其进行一些调整,但现在您知道不使用\b
符号。 Here是Flex的正则表达式语法的参考,因此您可以找到其他要使用/避免的内容。
答案 1 :(得分:0)
我认为您的要求是:
标识符只能使用字母数字字符和_
标识符不能以数字开头
标识符不能以 _
标识符不能包含两个以上连续 _
(当我第一次阅读你的问题时,我认为最后一个要求是标识符不能包含两个以上 _ ,但是看看提议的正则表达式,我认为上面的版本更准确。)
基于以上所述,您应该能够使用以下两种Flex模式:
([[:alpha:]]|__?[[:alnum:]])(_?_?[[:alnum:]])* { /* Handle an identifier */ }
[[:alpha:]_][[:alnum:]_]* { /* Error */ }
打破这一点:
([[:alpha:]]|__?[[:alnum:]])
匹配字母字符或一个或两个 _ 后跟一个字母数字字符。
(_?_?[[:alnum:]])*
匹配 和字母数字字符串,最多两个 在字母数字字符之前。
第二种模式将匹配任何以字母字符开头的内容或 后跟任意数量的字母数字或 。这将匹配所有有效标识符以及包含太多连续 或以 结尾的序列。如果两个模式匹配(即有效标识符),则第一个模式将获胜,因此将被正确识别。第二种模式将使用整个错误标识符,从而可以更容易地进行错误恢复。
OP中的模式不起作用,因为flex将\b
视为退格符(如C中所示)。 Flex没有实现单词边界断言,但在词法分析器中你几乎不需要这些;如有必要,可以使用上面的模式。