Java 定义xtext语法时导入packageDefinition“.”接口定义
我正在尝试使用xText创建一个简单的语法。语法应该只为Java接口定义语言,目前我正忙于导入声明。我希望能够引用我使用FQN定义的其他包中的其他接口。我的语法是这样的:Java 定义xtext语法时导入packageDefinition“.”接口定义,java,antlr,grammar,xtext,Java,Antlr,Grammar,Xtext,我正在尝试使用xText创建一个简单的语法。语法应该只为Java接口定义语言,目前我正忙于导入声明。我希望能够引用我使用FQN定义的其他包中的其他接口。我的语法是这样的: DomainModel: elements=AbstractElement; AbstractElement: 'package' packageDeclaration=PackageDeclaration 'import'? importDeclarations+=ImportDeclaratio
DomainModel:
elements=AbstractElement;
AbstractElement:
'package' packageDeclaration=PackageDeclaration
'import'? importDeclarations+=ImportDeclaration*
typeDeclaration=TypeDeclaration;
PackageDeclaration:
name=QualifiedName ';';
ImportDeclaration:
importedNamespace=[ReferncedType|QualifiedName] ('.*')? ';';
ReferncedType:
PackageDeclaration |InterfaceDeclaration; //need to combine both?? separated by '.'
TypeDeclaration:
'interface' interfaceDeclaration=InterfaceDeclaration;
TypeList:
Type ( ',' type+=Type)*;
Type:
typeDefinition=[ReferncedType|ValidID];
InterfaceDeclaration:
name=ValidID ('extends' superType=TypeList)? body=InterfaceBody;
InterfaceBody:
'{' (declarations+=InterfaceBodyDeclaration)+ '}';
InterfaceBodyDeclaration:
interfaceMemberDelcaration+=InterfaceMemberDeclaration ';';
InterfaceMemberDeclaration:
InterfaceMethodDeclaration;
InterfaceMethodDeclaration:
(Type | 'void') name+=ValidID '(' (formalParameters+=FormalParameters)* ')' ('throws'
....)?;
我已经定义了两个文件:
package org.first.sample;
interface Demo {
void getA();
}
你有什么想法吗?当我读语法时:
ImportDeclaration:
importedNamespace=[ReferncedType|QualifiedName] ('.*')? ';';
ReferncedType:
PackageDeclaration |InterfaceDeclaration; //need to combine both?? separated by '.'
PackageDeclaration:
name=QualifiedName ';';
因此,import后面可以跟一个PackageDeclaration=QualifiedName,后面跟一个;然后,回到规则导入声明,另一个;必须遵循
另外,我不明白为什么referencedType也可以扩展到InterfaceDeclaration,这就是全部
后来
因此,也许应该将导入定义为
AbstractElement:
'package' packageDeclaration=PackageDeclaration
importDeclarations+=ImportDeclaration*
...
ImportDeclaration
'import' importedNamespace=QualifiedName ('.*')? ';';
它不允许静态导入,必须做一些事情来跟踪。*如果发生这种情况。您可以绑定一个自定义的QualifiedNameProvider来覆盖接口导出的名称。 类似这样的东西应该可以使导入引用正常:import org.first.sample.Demo
public class CustomQualifiedNameProvider extends DefaultDeclarativeQualifiedNameProvider {
@Override
public QualifiedName getFullyQualifiedName(EObject obj) {
if (obj instanceof InterfaceDeclaration && obj.eContainer().eContainer() instanceof AbstractElement) {
QualifiedName packageQualifiedName = getFullyQualifiedName(((AbstractElement)obj.eContainer().eContainer()).getPackageDeclaration());
return packageQualifiedName.append(((InterfaceDeclaration) obj).getName());
}
return super.getFullyQualifiedName(obj);
}
}
此外,您可以按Ctrl+Shift+F3查看导出对象的名称。实际上@laune是正确的。Xtext支持这种开箱即用的方式。只要模型中引用的类型具有名为“name”的功能,类型的完全限定名就是现成的。我注意到Xtext语法定义中的错误是包应该包含接口,这样当一个完全限定名形成时,Xtext通过将接口的“名称”与包或其父包的“名称”相结合来构造它。 @如果xtext语法规则不包含“name”特性,那么您的答案是正确的。这是构建FQN的一种自定义方法,例如,我们使用以下方法:
Package:
'package' name=ID ';' imports=Import ';' interface=Interface ';'
;
Interface:
qualifier=Qualifier !id=ID (instead of name=ID)
;
然后我们应该显式地构造fqn,因为内置支持只查找“name”特性
因此,在我的情况下,正确的使用方法是:
Package:
'package' name=ID; imports=Import typeDefinition=TypeDefinition;
Import:
'import' importedNamespace=[TypeDefinition|QualifiedName] ';'
;
TypeDefinition:
InterfaceDefinition | EnumDefinition ...
;
InterfaceDefinition:
qualifier=Qualifier !name=ID
;
嗯,我不确定ReferencedType规则应该包含什么。我只需要能够像在Java import com.somepackage中那样导入类型。TypeName或com.sompackage.*请参阅我稍后添加的内容。谢谢,但如果导入的包无效,则不会引发编译错误。它将使用任何有效的限定名进行编译。我只需要引用现有的类型。这应该像Java编译器那样工作吗?如果是这样,则使用限定名访问类文件,或者,如果所有类文件都参与编译,则限定名最终必须引用在别处声明的接口。但是接口不会在导入中显示为完全的。不,演示类已编译。谢谢!这很有帮助。
Package:
'package' name=ID; imports=Import typeDefinition=TypeDefinition;
Import:
'import' importedNamespace=[TypeDefinition|QualifiedName] ';'
;
TypeDefinition:
InterfaceDefinition | EnumDefinition ...
;
InterfaceDefinition:
qualifier=Qualifier !name=ID
;