Custom logic for matching with Scala parser combinators
我正在使用Scala解析器组合器为DSL编写解析器,以使用我正在使用的约束编程语言。我希望能够解析的东西之一是以下形式的表达式:
1
| <resource1> <relationship_name> <resource2> |
例如:
我正在尝试使用以下方式来匹配它:
1
| stringLiteral ~ stringLiteral ~ stringLiteral |
但是我真正想要的是能够通过查找第一个和最后一个字符串是否定义了资源以及中间的字符串实际上是否属于范围内的关系来匹配它。
如何定义允许我将这些条件放在匹配条件上然后使用的函数。
- 语言是否定义了资源和关系?
-
@TravisBrown不,它们不是-它们是由用户在运行时定义的。想象一下REPL。
语法和语法之间有区别。 stringLiteral ~ stringLiteral ~ stringLiteral对stringLiteral是什么没有限制-即使您添加了一些限制(例如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 ))) |