2012-04-19 39 views
1

我已經爲大學裏的一項任務設置了作業任務,以便使用Scala組合器來分析命題邏輯,而且我正在處理這個問題時正要將我的頭髮撕掉幾個小時,甚至不能超過第一階段。使用scala組合器來分析命題邏輯

最初的部分是構建一個識別器,該識別器構建符合給定的EBNF格式的識別類型(類型已單獨提供)。 ([]意味着0或一個,+意味着一個或更多個和*意味着零個或多個)

prop ::= equiv 

equiv ::= impl biArrow impl 
            p <=> q becomes Equivalent (P, Q) 
            p <+> q becomes Not (Equivalent (P, Q)) 
impl ::= disj [impls] 
impls ::= (rightArrow disj)+ 
            p => q becomes Implies (P, Q) 
     | (leftArrow disj)+ 
            p => q becomes Implies (Q, P) 
disj ::= conj (disjOp conj)* 
            p | q becomes Or (P, Q) 
conj ::= neg (conjOp neg) 
            p & q becomes And (P, Q) 
neg ::= negs | pos 
negs ::= negOp neg 
            ~ p  becomes Not (P) 
pos ::= ident | "(" prop ")" 
            ident becomes Literal (true, ident) 

我們在組合子給出的階代碼提供支柱的懶惰確定指標這是一個錯誤。我已經開始填寫類來匹配上面的代碼,但即使我實現了它,我也沒有發現正確的錯誤,我認爲實際上我不明白你是如何指定的解析器

trait PropRecognizer extends RegexParsers { 

    val ident = """[a-zA-Z]\w*""".r 

    val biArrow = "<=>" | "<+>" 
    val rightArrow = "=>" 
    val leftArrow = "<=" 
    val disjOp = "|" 
    val conjOp = "&" 
    val negOp = "~" 
    lazy val pos = ident | "("~prop~")" 
    lazy val negs: Parser[Any] = negOp~neg 
    lazy val neg = negs | pos 
    lazy val conj = neg~(conjOp~neg).* | neg 
    lazy val disj = conj~(disjOp~conj).* | conj 
    lazy val impls = (rightArrow~disj).+ | (leftArrow~disj).+ | disj 
    lazy val impl = disj~impls.? | impls 
    lazy val equiv = impl~biArrow~impl | impl 
    lazy val prop: Parser[Any] = rep(equiv) 
} 

任何幫助,形成一個提示語法更好的大綱將是令人難以置信的幫助,我已經通過文檔閱讀,似乎仍不能把它按一下在我的頭上。我知道對於那些習慣於命題邏輯和解析器的人來說,這是一個相當簡單的問題,但我現在已經頭疼了好幾個小時,並且正逐漸接近我的點點滴滴。

編輯:UPDATE給出的語法錯了一個項目,所以我調整了它,現在完美的作品:

lazy val prop: Parser[Any] = rep(equiv) 
lazy val equiv: Parser[Any] = impl~(biArrow~impl).? 
    lazy val impl = disj~impls.? 
    lazy val impls: Parser[Any] = (rightArrow~disj).+ | (leftArrow~disj).+ 
    lazy val disj = conj~(disjOp~conj).* 
    lazy val conj: Parser[Any] = neg~(conjOp~neg).* 
    lazy val neg: Parser[Any] = negs | pos 
    lazy val negs: Parser[Any] = negOp~neg 
    lazy val pos = ident | "("~prop~")" 

回答

3

您需要解析表達式轉換成使用^^操作/方法表示類。例如:

lazy val conj: Parser[And] = neg~conjOp~neg ^^ {case p1~_~p2 => And(p1,p2)} 

這假定negParser[Proposition]類型,這是用於表示任何式超類和And需要兩個命題作爲參數。您需要知道Parser[T]將解析某些輸入並返回T作爲其結果的值。

另外Parser是covariant,所以你可以使用你需要解析任何命題的Parser[And]

看看this命題邏輯解析器的例子。

+0

我遇到問題,讓它正確編譯,初始階段它只是將它們解析爲命題,然後指定類型,我一直試圖指定特定的情況下,但我有一個最大的麻煩是檢查是否說我已經做了正確的暗示,確保是否在其自身括號內發生了左邊的暗示。像這樣的話使得聲明無效。 – Schroedinger 2012-04-19 10:05:01

+0

@Schroedinger所以你說它不能將兩個案件放入括號?像'case p1〜'=>「〜p2 => ...'和case p1〜''<" ~ p2 => ...''有時我不得不使用'〜'的前綴語法:'〜(p1,〜(」= >「,p2))'使它工作,也許這就是問題所在? – ziggystar 2012-04-19 11:36:56

+0

@Schroedinger看到我的編輯,我已經添加了鏈接。 – ziggystar 2012-04-19 11:38:42