几天前我开始玩xtext,刚刚完成了教程。也许解决方案已经在某处提到了参考,但我无法快速完成。
我的问题是这个。我试着写一个混合在org.eclipse.xtext.common.Terminals
中的简单语法。然后我想像这样插入一个cusotm终端FILE_NAME
:
terminal FILE_NAME:
( !('/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|') )+
;
这基本上是允许在Windows下使用的文件名。但是,通过这样做,ID,INT等继承的规则永远不会匹配,因为它们总是在自定义终端之后生成。
是否可以优雅地避免这种问题(尽可能重复和尽可能一般)?提前谢谢!
答案 0 :(得分:0)
终端规则(aka lexer规则)用于标记输入序列。恕我直言,终端规则中应该有最少的语义。
您尝试表达专门的解析器规则,该规则仅接受有效的文件名。
查看Xtext文档[1]中描述的解析器阶段。我的建议是:
Lexing:使用STRING代替使用专门的终端规则。
验证:为具有'fileName'EAttribute的EClass编写验证规则。
尽可能无重复且尽可能一般
您不希望为每个带有'fileName'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>