2017-02-20 7 views
0

에, 다른 형식으로 변환 나는 명제 공식이 다음 문자열을 구문 분석 :이 String 형식으로, 예를 들어, 스칼라

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

여러 가지 방법을 시도하고 있습니다. , ^^ 작업을 사용하여 이러한 "추가"괄호와 내용을 제거하지만 성공하지는 못합니다.

사실, 취득하는 결과가 각 문자/단어가 숫자 인 .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은 대수 데이터 유형의 예이며이 용어를 검색하면 더 많은 정보를 찾을 수 있습니다.