我正在尝试修改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”值?
答案 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)
}
~>
和<~
的常规助记符:您可以从开始到操作符或从操作符到结尾忽略,但不能忽略表达式的中间部分。