2017-02-20 80 views
0

我有一個命題公式,例如,在該字符串格式:解析字符串然後轉換爲另一種格式,在Scala中

(~d \/ x) /\ (y \/ ~b) /\ (~y \/ a \/ b)

我寫這樣一個解析器:

import scala.util.parsing.combinator._ 

class CNFParser extends JavaTokenParsers with RegexParsers { 
    def expr: Parser[Any] = term~rep("/\\"~term) 
    def term: Parser[Any] = value~rep("\\/"~value) 
    def value: Parser[Any] = ident | "~"~ident | "("~expr~")" 

} 

object Test_02 extends CNFParser { 
    def main(args: Array[String]): Unit = { 

    println("input: " + "(~d \\/ x) /\\ (y \\/ ~b) /\\ (~y \\/ a \\/ b)") 
    println(parseAll(expr, "(~d \\/ x) /\\ (y \\/ ~b) /\\ (~y \\/ a \\/ b)")) 

    } 
} 

那麼,解析輸出如下所示:

[1.41] parsed: (((((~(((~~d)~List((\/~x)))~List()))~))~List())~List((/\~((((~((y~List((\/~(~~b))))~List()))~))~List())), (/\~((((~(((~~y)~List((\/~a), (\/~b)))~List()))~))~List())))) 

我正在嘗試幾種方法,通過使用操作^^,擺脫這些「額外」括號和東西,但沒有成功。

其實,我想要得到的結果是公式轉換成一個.dimacs格式,其中每個字母/字是一個數字,\/運算符將成爲文字之間的space\/成爲newline(其中一值0插入在每行的末尾)。具體而言,在這裏我的例子 - 如果x = 1, y = 2, a = 3, b = 4, d = 5 - 然後將得到的文件必須是這樣的:

c filename.cnf 
p cnf 5 3 
-5 1 0 
2 -4 0 
-2 3 4 

任何暗示我怎麼能繼續做到這一點真的歡迎!謝謝。

回答

1

你不希望有Parser[Any];取而代之的是,代表公式數據類型:

sealed trait Formula 
case class Variable(name: String) extends Formula { 
    override def toString = name 
} 
case class And(left: Formula, right: Formula) { 
    override def toString = s"($left /\ $right)" 
} 
// etc. 

您可以添加你最終需要Formula(或同伴對象)以及任何操作。

然後定義Parser[Formula]並使用Formula s,而不是字符串。

Formula是一個代數數據類型的例子,通過搜索這個術語,你可以找到更多的信息。

相關問題