具有如下语法定义:
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”变量的类体声明列表?我尝试了理解,但我认为“身体”不是一个可枚举的类型。
答案 0 :(得分:2)
最简单的方法是给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所谓的深度匹配,匹配正文中所有出现的ClassBodyDeclaration
:
declList = [ d | /ClassBodyDeclaration d := body ];
除非出于某种原因,你可以将类嵌套在其他类中,否则这样就可以了。在这种情况下,你不会只获得属于当前类的那些类体声明,但你也可以得到所有类嵌套类所拥有的那些。
答案 1 :(得分:2)
如果你无法控制语法,你也可以在理解中使用深度匹配:declList = [ cbd | /ClassBodyDeclaration cbd := body]
。
这与ClassBodyDeclaration
中包含的所有body
相匹配。 :=
是匹配运算符。
答案 2 :(得分:2)
这个解决方案怎么样:
file_PATH = "y:/file_A.txt"
if os.path.exists(file_PATH):
file_to_use = "y:/file_A.txt"
else:
file_to_use = "d:/file_B.txt"
或者:
visit(unit) {
case classDecl(name, classBody(ClassBodyDeclaration* body)): { // a block "A" here }
...
}