2016-09-19 45 views
0

我使用scala.util.parsing.combinator寫解析器和語法的列表。 我輸入":za >= 1 alok && :ft == 9"Scala的解析器組合:提取型

case class Expression(op1:Operand,operator:Operator,op2:Operand) 

def word: Parser[String] = """[a-z\\\s]+""".r ^^ { _.toString } 

def colonWord:Parser[Operand]=":"~> word ^^{case variable => Operand(variable)} 

def constant:Parser[Operand]="""^[a-zA-Z0-9\\\s-]*""".r ^^ {case constant => Operand(constant)} 

def expression:Parser[Expression] = colonWord ~ operator ~ constant ^^{ case op1~operator~op2 => Expression(op1, operator, op2)} 

def expressions = expression ~ opt(" && " ~> expression)* 

但是當我分析後的樣本串,預計不會結果。 &&之後的第二個表達式未被解析。請注意,可以使用&&加入多個表達式。

在i執行:

val expr= ":za >= 1 alok && :ft == 9" 
    parse(expressions, expr) match { 
     case Success(matched, _) => println(matched) 
     case ..} 

輸出是:

List((Expression(za ,>= ,1 alok)~None)) 

我沒有看到正在分析的第二個表達式。任何人都可以幫助我在這裏錯過了什麼?

編輯 -----------------------------------

的要求是得到List[Expression]。 當我說,incorporting在答案中提到的變化:

def expressions = expression ~ ("&&" ~> expression)* 

表達式的返回類型沒有列出[表達。對於如: 如果我再寫高清:

case class Condition(exprs: List[Expression], st:Statement) 
def condition = expressions ~","~statement ^^{ 
    case exprs~commaa~statement => Condition(exprs,statement) //This is giving error. 

的錯誤是: 類型不匹配;發現:〜[Expression,Expression]]必需:表達式。

讓我怎麼轉換[表達式,表達式]列出[表達式]

感謝

+0

在你的輸出'名單((表達式(ZA,> =,1個阿洛克)〜無))'。試着在'1 alok'之後注意到額外的空間。而額外的空間是罪魁禍首,因爲你的下一個'expressions'解析器需要兩個'expression's到一個' && ' –

+0

這就是爲什麼它是一個很好的做法,''作爲第一類成員分隔你的語法。永遠不要貶低空間。 –

+0

謝謝。是的,這是問題所在。我試圖從 && 去掉空格。它在這種情況下工作。但我給另一個表達式=> 「:ZA> = 1 &&:英尺== 9 &&:WQ == 12」,在這種情況下,它把2的表達,而不是3。 我得到的輸出是List((Expression(za,> =,1)〜Some(Expression(ft,==,9)))) – Alok

回答

1

所需的修正值是:

expression ~ opt("&&" ~> expression)* 

刪除存儲空間,在&&,它應該工作。這是因爲您已經覆蓋了您的constant解析器中的空間。

編輯: 基於編輯的問題,這是你想要的東西:

def expressions = expression ~ (("&&" ~> expression)*) ^^{ 
    case x ~ y => x :: y 
    } 

現在的expressions返回類型爲List[Expression]。你condition現在編譯

+0

謝謝。是的,這是問題所在。我試圖從 && 去掉空格。它在這種情況下工作。但我給另一個表達式=> 「:ZA> = 1 &&:英尺== 9 &&:WQ == 12」,在這種情況下,它把2的表達,而不是3。我得到的輸出是List((Expression(za,> =,1)〜Some(Expression(ft,==,9)))) – Alok

+0

我相信這個問題也是用def表達式=表達式〜opt(「&&」 〜>表達式)*。我期待這回我列表[表達式]。但是它會返回[Expression,Option [Expression]] – Alok

+0

,因爲你在'opt(「&&」〜> expression)''中有'opt'''。現在,由於您使用'*'表示'0或更多',所以您不需要'opt'。 –

相關問題