题
我正在尝试解析ecore模型。如果有接口链接字段,我无法访问它的实现值。
X文本语法:
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
?它始终为空。
解决方案
你的语法是假的。本质上,你试图举例说明你的 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';
不隶属于 StackOverflow