2012-04-19 32 views
1

我已经为大学里的一项任务设置了作业任务,以便使用Scala组合器来分析命题逻辑,而且我正在处理这个问题时正要将我的头发撕掉几个小时,甚至不能超过第一阶段。使用scala组合器来分析命题逻辑

最初的部分是构建一个识别器,该识别器构建符合给定的EBNF格式的识别类型(类型已单独提供)。 ([]意味着0或一个,+意味着一个或更多个和*意味着零个或多个)

prop ::= equiv 

equiv ::= impl biArrow impl 
            p <=> q becomes Equivalent (P, Q) 
            p <+> q becomes Not (Equivalent (P, Q)) 
impl ::= disj [impls] 
impls ::= (rightArrow disj)+ 
            p => q becomes Implies (P, Q) 
     | (leftArrow disj)+ 
            p => q becomes Implies (Q, P) 
disj ::= conj (disjOp conj)* 
            p | q becomes Or (P, Q) 
conj ::= neg (conjOp neg) 
            p & q becomes And (P, Q) 
neg ::= negs | pos 
negs ::= negOp neg 
            ~ p  becomes Not (P) 
pos ::= ident | "(" prop ")" 
            ident becomes Literal (true, ident) 

我们在组合子给出的阶代码提供支柱的懒惰确定指标这是一个错误。我已经开始填写类来匹配上面的代码,但即使我实现了它,我也没有发现正确的错误,我认为实际上我不明白你是如何指定的解析器

trait PropRecognizer extends RegexParsers { 

    val ident = """[a-zA-Z]\w*""".r 

    val biArrow = "<=>" | "<+>" 
    val rightArrow = "=>" 
    val leftArrow = "<=" 
    val disjOp = "|" 
    val conjOp = "&" 
    val negOp = "~" 
    lazy val pos = ident | "("~prop~")" 
    lazy val negs: Parser[Any] = negOp~neg 
    lazy val neg = negs | pos 
    lazy val conj = neg~(conjOp~neg).* | neg 
    lazy val disj = conj~(disjOp~conj).* | conj 
    lazy val impls = (rightArrow~disj).+ | (leftArrow~disj).+ | disj 
    lazy val impl = disj~impls.? | impls 
    lazy val equiv = impl~biArrow~impl | impl 
    lazy val prop: Parser[Any] = rep(equiv) 
} 

任何帮助,形成一个提示语法更好的大纲将是令人难以置信的帮助,我已经通过文档阅读,似乎仍不能把它按一下在我的头上。我知道对于那些习惯于命题逻辑和解析器的人来说,这是一个相当简单的问题,但我现在已经头疼了好几个小时,并且正逐渐接近我的点点滴滴。

编辑:UPDATE给出的语法错了一个项目,所以我调整了它,现在完美的作品:

lazy val prop: Parser[Any] = rep(equiv) 
lazy val equiv: Parser[Any] = impl~(biArrow~impl).? 
    lazy val impl = disj~impls.? 
    lazy val impls: Parser[Any] = (rightArrow~disj).+ | (leftArrow~disj).+ 
    lazy val disj = conj~(disjOp~conj).* 
    lazy val conj: Parser[Any] = neg~(conjOp~neg).* 
    lazy val neg: Parser[Any] = negs | pos 
    lazy val negs: Parser[Any] = negOp~neg 
    lazy val pos = ident | "("~prop~")" 

回答

3

您需要解析表达式转换成使用^^操作/方法表示类。例如:

lazy val conj: Parser[And] = neg~conjOp~neg ^^ {case p1~_~p2 => And(p1,p2)} 

这假定negParser[Proposition]类型,这是用于表示任何式超类和And需要两个命题作为参数。您需要知道Parser[T]将解析某些输入并返回T作为其结果的值。

另外Parser是covariant,所以你可以使用你需要解析任何命题的Parser[And]

看看this命题逻辑解析器的例子。

+0

我遇到问题,让它正确编译,初始阶段它只是将它们解析为命题,然后指定类型,我一直试图指定特定的情况下,但我有一个最大的麻烦是检查是否说我已经做了正确的暗示,确保是否在其自身括号内发生了左边的暗示。像这样的话使得声明无效。 – Schroedinger 2012-04-19 10:05:01

+0

@Schroedinger所以你说它不能将两个案件放入括号?像'case p1〜'=>“〜p2 => ...'和case p1〜''<" ~ p2 => ...''有时我不得不使用'〜'的前缀语法:'〜(p1,〜(”= >“,p2))'使它工作,也许这就是问题所在? – ziggystar 2012-04-19 11:36:56

+0

@Schroedinger看到我的编辑,我已经添加了链接。 – ziggystar 2012-04-19 11:38:42