我尝试展示一个描述我的问题的最小工作示例:
语法
这是xtext
我为此示例创建的语法。(当然真正的语法要复杂得多,还涉及高级表达语言)
grammar org.example.dsl.DSL with org.eclipse.xtext.common.Terminals
generate dsl "http://www.example.org/dsl/DSL"
Model:
elements+=Declaration*
;
QualifiedName:
ID ('.' ID)*
;
Declaration:
SimpleTypeDeclaration |
SectionDeclaration |
FieldDeclaration
;
SimpleTypeDeclaration:
"type" name=ID "=" primitive=IntegerType
;
IntegerType
{IntegerType} "int"
;
SectionDeclaration:
"section" name=ID "{"
elements+=FieldDeclaration*
"}"
;
TypeDeclaration:
SimpleTypeDeclaration |
SectionDeclaration
;
FieldDeclaration:
name=ID ":" type=[TypeDeclaration|QualifiedName] ("=" value=ValueExpression)?
;
ValueExpression:
FieldReference |
SimpleValue
;
FieldReference:
ref=[FieldDeclaration|QualifiedName]
;
SimpleValue:
{SimpleValue} "sentinel"
;
示例语言中的示例代码
这是我上面描述的语言的一些示例代码。
type Foo = int
section A {
foo: Foo = sentinel
}
section B {
a: A
// here I want to assign the value of a subfield of `a`
// to fubar
fubar: Foo = a.foo // crucial point
}
示例代码片段的全局索引
示例代码片段的默认索引器将生成以下全局范围索引以供参考:
[Foo, A, A.foo, B, B.a, B.fubar]
因此,在正确的范围内,我将能够通过引用解析代码中的这些标识符来引用所有这些对象。
但是crucial point
代码片段中的 不会被解析,因为B.a.foo
分别a.foo
不会在索引中。
到目前为止我的想法和尝试(不完整的解决方案)
我想自定义索引,以便将其额外放入
B.a.foo
索引中。- 但这会污染索引,可能有很多不必要的资源 URI,我永远不想从全局范围引用。
- (例如,我只想能够从我引用它的部分中引用字段子字段)
在名为 => 的语法中创建一个新规则,
Selection
通过提供自定义来明确选择字段ScopeProvider
。但是我遇到了一些问题:- 如果我仍然提供通过
QualifiedName
s 引用所有内容的可能性,则语法和解析始终认为它是一个类型引用,并且不会要求我的自定义范围提供程序提供Selection
规则的引用,这会重载点运算符 (.
) - 如果我删除引用机制
[TypeDeclaration|QualifiedName]
来替换它,[TypeDeclaration|ID]
我将不得不为每个基本类型和子引用自定义范围,并且不会利用 xtext 强大的默认限定名称解析。
- 如果我仍然提供通过
我现在的问题
有人知道我描述的问题的标准或最佳解决方案吗?