解析字符串然后转换为另一种格式,在Scala中
问题描述:
我有一个命题公式,例如,在该字符串格式:解析字符串然后转换为另一种格式,在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
任何暗示我怎么能继续做到这一点真的欢迎!谢谢。
答
你不希望有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
是一个代数数据类型的例子,通过搜索这个术语,你可以找到更多的信息。