我有一个Xtext语法,它读(部分):
grammar mm.ecxt.MMLanguage hidden(WS, COMMENT)
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
...
Statement:
ConstantStatement |
VariableStatement |
LabeledStatement |
...
LabeledStatement:
EssentialHypothesisStatement |
...
ConstantStatement:
DOLLAR_C (constants+=ConstDecl)+ DOLLAR_DOT;
VariableStatement:
DOLLAR_V (variables+=VarDecl)+ DOLLAR_DOT;
EssentialHypothesisStatement:
name=LABEL DOLLAR_E (symbols+=[Decl|MATHSYMBOL])+ DOLLAR_DOT;
Decl: ConstDecl | VarDecl;
ConstDecl returns ConstDecl: name=MATHSYMBOL;
VarDecl returns VarDecl: name=MATHSYMBOL;
MATHSYMBOL: PARENOPEN | PARENCLOSE | QUESTIONMARK | COMPRESSED | TLABEL | WORD;
...
(完整的语法是来自当前MMLanguage.xtext的承诺328 a5e7 of https://github.com/marnix/metamath-eclipse-xtext/)。
我的问题:如何通过对常量和变量使用不同的颜色来突出显示EssentialHypothesisStatement
中的symbols
?因此,如果MATHSYMBOL
引用的是ConstDecl
,那么应该以一种方式高亮显示,而对于VarDecl
,则应该用其他方式突出显示。
我试图以各种方式创建一个ISemanticHighlightingCalculator
,但我似乎无法通过节点模型或Ecore模型来检测实际的引用类型。一方面,语法相关的方法只告诉我引用指向Decl
。另一方面,Ecore模型的EReference
告诉我目标是ConstDecl
还是VarDecl
,但是在那里我找不到源MATHSYMBOL
的位置。
请注意,我更喜欢使用节点模型(而不是Ecore模型),因为我也希望突出注释,而且出于性能原因,我无法对文档进行多次传递。
实现这一目标的好/规范/高效/简单的方法是什么?
发布于 2015-11-16 22:44:41
从org.eclipse.xtext.nodemodel.util.NodeModelUtils.findNodesForFeature(EObject,的角度看一看EObject EStructuralFeature),从节点模型的角度来看,您可以使用EObjectAtOffsetHelper
样本文法
Model:
defs+=Def*
uses+=Use*
;
Def:
ADef | BDef;
ADef:
"adef" name=ID
;
BDef:
"bdef" name=ID
;
Use:
"use" def=[Def]
;
而这里的动力
public class MyDslSemanticHighlightingCalculator implements ISemanticHighlightingCalculator {
@Inject
private MyDslGrammarAccess ga;
@Inject
private EObjectAtOffsetHelper helper;
@Override
public void provideHighlightingFor(XtextResource resource, IHighlightedPositionAcceptor accoptor, CancelIndicator cancelIndicator) {
if (resource == null)
return;
IParseResult parseResult = resource.getParseResult();
if (parseResult == null || parseResult.getRootNode() == null)
return;
BidiTreeIterable<INode> tree = parseResult.getRootNode().getAsTreeIterable();
for (INode node : tree) {
if (cancelIndicator.isCanceled()) {
return;
}
if (node.getGrammarElement() instanceof CrossReference) {
if (ga.getUseAccess().getDefDefCrossReference_1_0() == node.getGrammarElement()) {
EObject target = helper.resolveElementAt(resource, node.getOffset());
if (target instanceof ADef) {
accoptor.addPosition(node.getOffset(), node.getLength(), HighlightingStyles.COMMENT_ID);
} else if (target instanceof BDef) {
accoptor.addPosition(node.getOffset(), node.getLength(), HighlightingStyles.STRING_ID);
}
}
}
}
}
}
https://stackoverflow.com/questions/33348064
复制相似问题