【问题标题】:Matching Lua's "Long bracket" string syntax匹配 Lua 的“长括号”字符串语法
【发布时间】:2009-06-21 11:37:55
【问题描述】:

我正在为 Lua 编写 jFlex 词法分析器,但在设计正则表达式以匹配语言规范的特定部分时遇到问题:

文字字符串也可以使用长括号括起来的长格式来定义。我们将第 n 级的左长括号定义为一个左方括号,后跟 n 个等号,然后是另一个左方括号。因此,级别 0 的左长括号写为 [[,级别 1 的左长括号写为 [=[,依此类推。闭合长括号的定义类似;例如,第 4 级的右长括号写为]====]。长字符串以任何级别的左长括号开始,并在同一级别的第一个右长括号结束。这种括号形式的文字可以运行多行,不解释任何转义序列,并忽略任何其他级别的长括号。除了适当级别的右括号之外,它们可以包含任何内容。

简而言之,我正在尝试设计一个正则表达式,它将匹配一个开始的长括号、中间的字符串内容和结束的长括号。只有当开始的长括号和结束的长括号具有相同数量的等号(可以是零或更多)时才会发生匹配。

【问题讨论】:

    标签: regex lua lexer jflex


    【解决方案1】:

    好吧,我担心使用正则表达式进行标记不足以完成这项任务。正则表达式还不够强大。

    没有办法在 jFlex 中使用普通的正则表达式来比较 '=' 标记的数量。 Perl 对此有一些技巧(如上面建议的 \1 ),但我们不是在谈论编程 Perl,而是在谈论 jFlex 词法分析器。

    解决方案是使用 \[=*\[ 作为左括号标记,使用 \]=*\] 作为右括号标记,然后在上面的层(解析器)中比较它们的长度是否匹配。

    不管怎样,你可以看看 llex.c 中 lua 源代码中的 read_long_string() ,看看他们是如何在完全不使用正则表达式的情况下做到这一点的。

    【讨论】:

    • 你也可以使用词法状态:匹配左括号为\[=*\[ ,存储它的长度,进入一个新的状态,匹配内容和任何结束\]=*\]。如果结束匹配的长度正确,则返回令牌,如果长度错误,则将其添加到内容中。
    • \1 不是 Perl hack,它是一个反向引用,您可以在许多正则表达式实现中找到它(例如 sedgrep 有它们)。问题是 jFlex 不支持反向引用。
    【解决方案2】:
    \[(=*)\[.*?\]\1\]
    

    \1 捕获第一个 ()。

    【讨论】:

    • 这不是一个有效的 JFlex 正则表达式,或者至少它并不意味着 JFlex 中的答案。 \1 在 JFlex 中没有特殊含义,只是匹配为字符 1
    【解决方案3】:
    \[(=*)\[.*?\]\1\]
    

    【讨论】:

    • 晚了 30 秒我的朋友 :)
    • 与 SpliFF 的回答相差一个字符;我的回答也接受带有零等号的长括号。
    • 现在他修好了。 (顺便说一句:P 25 秒)
    • 是的,虽然我在重新检查问题时意识到我的错误,并且在您发布时正在修复它。反正我赢了:P
    猜你喜欢
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多