【问题标题】:how to skip all single- and multi-line comments in a Parse::RecDescent parser如何跳过 Parse::RecDescent 解析器中的所有单行和多行注释
【发布时间】:2012-07-03 19:52:44
【问题描述】:

在 Parse::RecDescent 中,我如何有效地忽略 C++/Java 样式的 cmets?这包括单行('//' 直到行尾)和多行(/这里的所有内容/)。

【问题讨论】:

    标签: perl parsing parse-recdescent


    【解决方案1】:

    <skip> 定义解析器认为什么是空白。

    parse: <skip: qr{(?xs:
              (?: \s+                       # Whitespace
              |   /[*] (?:(?![*]/).)* [*]/  # Inline comment
              |   // [^\n]* \n?             # End of line comment
              )
           )*}>
           main_rule
           /\Z/
           { $item[2] }
    

    与 Nate Glenn 的解决方案不同,我的

    • 不设置影响所有解析器的全局变量。
    • 不使用不必要的捕获。
    • 不使用非贪婪修饰符。 (他使用 non-greedy 修饰符来确保某些字符在某些位置不匹配,但 non-greedy 修饰符并不能保证这一点。)

    注意:(?:(?!STRING).)* 对应于 (?:STRING),就像 [^CHAR] 对应于 CHAR。

    【讨论】:

    • 谢谢!我有答案,但希望有所改进。
    • 哦,我没有意识到你在回答你自己的问题!哈哈!老实说,答案非常好。 1) 如果要使用 $Parse::RecDescent::skip,只需使用local 将更改限制在编译语法时。 2) 考虑到 PRD 有多慢,速度损失可以忽略不计。 3)我基本上是安全的。根据 PRD 使用正则表达式的方式,这可能是也可能不是问题。
    【解决方案2】:

    您必须设置$Parse::RecDescent::skip 的值。默认情况下,Parse::RecDescent 会跳过所有空白。如果将此变量设置为匹配空格和 cmets 的正则表达式,则可以跳过它们。使用这个:

    $Parse::RecDescent::skip = 
        qr{
            (
                \s+                 #whitespace
                    |               #or
                /[*] .*? [*]/ \s*   #a multiline comment
                    |               #or
                //.*?$               #a single line comment
            )*                      #zero or more
    
        }mxs;
    # m allows '$' to match a newline, x allows regex comments/whitespace, 
    # s allows '.' to match newlines.
    

    【讨论】:

    • 我认为这仍然存在一个问题,即看起来像 C 风格的注释被嵌入在单行注释中:rt.cpan.org/Public/Bug/Display.html?id=77702
    • @DavidO,不,这里有一个隐含的\G。
    • @ikegami,不错。这样就可以了。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-25
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多