具有可选值的解析器组合器^^

时间:2014-01-09 17:20:21

标签: scala parsing

我正在尝试修改DSLs in Action中的示例。

最初,此代码用于解析items后跟account

  lazy val order: Parser[Order] = 
    items ~ account_spec ^^ {
      case i ~ a => Order(i, a)
    }

可以使用上面的解析器解析以下文本:

(100 IBM shares to buy at max 45) for account "A1234
------------- item -------------  ------ account ----

但是,我想在解析器中添加FOO和可选的not值:

  lazy val order: Parser[Order] = 
    items <~ "FOO" ~> ("not"?) ~ account_spec ^^ {
      case i ~ n ~ a => println(n); Order(i, a)
    }

FOO必须遵循account,并且可选择not

示例:

(100 IBM shares to buy at max 45) FOO not for account "A1234
---------- item ------------------ --- --- ------ account ----

但是,上面的代码给出了这个编译时错误:

[WARNING] ....\OrderDsl.scala:19: error: constructor cannot be instantiated to 
expected type;
[WARNING]  found   : ch8.trading.semantic.dsl.OrderDsl.~[a,b]
[WARNING]  required: ch8.trading.semantic.dsl.AST.Items
[WARNING]       case i ~ n ~ a => println(n); Order(i, a)
[WARNING]                  ^

如何修改case语句以支持解析可选“not”值?

1 个答案:

答案 0 :(得分:2)

a <~ "FOO" ~> b表示“忽略解析器"FOO"b的结果,并返回a”的结果。

重写你的方法:

lazy val order: Parser[Order] = 
  items ~ opt("FOO") ~ opt("not") ~ account_spec ^^ {
    case i ~ _ ~ n ~ a => println(n); Order(i, a)
  }

~><~的常规助记符:您可以从开始到操作符或从操作符到结尾忽略,但不能忽略表达式的中间部分。