关于dsl:用于与Scala解析器组合器匹配的自定义逻辑

Custom logic for matching with Scala parser combinators

我正在使用Scala解析器组合器为DSL编写解析器,以使用我正在使用的约束编程语言。我希望能够解析的东西之一是以下形式的表达式:

1
<resource1> <relationship_name> <resource2>

例如:

1
Teacher canTeach Class

我正在尝试使用以下方式来匹配它:

1
stringLiteral ~ stringLiteral ~ stringLiteral

但是我真正想要的是能够通过查找第一个和最后一个字符串是否定义了资源以及中间的字符串实际上是否属于范围内的关系来匹配它。

如何定义允许我将这些条件放在匹配条件上然后使用的函数。


语法和语法之间有区别。 stringLiteral ~ stringLiteral ~ stringLiteralstringLiteral是什么没有限制-即使您添加了一些限制(例如stringLiteral ~"canTeach" |"canWhatever" ~ stringLiteral)"-在构造解析器之前(而不是在解析本身期间)也应该知道它。但是,您想要的限制似乎是表示语义,这意味着某些语法上正确的句子(例如" Teacher canTeach Microwave ")可能在语义上不正确-因此应在解析后进行此检查。您将AST作为解析器的输出-因此您可以仅验证此AST ,例如:

1
2
3
4
5
case class Knowledge(subject: String, can: Boolean, predicate: String, obj: String)

val knowledges = parse("Teacher can teach Class","Teacher cannot teach Class")

knowledges.groupBy(x => (x.subject, x.predicate, x.obj)).mapValues(v => if(v.forall(v.head.can == _.can)) Right(v) else Left(v)))