|(或)scala解析组合符的运算符不起作用

|(或)scala解析组合符的运算符不起作用,scala,parsing,integer,double,parser-combinators,Scala,Parsing,Integer,Double,Parser Combinators,exactIntegerLiteral和exactDoubleLiteral都能成功解析,但当它们在ExectNumericLiteral中组合在一起时,不能使用相同的输入-1234.4。原因可能是什么 def exactIntegerLiteral: Parser[IntegerLiteral] = "[-+]?\\d+(?!\\.)".r ^^ { parsed => IntegerLiteral(parsed.toLong) } def exactDoubleLit

exactIntegerLiteral和exactDoubleLiteral都能成功解析,但当它们在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
|||这个方法完成了工作,但是我不理解它的行为。

给定两个解析器p和q,如果p成功,解析器p | q就会短路。由于定义exactNumericLiteral时首先尝试exactIntegerLiteral,因此它将始终在-1234上匹配,因此也不需要尝试exactDoubleLiteral

将exactIntegerLiteral和exactDoubleLiteral的顺序切换为

我会先尝试双重文字,然后做你想做的或者我认为你想做的,问题是有点不清楚到底是什么不符合预期

当使用p | | | q代替p | q时,将同时尝试p和q,并选择匹配时间最长的结果。在您的示例中,如果给定-1234.4,则为exactDoubleLiteral


编辑:根据下面的问题,应该注意的是,调用parseAll还是parse很重要。在parseAll的情况下,解析器应该匹配整个输入流,而exactIntegerLiteral对-1234.4不起作用。相反,调用parse将匹配到。并且不再消耗输入流。

实际上,exactIntegerLiteral不匹配,并抛出异常,但它应该如您所说的那样。异常消息:失败:字符串匹配regex\z'expected but 4'found这是您调用parseAll的时候,因为此时您的解析器应该匹配整个输入,但exactIntegerLiteral无法做到这一点。改为尝试解析,它将匹配,直到。和输入流的其余部分保留。
def exactNumericLiteral: Parser[NumericLiteral] = 
        exactDoubleLiteral | exactIntegerLiteral