【问题标题】:| (or) operator for scala parsing combinators does not work| (或)scala 解析组合器的运算符不起作用
【发布时间】:2014-02-05 19:18:24
【问题描述】:

exactIntegerLiteralexactDoubleLiteral 一样成功解析,但是当它们在 ExectNumericLiteral 中组合在一起时,它们不适用于相同的输入 -1234.4。可能是什么原因?

def exactIntegerLiteral: Parser[IntegerLiteral] =
        "[-+]?\\d+(?!\\.)".r ^^ { parsed => IntegerLiteral(parsed.toLong) }

def exactDoubleLiteral: Parser[DoubleLiteral] =
        "[-+]?\\d+(\\.\\d+)?".r ^^ { parsed => DoubleLiteral(parsed.toDouble) }

def exactNumericLiteral: Parser[NumericLiteral] = 
        exactIntegerLiteral | exactDoubleLiteral

|||这个方法可以工作,但是我不明白这个行为。

【问题讨论】:

    标签: scala parsing integer double parser-combinators


    【解决方案1】:

    给定两个解析器pq,如果p 成功,则解析器p | q 短路。由于您正在定义 exactNumericLiteral 以便首先尝试 exactIntegerLiteral,因此它将始终匹配“-1234”,因此也无需尝试 exactDoubleLiteral

    exactIntegerLiteralexactDoubleLiteral的顺序切换为

    def exactNumericLiteral: Parser[NumericLiteral] = 
            exactDoubleLiteral | exactIntegerLiteral
    

    将首先尝试双重文字,因此做你想要的(或者我想你想要的,这个问题有点不清楚究竟什么不能按预期工作)。

    当使用p ||| q 而不是p | q 时,pq 都将被尝试,并选择匹配时间最长的结果。在您的示例中,当给定 -1234.4 时,这将是 exactDoubleLiteral

    编辑:根据下面的问题,应该注意的是,无论您拨打parseAll 还是parse,都很重要。在parseAll 的情况下,解析器应该匹配exactIntegerLiteral 不会为-1234.4 匹配的整个输入流。相反,调用 parse 将匹配到 . 并且不再消耗输入流。

    【讨论】:

    • 其实,exactIntegerLiteral 不匹配,会抛出异常,但应该如你所说。异常消息:失败:找到字符串匹配正则表达式\z' expected but 4'
    • 那是你调用 parseAll 的时候,因为你的解析器应该匹配整个输入,但 exactIntegerLiteral 不能这样做。试试parse,它会匹配到.,剩下的输入流仍然存在。
    猜你喜欢
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    相关资源
    最近更新 更多