我正在尝试解析ecore模型。如果存在接口链接字段,则无法访问其实现值。
Xtext Grammar:
Map:
type=MapCreate
name=ID '='
mapcontent+=MapBody (',' mapcontent+=MapBody)* ';';
MapCreate:
'Map' '<' keyType=MapKeyDataType ',' valueType=MapValueType '>';
MapKeyDataType:
'String' | 'int';
MapValueType:
MapKeyDataType | 'float' | MapCreate;
示例实施:
Map<int, String> ma = {0="a", 5="b"};
解析keyType
字段效果很好,但如何对valueType
执行相同操作?它总是空的。
答案 0 :(得分:2)
你的语法是假的。基本上,您尝试使Map
的实例成为String
的超类型实例。这将永远不会奏效,Xtext可能会对该语法显示一些警告。
基本上发生了以下情况:
您将规则MapKeyDataType
定义为数据类型规则(有关详细信息,请参阅文档)。也就是说,它的返回类型是String
。
您还可以定义委派给MapValueType
的规则MapKeyDataType
。这意味着返回类型必须是返回类型MapKeyDataType
的赋值兼容(超类型)。它必须是String
或其超类型之一,例如Object
。现在,您还可以从MapValueType
委派给MapCreate
。 MapCreate
反过来不生成普通字符串,而是MapCreate
的实例。您的MapCreate
和Java的String
通常不兼容。 Xtext的类型推断现在使MapKeyDataType
不再返回String,而是声明返回类型MapKeyDataType
。但是,不会有任何实例,因为它们从未实例化:解析器规则没有任何赋值。这就是为什么你的语法会给你带来麻烦。
这样的东西可以清理一下:
Map:
type = MapType name=ID '=' ...;
MapType:
{MapType} name='Map' '<' keyType=PlainType ',' valueType=ValueType '>';
PlainType returns Type:
name = 'String' | name='int';
ValueType returns Type:
MapType | PlainType | ValuePlainType;
ValuePlainType returns Type:
name='float';