2017-02-20 4 views
0

に、別の形式に変換する私は命題式を有し、文字列の解析:この文字列の形式で、例えば、Scalaの

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

    } 
} 

(~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())))) 

私はいくつかの方法を試していますこれらの「余分な」括弧やものを取り除くために、操作^^を使用することによって、成功することはできません。

実際、私が取得したい結果は各文字/単語の数であり、\/オペレータはリテラル間spaceなり、\/newline(ここでなる.dimacs形式、式を変換することです値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を使用します。

Formulaは、代数データ型の例であり、この用語を検索すると、より多くの情報を見つけることができます。