我想爲下面的命令定義一個語法。斯卡拉解析器令牌分隔符問題
action = todo
message = link todo to database
properties = [deadline: next tuesday, context: app.model]
當運行如下所定義的語法這個輸入時,收到以下錯誤消息::
[1.27] parsed: Command(todo,link todo to database,List())
[1.36] failure: string matching regex `\z' expected but `:' found
todo link todo to database deadline: next tuesday context: app.model
^
至於
object ParserWorkshop {
def main(args: Array[String]) = {
ChoiceParser("todo link todo to database")
ChoiceParser("todo link todo to database deadline: next tuesday context: app.model")
}
}
第二命令作爲應該標記化我可以看到它失敗了,因爲用於匹配消息的單詞的模式與屬性鍵:值對的模式幾乎相同,所以解析器無法知道消息的結束位置並開始物業。我可以堅持起始令牌被用來爲每個屬性像這樣解決這個問題:
todo link todo to database :deadline: next tuesday :context: app.model
但我寧願保留命令接近自然語言越好。 我有兩個問題:
錯誤信息實際上是什麼意思? 而我將如何修改現有語法以適用於給定的輸入字符串?
import scala.util.parsing.combinator._
case class Command(action: String, message: String, properties: List[Property])
case class Property(name: String, value: String)
object ChoiceParser extends JavaTokenParsers {
def apply(input: String) = println(parseAll(command, input))
def command = action~message~properties ^^ {case a~m~p => new Command(a, m, p)}
def action = ident
def message = """[\w\d\s\.]+""".r
def properties = rep(property)
def property = propertyName~":"~propertyValue ^^ {
case n~":"~v => new Property(n, v)
}
def propertyName: Parser[String] = ident
def propertyValue: Parser[String] = """[\w\d\s\.]+""".r
}
我認爲你應該改變你的語法是這樣的: todo「鏈接待辦事項數據庫」:截止日期:「下週二」:上下文:「應用程序。模型「 – ziggystar 2009-11-26 13:28:02
這是一個我想避免的解決方案,因爲我想盡可能使Todo語法儘可能地接近自然語言。 – 2009-11-27 10:14:31