0

听着,我有语法。仅查看我需要处理的特定部分:

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);
                }
              }
    }

}

我正在按照文档中的说明执行此操作。我在编译时没有收到任何错误。这是一个示例输出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: ))
4

2 回答 2

2

我也只是刚开始使用 XText,但我可能会提供帮助。我能够为一个与您的代码相似的小项目使用语法突出显示,但有一些不同之处。我在这里的 Eclipse 论坛上找到了有用的论坛张贴。

根据控制台输出,它看起来从未将任何 AbstractNodes 识别为 Par 的实例。

Eclipse 论坛和您的代码之间的区别似乎是:

  • 它使用Iterator<EObject> iter = EcoreUtil.getAllContents(resource, true);一个while循环来遍历结果。
  • 它直接检查 EObject 的类型(在您的情况下为 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);
            }
        }
    }
}

我已经包含了一些代码来处理其他突出显示选项,因此您需要在configure()调用 IHighlightingConfiguration 类时将 ELEMENT_STRING 和 ELEMENT_INT 处理程序添加到您的方法中,以返回TextStyle适用于它们的选项。

另请注意,我没有测试过以上任何内容,因此它实际上可能是完全错误和误导的!但希望不是。:)

于 2011-04-27T06:01:04.180 回答
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.

在 case 方法中,您需要找到与您关心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 模块中绑定两个新类!

于 2012-11-29T14:52:21.297 回答