2017-02-20 18 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 - пример алгебраического типа данных, и, ища этот термин, вы можете найти гораздо больше информации.