具有如下语法定义:
syntax ClassDeclaration = classDecl: "class" Identifier ClassBody ;
...
syntax ClassBody = classBody : "{" ClassBodyDeclaration* "}" ;
syntax ClassBodyDeclaration = ClassMemberDeclaration
| InstanceInitializer
| StaticInitializer
| ConstructorDeclaration
;
... 通过使用访问器,我可以使用以下命令对类主体进行模式匹配:
visit(unit) {
case classDecl(name, ClassBody body): { // a block "A" here }
...
}问:在这种情况下,我如何模式匹配"A“块中" body”变量中的类体声明列表?我尝试过理解,但我发现"body“不是一个可枚举类型。
发布于 2016-10-20 23:56:21
最简单的方法是为ClassBodyDeclaration*命名,如下所示:
syntax ClassBody = classBody : "{" ClassBodyDeclaration* decls "}";然后,您可以使用理解来访问每个声明,例如,使用declList = [ d | d <- body.decls ]之类的代码将它们提取到一个列表中。
另一种选择是使用Rascal的具体语法匹配功能,它不需要修改语法。您可以使用以下代码匹配正文中的声明:
list[ClassBodyDeclaration] declList = [ ];
if ((ClassBody)`{ <ClassBodyDeclaration* decls> }` := body) {
declList = [ d | d <- decls ];
}最后,正如在另一个响应中提到的,您可以执行Rascal所称的深度匹配,匹配body中出现的所有ClassBodyDeclaration:
declList = [ d | /ClassBodyDeclaration d := body ];这是很好的,除非,由于某种原因,您可以将类嵌套在其他类中,在这种情况下,您不会只获得那些属于当前类的类体声明,还会获得嵌套类所拥有的所有声明。
发布于 2016-10-21 00:03:17
如果你无法控制语法,你也可以在理解中使用深度匹配,比如:declList = [ cbd | /ClassBodyDeclaration cbd := body]。这与body中包含的所有ClassBodyDeclaration都匹配。:=是匹配操作符。
发布于 2016-10-21 00:18:25
这个解决方案怎么样:
visit(unit) {
case classDecl(name, classBody(ClassBodyDeclaration* body)): { // a block "A" here }
...
}或者:
visit(unit) {
case (ClassDecl) `class <Identifier name> { <ClassBodyDeclaration* body> }` : {
...
}
}https://stackoverflow.com/questions/40158926
复制相似问题