Scala中parseAll结合备选解析器未按预期工作的原因
问题原因解析
这是Scala RegexParsers 组合子的短路匹配特性导致的差异:
当使用
orExpression | andExpression时,解析器会优先尝试左边的orExpression:
对于输入"1&2&3",orExpression里的rep1sep(identifier, "|")会先成功匹配第一个标识符"1"——因为rep1sep只要求至少匹配一个元素,哪怕后续的分隔符(|)不匹配,它也会返回“部分匹配成功”的结果。而parseAll要求必须完全消耗整个输入,此时左边的解析器虽然没匹配完所有内容,但它已经匹配了一部分输入,不是完全失败,所以组合子不会尝试右边的andExpression,直接判定整体解析失败,抛出异常。而依次尝试两个解析器时:
先调用parseAll(orExpression, "1&2&3")会因为有剩余输入(&2&3)失败,之后再调用parseAll(andExpression, "1&2&3"),此时andExpression里的rep1sep(identifier, "&")可以完整匹配所有输入,所以成功。
简单来说,| 组合子只有在左边解析器完全无法匹配任何输入时才会尝试右边,而不是左边匹配失败(比如没消耗完输入)就切换。
内容的提问来源于stack exchange,提问作者JoeMjr2
相关产品推荐
相关产品推荐

