我正在尝试使用 Scala 的 RegexParser 按照动态认知逻辑语法解析一些文本,作为我硕士论文的一部分。但我在简单的逻辑连接上不断遇到同样的错误。我了解它在哪里以及为什么失败,但不知道为什么它与它最初的情况相匹配。
我的代码(严格归结为隔离问题):
import scala.util.parsing.combinator._
class Formula() {
def and(q:Formula) = Conjunction(this, q) // ∧
}
abstract class Literal extends Formula
abstract class Constant extends Formula
case class Atom(symbol:String) extends Literal
case class NotAtom(p:Atom) extends Literal
case class Conjunction(p:Formula, q:Formula) extends Formula
class mapParser extends RegexParsers {
val conjOp = "&"
val negOp = "~"
val listseparator = ","
val leftparen = "("
val rightparen = ")"
def id:Parser[String] = "[a-z_]+".r // fluents are never capitalized. but may have underscore.
def litargs: Parser[String] = repsep("[a-zA-Z]+".r,listseparator) ^^ {case list => "(" + list.toString.stripPrefix("List") + ")"}
def atom: Parser[Atom] = id~leftparen~litargs~rightparen ^^ {case head~_~tail~_ => Atom(head+tail)}
def negAtom: Parser[NotAtom] = negOp~>atom ^^ (NotAtom(_))
def literal: Parser[Literal] = negAtom | atom
def and: Parser[Formula] = formula~conjOp~formula ^^ {case p1~_~p2 => Conjunction(p1,p2)}
def formula: Parser[Formula] = literal | and
};
object DomainParser extends mapParser {
def test() = {
val domainDesc ="present(A) & ~present(B)";
println("input: " + domainDesc)
println("result: " + apply(domainDesc))
}
def apply(domainDesc: String) = parseAll(formula, domainDesc) match {
case Success(result, _) => result
case failure : NoSuccess => scala.sys.error(failure.msg)
}
}
我正在从 java 外部调用 DomainParser.test() 函数。输入为
present(A) & ~present(B)
应该产生:
Conjunction(Atom(present((A))),NotAtom(Atom(present((B)))))
但却给了我错误:
Exception in thread "main" java.lang.RuntimeException: string matching regex `\z' expected but `&' found
at scala.sys.package$.error(package.scala:27)
at mAp.DomainParser$.apply(DEL.scala:48)
at mAp.DomainParser$.test(DEL.scala:43)
at mAp.DomainParser.test(DEL.scala)
at ma.MA.main(MA.java:8)
此外,如果我直接调用“and”解析器而不是“formula”解析器,它可以正常工作。因此问题似乎出在这一行:
def formula: Parser[Formula] = literal | and
因为它尝试将整行解析为单个文字。然后它正确地解析present(A),但不是在“&”(不是文字解析器的一部分)上失败并返回解析为“and”项,而是失败并出现异常。
我无法理解为什么它会尝试匹配任何“\z”。它没有被我包含在语法中,即使它是 - 它不应该失败并尝试解析为下一个术语而不是异常退出吗?我左右为难,一是认为存在一些我不知道的字符串结尾术语的内置功能,二是认为有一些非常明显的东西就在我面前。
我们非常需要任何帮助,非常欢迎并提前非常感谢您。
丹·特鲁
最佳答案
我只会为我制作的命题公式添加一个类似的解析器。也许这可能对您有帮助。
'+' = 顶部/true
'-' = 底部/假
'!' = 否定
'&' = 连词
'|' = 析取
'>' = 含义
'<' = 等价
object FormulaParser extends StandardTokenParsers with PackratParsers {
//Symbols for all connectives
private val parseSymbols = List("(", ")", "+", "-", "!", "&", "|", ">", "<")
lexical.delimiters ++= parseSymbols
private lazy val formula: PackratParser[Formula] = implication | equivalence | conjunction | disjunction | term
private lazy val formulaWithoutBrackets: PackratParser[Formula] = implication | equivalence | conjunction | disjunction | termWithoutBrackets
private lazy val term: PackratParser[Formula] = top | bottom | variable | parens | negation
private lazy val termWithoutBrackets = top | bottom | variable | negation
private lazy val top: PackratParser[Formula] = "+" ^^^ { Top() }
private lazy val bottom: PackratParser[Formula] = "-" ^^^ { Bottom() }
private lazy val variable: PackratParser[Formula] = ident ^^ { Variable(_) }
private lazy val parens: PackratParser[Formula] = "(" ~> formulaWithoutBrackets <~ ")"
private lazy val negation: PackratParser[Formula] = "!" ~> term ^^ { Negation(_) }
private lazy val conjunction: PackratParser[Formula] = term ~ "&" ~ term ~ rep("&" ~> term) ^^ {
case p ~ "&" ~ q ~ conj => conj.foldLeft(Conjunction(p,q))((con, elem) => Conjunction(con, elem))
}
private lazy val disjunction: PackratParser[Formula] = term ~ "|" ~ term ~ rep("|" ~> term) ^^ {
case p ~ "|" ~ q ~ disj => disj.foldLeft(Disjunction(p,q))((dis, elem) => Disjunction(dis, elem))
}
private lazy val implication: PackratParser[Formula] = (conjunction | disjunction | term) ~ ">" ~ (conjunction | disjunction | term) ^^ { case p ~ ">" ~ q => Implication(p, q) }
private lazy val equivalence: PackratParser[Formula] = (conjunction | disjunction | term) ~ "<" ~ (conjunction | disjunction | term) ^^ { case p ~ "<" ~ q => Equivalence(p, q) }
}
有了这个,您可以解析输入,例如:
(p & q) | (!q > (r & s))
这里的连词和析取也比蕴涵和等价结合得更强。
p & q > r | s
将导致 Implication(Conjunction(Variable(p), Variable(q)), Disjunction(Variable(r), Variable(s)))
关于java - Scala 解析器和组合器 : java. lang.RuntimeException:字符串匹配正则表达式 `\z' 预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22212448/