听着,我有一个语法。只看我需要处理的具体部分:
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
这是我的 SemanticHighlightingCalculator
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);
}
}
}
}
我正在这里写documentation。我在编译时没有收到任何错误。以下是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: ))
答案 0 :(得分:2)
我也刚刚开始使用XText,但我可以提供帮助。我能够为一个与你的代码类似的小项目提供语法高亮,但有一些差异。我找到了有用的论坛on the Eclipse forums here。
基于控制台输出,它似乎永远不会将任何AbstractNodes识别为Par的实例。
Eclipse论坛和您的代码之间的差异似乎是:
Iterator<EObject> iter = EcoreUtil.getAllContents(resource, true);
和while
循环来迭代结果。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);
}
}
}
}
我已经包含了一些代码来处理其他突出显示选项,所以你需要在你的configure()
方法中添加ELEMENT_STRING和ELEMENT_INT处理程序来调用你的IHighlightingConfiguration类,以返回{{ 1}}适用于他们。
另请注意,我没有测试过任何上述内容,因此实际上可能完全错误并具有误导性!但希望不是这样。 :)
答案 1 :(得分:2)
对于Xtext 2.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模块中绑定两个新类!