flex中的正则表达式有错误
Regular expressions in flex has error
我是 flex 的新手,我想使用 flex 设计一个扫描仪。
在这一步,我想做正则表达式来匹配id,但是有一些条件:
id中可以存在下划线
您可以随时使用 _,但如果您确实使用它们
因此它最多可以是 2 个下划线,例如:
a_b_c »»»» 真
a___b »»»» 错误
123abv »»»» 假
整数不能在 id 的开头
id 末尾不能有下划线
我为此编写的正则表达式是:
(\b(_{0,2}[A-Za-z][0-9A-Za-z]*(_{0,2}[0-9A-Za-z]+)*)\b)
但现在我有两个问题:
正则表达式是否正确?我已经在 rubular.com 中测试过了,我认为这是真的,但我不确定?
另一个重要的问题是,当我在我的 flex 文件中写这个时,不幸的是没有识别出 id。但是不明白为什么不被识别
谁能帮帮我?
这里的问题是您的 ID
正则表达式。您正在使用 \b
来匹配单词边界,但 Flex 的正则表达式没有对匹配单词边界的内置支持。除此之外,您的正则表达式是正确的。我能够使用你的这个修改版本让你的代码工作:_{0,2}[A-Za-z][0-9A-Za-z]*(_{0,2}[0-9A-Za-z]+)*
。 (我刚刚去掉了 \b
和一些困扰我的括号)。
不幸的是,这会导致一个小问题。假设您正在对诸如 12_345
之类的内容进行词法分析和 运行。 Flex 将读取 12
,假设它找到了一个 IC
,然后读取 _
。找不到匹配项,它会将其打印到标准输出,然后将 345
读取为另一个 IC
.
为了避免这个问题(由 Flex 缺少单词边界引起),您可以执行以下两种操作之一:
- 在末尾创建一个匹配任何字符(空格除外)的规则,并使其给出错误。在上面的示例中,当它到达
_
时,这将停止 Flex。
- 在末尾创建一个匹配字母、数字和下划线的任意组合的规则 (
[_0-9A-Za-z]+
)。如果匹配,则报错。这将导致 Flex return 整个标记 12_345
作为上例中的错误。
另一个问题: ID
正则表达式仍然无法匹配任何末尾带有下划线的内容。这意味着您当前的正则表达式并不完美,您需要对其进行一些调整,但现在您知道不要使用 \b
符号。 Here 是对 Flex 正则表达式语法的参考,因此您可以找到 use/avoid.
的其他内容
我认为你的要求是:
标识符只能使用字母数字字符和_
标识符不能以数字开头
标识符不能以 _
结尾
标识符不能超过两个连续_
(当我第一次读到你的问题时,我认为最后的要求是标识符不能包含两个以上的 _,但是看看提议的正则表达式,我认为上面的版本更准确。)
基于以上内容,您应该可以使用以下两种 Flex 模式:
([[:alpha:]]|__?[[:alnum:]])(_?_?[[:alnum:]])* { /* Handle an identifier */ }
[[:alpha:]_][[:alnum:]_]* { /* Error */ }
分解:
([[:alpha:]]|__?[[:alnum:]])
匹配一个字母字符或一个或两个 _ 后跟一个字母数字字符。
(_?_?[[:alnum:]])*
匹配字符串和字母数字字符,最多两个 在字母数字字符之前。
第二个模式将匹配以字母字符或 后跟任意数量的字母数字或 开头的任何内容。这将匹配所有有效标识符以及包含太多连续 或以 结尾的序列.如果两个模式都匹配(即有效标识符),则第一个将获胜,因此将被正确识别。第二种模式将消耗整个错误标识符,以便更容易地恢复错误。
OP 中的模式不起作用,因为 flex 将 \b
视为退格字符(如在 C 中)。 Flex 不实现词边界断言,但在词法分析器中你几乎不需要这些;如有必要,可以使用上面的模式。
我是 flex 的新手,我想使用 flex 设计一个扫描仪。
在这一步,我想做正则表达式来匹配id,但是有一些条件:
id中可以存在下划线
您可以随时使用 _,但如果您确实使用它们 因此它最多可以是 2 个下划线,例如:
a_b_c »»»» 真
a___b »»»» 错误
123abv »»»» 假
整数不能在 id 的开头
id 末尾不能有下划线
我为此编写的正则表达式是:
(\b(_{0,2}[A-Za-z][0-9A-Za-z]*(_{0,2}[0-9A-Za-z]+)*)\b)
但现在我有两个问题:
正则表达式是否正确?我已经在 rubular.com 中测试过了,我认为这是真的,但我不确定?
另一个重要的问题是,当我在我的 flex 文件中写这个时,不幸的是没有识别出 id。但是不明白为什么不被识别
谁能帮帮我?
这里的问题是您的 ID
正则表达式。您正在使用 \b
来匹配单词边界,但 Flex 的正则表达式没有对匹配单词边界的内置支持。除此之外,您的正则表达式是正确的。我能够使用你的这个修改版本让你的代码工作:_{0,2}[A-Za-z][0-9A-Za-z]*(_{0,2}[0-9A-Za-z]+)*
。 (我刚刚去掉了 \b
和一些困扰我的括号)。
不幸的是,这会导致一个小问题。假设您正在对诸如 12_345
之类的内容进行词法分析和 运行。 Flex 将读取 12
,假设它找到了一个 IC
,然后读取 _
。找不到匹配项,它会将其打印到标准输出,然后将 345
读取为另一个 IC
.
为了避免这个问题(由 Flex 缺少单词边界引起),您可以执行以下两种操作之一:
- 在末尾创建一个匹配任何字符(空格除外)的规则,并使其给出错误。在上面的示例中,当它到达
_
时,这将停止 Flex。 - 在末尾创建一个匹配字母、数字和下划线的任意组合的规则 (
[_0-9A-Za-z]+
)。如果匹配,则报错。这将导致 Flex return 整个标记12_345
作为上例中的错误。
另一个问题: ID
正则表达式仍然无法匹配任何末尾带有下划线的内容。这意味着您当前的正则表达式并不完美,您需要对其进行一些调整,但现在您知道不要使用 \b
符号。 Here 是对 Flex 正则表达式语法的参考,因此您可以找到 use/avoid.
我认为你的要求是:
标识符只能使用字母数字字符和_
标识符不能以数字开头
标识符不能以 _
结尾
标识符不能超过两个连续_
(当我第一次读到你的问题时,我认为最后的要求是标识符不能包含两个以上的 _,但是看看提议的正则表达式,我认为上面的版本更准确。)
基于以上内容,您应该可以使用以下两种 Flex 模式:
([[:alpha:]]|__?[[:alnum:]])(_?_?[[:alnum:]])* { /* Handle an identifier */ }
[[:alpha:]_][[:alnum:]_]* { /* Error */ }
分解:
([[:alpha:]]|__?[[:alnum:]])
匹配一个字母字符或一个或两个 _ 后跟一个字母数字字符。(_?_?[[:alnum:]])*
匹配字符串和字母数字字符,最多两个 在字母数字字符之前。
第二个模式将匹配以字母字符或 后跟任意数量的字母数字或 开头的任何内容。这将匹配所有有效标识符以及包含太多连续 或以 结尾的序列.如果两个模式都匹配(即有效标识符),则第一个将获胜,因此将被正确识别。第二种模式将消耗整个错误标识符,以便更容易地恢复错误。
OP 中的模式不起作用,因为 flex 将 \b
视为退格字符(如在 C 中)。 Flex 不实现词边界断言,但在词法分析器中你几乎不需要这些;如有必要,可以使用上面的模式。