文本,文本:在ISemanticHighlightingCalculator中使用语法类
-
14-11-2019 - |
题
听着,我有语法。看看我需要处理的具体部分:
Par:
id=ID | string=STRING | integer=INT;
我想获得的是:
if it's a Par element of type ID then color the background
if it's a Par element of type STRING then set text color
这是我的 语义高亮度计算器
public class GrailSemanticHighlightingCalculator implements ISemanticHighlightingCalculator {
@Override
public void provideHighlightingFor(XtextResource resource, IHighlightedPositionAcceptor acceptor) {
if (resource == null) return;
Iterable<AbstractNode> allNodes = NodeUtil.getAllContents( resource.getParseResult().getRootNode() );
for (AbstractNode node : allNodes) {
System.out.println(node.getGrammarElement().toString());
if (node.getGrammarElement() instanceof Par) {
System.out.println("Il mio par: " + ((Par)node).getId());
acceptor.addPosition(node.getOffset(), node.getLength(), GrailHighlightingConfiguration.ELEMENT_ID);
}
}
}
}
我这样做是写在这里 文件.我在编译时没有收到任何错误。下面是一个示例输出 System.out.println(node.getGrammarElement().toString());
org.eclipse.xtext.impl.RuleCallImpl@165a43b (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@159b3 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@a866a9 (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@f4c9c4 (cardinality: null) (value: ()
org.eclipse.xtext.impl.RuleCallImpl@a82a10 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@618b08 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@1da2b6d (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@591171 (cardinality: null) (value: ,)
org.eclipse.xtext.impl.RuleCallImpl@1882876 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@618b08 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@1da2b6d (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@591171 (cardinality: null) (value: ,)
org.eclipse.xtext.impl.RuleCallImpl@1882876 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@618b08 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@1860e4 (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@ea8847 (cardinality: null) (value: ))
org.eclipse.xtext.impl.RuleCallImpl@812517 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@aa3e9a (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@f42d53 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@cbb612 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.KeywordImpl@1990d96 (cardinality: null) (value: ()
org.eclipse.xtext.impl.RuleCallImpl@1e7f21 (cardinality: null)
org.eclipse.xtext.impl.ActionImpl@2c79a5 (cardinality: null) (feature: left, operator: =)
org.eclipse.xtext.impl.RuleCallImpl@aa3e9a (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@f42d53 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@cbb612 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.KeywordImpl@1990d96 (cardinality: null) (value: ()
org.eclipse.xtext.impl.RuleCallImpl@1e7f21 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@aa3e9a (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@f42d53 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@cbb612 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@1e668c2 (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@1e7a4d0 (cardinality: null) (value: .)
org.eclipse.xtext.impl.RuleCallImpl@f55ff2 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@16e3eb3 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@d67d61 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@1860e4 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.KeywordImpl@14afef4 (cardinality: null) (value: ))
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.KeywordImpl@1c190a2 (cardinality: null) (value: AND)
org.eclipse.xtext.impl.RuleCallImpl@feba21 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.KeywordImpl@16dd645 (cardinality: null) (value: NOT)
org.eclipse.xtext.impl.RuleCallImpl@e54f3 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@1e668c2 (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@1e7a4d0 (cardinality: null) (value: .)
org.eclipse.xtext.impl.RuleCallImpl@f55ff2 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@16e3eb3 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@d67d61 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@eb3f66 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.KeywordImpl@14afef4 (cardinality: null) (value: ))
org.eclipse.xtext.impl.RuleCallImpl@165a43b (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@159b3 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@a866a9 (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@f4c9c4 (cardinality: null) (value: ()
org.eclipse.xtext.impl.RuleCallImpl@a82a10 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@618b08 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@1da2b6d (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@ea8847 (cardinality: null) (value: ))
org.eclipse.xtext.impl.RuleCallImpl@812517 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@aa3e9a (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@f42d53 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@cbb612 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.KeywordImpl@1990d96 (cardinality: null) (value: ()
org.eclipse.xtext.impl.RuleCallImpl@1e7f21 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@aa3e9a (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@f42d53 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@cbb612 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@1e668c2 (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@1e7a4d0 (cardinality: null) (value: .)
org.eclipse.xtext.impl.RuleCallImpl@f55ff2 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@16e3eb3 (cardinality: null)
org.eclipse.xtext.impl.RuleCallImpl@d67d61 (cardinality: null)
org.eclipse.xtext.impl.TerminalRuleImpl@1eed0fb (name: WS)
org.eclipse.xtext.impl.RuleCallImpl@1860e4 (cardinality: null)
org.eclipse.xtext.impl.KeywordImpl@14afef4 (cardinality: null) (value: ))
解决方案
我也只是刚刚开始使用XText,但我可能可以提供帮助。我能够获得语法突出显示工作的一个小项目与您的代码相似,但有一些差异。我发现有用的论坛发帖 在Eclipse论坛上.
基于控制台输出,它看起来像永远不会将任何Abstractnode识别为Par的实例。
Eclipse论坛和你的代码之间的差异似乎是:
- 它使用
Iterator<EObject> iter = EcoreUtil.getAllContents(resource, true);
和一个while
循环遍历结果。 - 它直接检查弹出对象的类型(在你的情况下是Par),而不是使用
getGrammarElement
.
它可能就像上面那样简单,比如:
public class GrailSemanticHighlightingCalculator implements ISemanticHighlightingCalculator {
@Override
public void provideHighlightingFor(XtextResource resource, IHighlightedPositionAcceptor acceptor) {
if (resource == null) return;
Iterator<EObject> iter = EcoreUtil.getAllContents(resource, true);
while (iter.hasNext()) {
EObject current = iter.next();
if (current instanceof Par) {
Par parNode = (Par) current;
if (parNode.getId() != null) {
acceptor.addPosition(node.getOffset(), node.getLength(), GrailHighlightingConfiguration.ELEMENT_ID);
} else if (parNode.getString() != null) {
acceptor.addPosition(node.getOffset(), node.getLength(), GrailHighlightingConfiguration.ELEMENT_STRING);
} else if (parNode.getInt() != null) {
acceptor.addPosition(node.getOffset(), node.getLength(), GrailHighlightingConfiguration.ELEMENT_INT);
}
}
}
}
我已经包含了一些代码来处理其他突出显示选项,因此您需要将ELEMENT_STRING和ELEMENT_INT处理程序添加到您的 configure()
无论调用IHighlightingConfiguration类中的任何方法,都可以返回 TextStyle
适用于他们。
另请注意,我没有测试上述任何一个,所以它实际上可能是完全错误和误导!但希望不是。:)
其他提示
对于Xtext2.0,此代码可以用作模板:
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightedPositionAcceptor;
import org.eclipse.xtext.ui.editor.syntaxcoloring.ISemanticHighlightingCalculator;
public class YourDslSemanticHighlightingCalculator implements ISemanticHighlightingCalculator {
@Override
public void provideHighlightingFor( XtextResource resource, IHighlightedPositionAcceptor acceptor ) {
if( resource == null ) {
return;
}
HighlightingSwitch switcher = new HighlightingSwitch( acceptor );
Iterator<EObject> iter = EcoreUtil.getAllContents(resource, true);
while(iter.hasNext()) {
EObject current = iter.next();
switcher.doSwitch( current );
}
}
private class HighlightingSwitch extends YourDslSwitch<Void> {
private final IHighlightedPositionAcceptor acceptor;
public HighlightingSwitch( IHighlightedPositionAcceptor acceptor ) {
this.acceptor = acceptor;
}
@Override
public Void caseOption( Option object ) {
INode node = getFirstFeatureNode( object, YourDslPackage.eINSTANCE.getOption_Name() );
highlightNode( node, YourDslHighlightingConfiguration.OPTION );
return null;
}
private void highlightNode( INode node, String id ) {
if( node == null )
return;
if( node instanceof ILeafNode ) {
acceptor.addPosition( node.getOffset(), node.getLength(), id );
} else {
for( ILeafNode leaf : node.getLeafNodes() ) {
if( !leaf.isHidden() ) {
acceptor.addPosition( leaf.getOffset(), leaf.getLength(), id );
}
}
}
}
}
public INode getFirstFeatureNode( EObject semantic, EStructuralFeature feature ) {
if( feature == null )
return NodeModelUtils.findActualNodeFor( semantic );
List<INode> nodes = NodeModelUtils.findNodesForFeature( semantic, feature );
if( !nodes.isEmpty() )
return nodes.get( 0 );
return null;
}
}
这将迭代模型中的所有节点,并在 HighlightingSwitch
.
在案例方法中,您需要定位 INode
有关的功能或 EObject
实例,你关心,然后,你可以突出显示它。
请注意 getFirstFeatureNode()
不会在整个AST中搜索节点;实现实际上非常快。
样式配置如下所示:
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultHighlightingConfiguration;
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfigurationAcceptor;
import org.eclipse.xtext.ui.editor.utils.TextStyle;
public class YourDslHighlightingConfiguration extends DefaultHighlightingConfiguration {
public static final String OPTION = "yourDsl.option";
public void configure(IHighlightingConfigurationAcceptor acceptor) {
acceptor.acceptDefaultHighlighting( OPTION, "Option", option() );
super.configure( acceptor );
}
public TextStyle option() {
TextStyle textStyle = defaultTextStyle().copy();
textStyle.setColor( new RGB( 0, 26, 171 ) );
textStyle.setStyle( SWT.ITALIC );
return textStyle;
}
}
不要忘记在UI模块中绑定两个新类!
不隶属于 StackOverflow