2012-11-11 37 views
0

几天前我开始玩xtext,刚刚通过教程。也许这个解决方案已经在参考文献中介绍过了,但我不能很快理解它。避免自定义终端隐藏(抑制)衍生个人

我的问题是这样的。我试图写一个混合在org.eclipse.xtext.common.Terminals中的简单语法。然后,我想插入cusotm终端FILE_NAME这样的:

terminal FILE_NAME: 
(!('/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|'))+ 
; 

这基本上是什么文件名被允许在Windows下。但是,通过这样做,像ID,INT等继承的规则永远不会匹配,因为它们总是在自定义终端之后生成的。

能否优雅地避免这类问题(尽可能重复且尽可能一般)?提前致谢!

回答

0

终端规则(也称为词法分析规则)用于标记输入序列。恕我直言,在终端规则中应该有最小的语义。

您试图表达一个专门的解析器规则,它只接受有效的文件名。

查看Xtext Documentation [1]中描述的解析器阶段。我的建议:

  1. Lexing:不是使用专门的终端规则,而是使用STRING。

  2. 验证:为具有'fileName'EAttribute的EClass编写验证规则。



的非重复越好,尽可能通用

你不想用 '文件名' EAttribute重复你的验证每一个的EClass。如果您拥有精致的Ecore模型,请使用'fileName'EAttribute引入新的超类型。

比你可以实现一个通用验证规则#check_fileName_is_valid(ElementWithFile)。

如果您没有精致的MM,请在您的语法中使用元模型提示。如果你提供了一个广义的超类型Xtext的Ecore推理器将拉起这些子类型的共同特征。例如:

ElementWithFile: A | B; 
A: ... 'file' fileName=STRING ...; 
B: ... 'file' fileName=STRING ...; 
// => Ecore: ElementWithFile.fileName<EString> 



[1] http://www.eclipse.org/Xtext/documentation.html#DSL

+0

感谢亚历克斯!我所做的大致是你所建议的。但是,这是一种解决方法,而非解决方案。如果我想使用xtext为现有语法创建一个编辑器,而我无法修改语法,那么它将无法工作。一个真实世界的例子是由ogre3d材料脚本定义的材料的名称:http://www.ogre3d.org/docs/manual/manual_14.html#Material-Scripts – abel

+0

实际上它是一种可能的解决方案。 另一种方式需要一些额外的设置。 特别是如果语法是固定的,或者您不想用这种提示来污染它,请在语法后面细化Ecore模型: *转到DSL运行时插件的src-gen并获取YourDSL.ecore和YourDSL。的genmodel。 *将MM资源移动到新的“com.your.dsl.model”插件。 *根据需要修改YourDSL.ecore。 *从GenModel生成模型代码。 *确保模型插件导出模型代码的正确包装。 (tbc ...) – Alex

+0

... *确保runtime/ui/test/generator/...插件声明模型插件的依赖关系。 *使用导入“YourDslURL”而不是生成“YourDslURL”。 这样您就负责Ecore模型和Xtext语法的兼容性。 语法编辑器会在出现问题时显示警告/错误。 还有一种通过执行MWE2工作流程来生成模型代码的方法。 – Alex