我一直試圖讓我的頭在斯卡拉的分析器組合器。看起來它們非常強大,但我似乎發現的唯一教程示例是使用數學表達式和幾乎沒有適當的真實世界解析示例,需要解析DSL並將其映射到不同的實體等。斯卡拉分析器組合器將字符列表轉換爲字符串
爲了在這個例子中,可以說我有這個BNF,我有這個實體名爲Model,它由一個字符串組成,如下所示:[model [name <name> ]]
。這是一個更大的BNF的簡單例子,現實中有更多的實體。
所以我定義我自己的類Model
更是把name
的構造函數,然後定義我自己ModelParser
對象延伸JavaTokenParsers
。然後,我定義了下面的解析器,遵循BNF(我知道有些可能有一個更簡單的正則表達式匹配器,但我更願意遵循BNF準確地出於其他原因)。
def model : Parser[Model] = "[model" ~> "[name" ~> name <~ "]]" ^^ (Model(_))
def name : Parser[String] = (letter ~ (anyChar*)) ^^ {case text => text.toString())
def anyChar = letter | digit | "_".r | "-".r
def letter = """[a-zA-Z]""".r
def digit = """\d""".r
的Model
的toString
看起來是這樣的:
override def toString : String = "[model " + name + "]"
當我嘗試用繩子運行它像[model [name helloWorld]]
我得到這個 [model [h~List(e, l, l, o, W, o, r, l, d)]]
什麼,而不是我期待[model helloWorld]
如何我能讓這些個人角色重新加入他們最初的字符串嗎?
我也混淆了個別解析器和.r
的使用。有時我看到他們只有以下解析器的例子(解析「hello」):
def hello = "hello"
這不就是一個字符串嗎?它如何突然成爲可與其他解析器結合使用的解析器? .r
究竟在做什麼?我已經閱讀了至少3個教程,但仍然完全失去了實際發生的事情。
http://www.artima.com/pins1ed/combinator-parsing.html#31.7 –
非常感謝您的澄清,尤其是'.r'混淆以及String文字與'Parser [String ]'。 'name'分析器現在工作正常! – jbx
@Travis我注意到,出於某種原因,即使'[名稱hello World]]被接受並在解析爲helloWorld後再現。我如何強制它不接受名稱部分,如果它有空格? 〜似乎允許它很好。我不想完全禁用解析器,因爲它非常有用。 – jbx