还在学习如何正确使用ANTLR ......这是我的问题。
假设您有一个(子集)UML语法和一个ANTLR Lexer / Parser,其中包含以下规则:
// Parser Rules
model
: 'MODEL' IDENTIFIER list_dec
;
list_dec
: declaration*
;
declaration
: class_dec ';'
| association ';'
| generalization ';'
| aggregation ';'
;
class_dec
: 'CLASS' IDENTIFIER class_content
;
...
association
: 'RELATION' IDENTIFIER 'ROLES' two_roles
;
two_roles
: role ',' role
;
role
: 'CLASS' IDENTIFIER multiplicity
;
...
我希望'role'规则只允许IDENTIFIER标记与现有的类IDENTIFIER匹配。换句话说,如果给你一个输入文件并在其上运行词法分析器/解析器,那么所有引用的类(例如关联规则中的IDENTIFIER)都应该存在。问题是类(可能)在运行时可能不存在(它可以在文件中的任何位置声明)。最好的办法是什么?
提前致谢...
答案 0 :(得分:1)
这可能是在解析之后完成的。解析器为您创建某种树,然后您遍历树并收集有关已声明类的信息,并再次遍历它以验证role
树/规则。
当然,有些事情可以通过一些自定义代码完成:
grammar G;
options {
...
}
@parser::members {
java.util.Set<String> declaredClasses = new java.util.HashSet<String>();
}
model
: 'MODEL' IDENTIFIER list_dec
;
...
class_dec
: 'CLASS' id=IDENTIFIER class_content
{
declaredClasses.add($id.text);
}
;
...
role
: 'CLASS' id=IDENTIFIER multiplicity
{
if(!declaredClasses.contains($id.text)) {
// warning or exception in here
}
}
;
...
或使用自定义方法:
@parser::members {
java.util.Set<String> declaredClasses = new java.util.HashSet<String>();
void addClass(String id) {
boolean added = declaredClasses.add(id);
if(!added) {
// 'id' was already present, do something, perhaps?
}
}
void checkClass(String id) {
if(!declaredClasses.contains(id)) {
// exception, error or warning?
}
}
}
...
class_dec
: 'CLASS' id=IDENTIFIER class_content {addClass($id.text);}
;
role
: 'CLASS' id=IDENTIFIER multiplicity {checkClass($id.text);}
;