我正在使用 Scala 解析器组合器为我正在开发的约束编程语言的 DSL 编写解析器。我希望能够解析的内容之一是以下形式的表达式:
<resource1> <relationship_name> <resource2>
例如:
Teacher canTeach Class
我正在尝试使用以下方法来匹配:
stringLiteral ~ stringLiteral ~ stringLiteral
但我真正想要的是能够通过查找第一个和最后一个字符串是否是定义的资源以及中间的字符串是否实际上是范围内的关系来匹配它。
如何定义一个函数,允许我将这些条件放在匹配上,然后使用它。
最佳答案
语法和语法之间存在差异。 stringLiteral ~ stringLiteral ~ stringLiteral
对 stringLiteral
的含义没有任何限制 - 即使您添加一些限制(例如 stringLiteral ~ "canTeach"| "canWhatever"~ stringLiteral
)"- 应该在构造解析器之前知道(而不是在解析本身期间)。但是,您想要的限制似乎是语义,这意味着一些语法正确的句子,例如“Teacher canTeach Microwave” “在语义上可能不正确 - 所以这个检查应该在解析之后完成。你有 AST 作为解析器的输出 - 所以你可以验证这个 AST,比如:
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)))
关于scala - 用于与 Scala 解析器组合器匹配的自定义逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29279459/