简体   繁体   English

在Scala中解析字符串然后转换为另一种格式

[英]Parsing a string then converting to another format, in Scala

I have a propositional formula, eg, in this String format: 我有一个命题公式,例如,这种String格式:

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

I wrote a parser like this: 我写了这样的解析器:

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)"))

  }
}

Well, the parsed output looks like: 好了,解析后的输出看起来像:

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

I am trying several ways, by using the operations ^^ , to get rid of these "extra" parentheses and stuff, but without success. 我正在尝试几种方法,通过使用操作^^来摆脱这些“额外”括号和内容,但没有成功。

Actually, the result that I want to get is to convert the formula in a .dimacs format, where each letter/word is a number, the \\/ operator becomes a space between the literals and the \\/ becomes a newline (where a value 0 is inserted at the end of each line). 实际上,我想要得到的结果是将公式转换为.dimacs格式,其中每个字母/单词是一个数字, \\/运算符变成文字之间的space ,而\\/变成newline (其中一个值每行的末尾插入0 )。 Concretely, for my example here - if x = 1, y = 2, a = 3, b = 4, d = 5 - then the resulting file must look like this: 具体来说,以我的示例为例-如果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

Any hint how I can continue to achieve this is really welcomed! 非常欢迎我能继续实现这一目标的任何提示! Thanks. 谢谢。

You don't want to have Parser[Any] ; 您不想拥有Parser[Any] instead, define a data type representing formulas: 而是定义代表公式的数据类型:

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.

You can add any operations you end up needing to Formula (or to the companion object) as well. 您还可以将最终需要的所有操作添加到“ Formula (或伴随对象)中。

Then define Parser[Formula] and work with Formula s, not with strings. 然后定义Parser[Formula]并使用Formula而不是字符串。

Formula is an example of an algebraic data type, and by searching for this term you can find a lot more information. Formula是代数数据类型的示例,通过搜索此术语,您可以找到更多的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM