0

我正在使用Trifecta库学习 Parser Combinators。我被介绍给Alternative typeclass 和它的 <|> 函数。

我的代码中有一个解析器函数,其定义是

fractionOrDecimal :: Parser DoubleOrRational
fractionOrDecimal =
        (Left <$> try parseDecimal)                  -- A
    <|> (Right <$> try parseFraction)                -- B
    <|> (fail  "Expected Fraction or Decimal.")      -- Err

它试图将输入解析为小数或分数,如果没有任何效果则失败。这种方法是否正确,或者我应该以不同的方式对失败(失败)进行编码,而不是作为 <|> 操作的一部分。

4

1 回答 1

4

失败是由没有成功的解析器编码的。Trifecta 将为您跟踪预期的令牌,但您必须告诉它使用<?>. 所以你会做

fractionOrDecimal :: Parser DoubleOrRational
fractionOrDecimal =
        (Left  <$> try parseDecimal  <?> "Decimal")
    <|> (Right <$> try parseFraction <?> "Fractional")

我们现在得到这样的错误:

>>> parseTest fractionalOrDecimal "neither fractional nor decimal"
error: expected: Decimal, Fractional
neither fractional nor decimal<EOF> 
^                       
于 2019-01-27T16:17:54.710 回答