2017-02-20 40 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是一个代数数据类型的例子,通过搜索这个术语,你可以找到更多的信息。

相关问题