2015-04-06 79 views
0

我正在嘗試編寫一個簡單的解析器,以便能夠爲RDBMS生成DDL,但陷入了定義組合器的困境。Combinator定義給出了一個錯誤,無法理解爲什麼

import scala.util.parsing.combinator._ 
object DocumentParser extends RegexParsers { 
    override protected val whiteSpace = """(\s|//.*)+""".r //To include comments in what is regarded as white space, to be ignored 
    case class DocumentAttribute(attributeName : String, attributeType : String) 
    case class Document(documentName : String, documentAttributeList : List[DocumentAttribute]) 
    def document : Parser[Document]= "document" ~> documentName <~ "{" ~> attributeList <~ "}" ^^ {case n ~ l => Document(n, l)} //Here is where I get an error 
    def documentName : Parser[String] = """[a-zA-Z_][a-zA-Z0-9_]*""".r ^^ {_.toString} 
    def attributeList : Parser[List[DocumentAttribute]] = repsep(attribute, ",") 
    def attribute : Parser[DocumentAttribute] = attributeName ~ attributeType ^^ {case n ~ t => DocumentAttribute(n, t)} 
    def attributeName : Parser[String] = """[a-zA-Z_][a-zA-Z0-9_]*""".r ^^ {_.toString} 
    def attributeType : Parser[String] = """[a-zA-Z_][a-zA-Z0-9_]*""".r ^^ {_.toString} 
} 

看來我已經正確定義了它。有什麼明顯的我失蹤或什麼基本的關於combinators我不明白?謝謝!

回答

0

你必須使用下面的代碼document

def document : Parser[Document]= "document" ~> documentName ~ ("{" ~> attributeList <~ "}") ^^ {case n ~ l => Document(n, l)} 

注意~documentName後和周圍"{" ~> attributeList <~ "}"支架。否則,所有那些<~~>將丟棄除attributeList之外的所有內容。

基本上,沒有任何括號,結果是放棄最左邊的<~右側的所有東西,然後丟棄仍然剩下的最右邊~>左側的所有東西。例如:

def foo: Parser[String] = "a" ~> "b" ~> "c" ~ "d" <~ "e" ~> "f" <~ "g" 
         |<-discarded->|   | <- discarded -> | 

有了這個改變你的代碼的工作:

scala> DocumentParser.document(new CharSequenceReader(
    """ document foo {bar baz, // comment 
    | qaz wsx}""".stripMargin)) 
res4: DocumentParser.ParseResult[DocumentParser.Document] = [2.10] parsed: Document(foo,List(DocumentAttribute(bar,baz), DocumentAttribute(qaz,wsx))) 
+0

謝謝!這就解釋了爲什麼括號是必要的。現在一切正常。其實,我的代碼稍微涉及一些;我需要直接定義屬性或將其指向另一個文檔的屬性(基本上是外鍵)。但在發佈任何問題之前,我會先嚐試一下自己的事情。再次感謝! – user4562262 2015-04-07 03:39:16

相關問題