以下是我的语法:
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
greetings+=Table*;
Table:
'table' name=ID type=Type
;
enum Type: COLUMN | ROW;
以下字符串无效实例:
table ROW COLUMN
这是关键词污染吗? ROW
可以充当表的名称。为什么xtext会将其视为一个类型?它有确定它的背景。
我误解了什么吗?我怎么能避免这种事呢?
答案 0 :(得分:0)
这是xtext枚举的工作原理。枚举文字成为关键字。
你基本上有两个选择
(1)摆脱关键词遮蔽ID规则
Table:
'table' name=MyID type=Type
;
MyID: ID | "COLUMN" | "ROW";
可能需要针对MyID修改proposalprovider
(2)以不同的方式处理枚举。这适用于仅手动维护的元模型
MyEnum returns importedPackage::MyEnum : ID;
实施例
Model:
greetings+=Greeting*;
Greeting:
'Hello' name=ID value=MyEnumDataTypeRule;
//TO be save MyEnum wold be better declared in a separate metamodel
// for sake of easyness i work here with literals that seem to be unlikely to conflict
// to tell xtext there are literals A B and C
enum MyEnum:
A="___________a"|
B="___________b"|
C="___________c"
;
MyEnumDataTypeRule returns MyEnum:
ID
;
价值转换器
class MyDslValueConverters extends DefaultTerminalConverters {
@Inject
MyEnumValueConverter myEnumValueConverter
@ValueConverter(rule = "MyEnumDataTypeRule")
def IValueConverter<MyEnum> MyEnumDataTypeRule() {
return myEnumValueConverter
}
}
class MyEnumValueConverter implements IValueConverter<MyEnum> {
override toString(MyEnum value) throws ValueConverterException {
return value.getName();
}
override toValue(String string, INode node) throws ValueConverterException {
try {
return MyEnum.valueOf(string)
} catch (IllegalArgumentException e) {
throw new ValueConverterException("MyEnum does not allow literal " + string, node, e)
}
}
def static void main(String[] args) {
MyEnum.valueOf("xxxx")
}
}
结合
class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
override bindIValueConverterService() {
MyDslValueConverters
}
}
内容辅助
class MyDslProposalProvider extends AbstractMyDslProposalProvider {
override complete_MyEnumDataTypeRule(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
MyEnum.values.forEach[
acceptor.accept(createCompletionProposal(getName(),context))
]
}
}