Home » Modeling » TMF (Xtext) » Xtext Syntax Coloring(Not able to highlight special keywords (API functions))
| | | |
Re: Xtext Syntax Coloring [message #509191 is a reply to message #508580] |
Thu, 21 January 2010 15:56 |
Stefan Jäger Messages: 22 Registered: January 2010 |
Junior Member |
|
|
Sorry for confusing you. I think I now managed to precisely describe what I'd like to achieve.
Subsequent you can find a picture which shows you the syntax coloring I'd like to achieve:
http:// picasaweb.google.de/sjaeger2902/CodeColoring#542922155390390 8498
Basically I'd like to have:
- Comments (e.g. \\, \* *\)
- Keywords (e.g. int, string, void)
- Functions (e.g. abs)
I'm able to define the coloring for the Keywords using single quotes (') in the grammar:
grammar org.xtext.example.Entities with org.eclipse.xtext.common.Terminals
generate entities "http://www.xtext.org/example/Entities"
Model:
(prototypes+=Prototype)* (functions+=Function)*;
SimpleDataType:
('void' | 'string' | 'int' | 'double' | 'TablePtr')+ name=ID;
Prototype:
SimpleDataType '(' ((prototypeDataTypes+=SimpleDataType)* | ',') ')'';';
Function:
SimpleDataType '(' ((functionDataTypes+=SimpleDataType)* | ',') ')'
'{' (lines+=Line)* '}';
Line:
retValue=ID '=' (functionName+=ListOfApiFunctions)* ';';
ListOfApiFunctions:
('abs' |
'ACCT_DefineManualEntry' |
'ACCT_DefineManualEntryR' |
'ACCT_DefinePostingParameter')
('(' ((prototypeDataTypes+=SimpleDataType)* | ',') ')')*;
But how do I manage to get the functionnames in red?
Cheers,
Stefan
[Updated on: Thu, 21 January 2010 16:02] Report message to a moderator
|
|
| |
Re: Xtext Syntax Coloring [message #509286 is a reply to message #509191] |
Thu, 21 January 2010 20:38 |
|
Hello, it may not be easy to get this running, but a starting point could be following classes
package org.xtext.example.syntaxcoloring;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.IHighlightingConfigurationAcceptor;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.ILexicalHighlightingConfiguration;
import org.eclipse.xtext.ui.core.editor.utils.TextStyle;
public class MyDslLexicalHighlightingConfiguration implements ILexicalHighlightingConfiguration {
public static final String ABS_ID = "abs";
public static final String DEFAULT_ID = "default";
public TextStyle keywordTextStyle() {
TextStyle textStyle = new TextStyle();
textStyle.setColor(new RGB(255, 0, 0));
textStyle.setStyle(SWT.BOLD);
return textStyle;
}
public TextStyle defaultTextStyle() {
TextStyle textStyle = new TextStyle();
textStyle.setBackgroundColor(new RGB(255, 255, 255));
textStyle.setColor(new RGB(0, 0, 0));
return textStyle;
}
@Override
public void configure(IHighlightingConfigurationAcceptor acceptor) {
acceptor.acceptDefaultHighlighting(ABS_ID, "abs", keywordTextStyle());
acceptor.acceptDefaultHighlighting(DEFAULT_ID, "default", defaultTextStyle());
}
}
package org.xtext.example.syntaxcoloring;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.AbstractTokenScanner;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.DefaultLexicalHighlightingConfiguration;
public class MyDslTokenScanner extends AbstractTokenScanner {
class MyToken extends Token {
public int getOffset() {
return offset;
}
public int getLength() {
return length;
}
private int offset;
private int length;
public MyToken(Object data, int offset, int length) {
super(data);
this.offset = offset;
this.length = length;
}
}
private List<MyToken> tokens = new ArrayList<MyToken>();
private int current = -1;
@Override
public int getTokenLength() {
return tokens.get(current).getLength();
}
@Override
public int getTokenOffset() {
return tokens.get(current).getOffset();
}
@Override
public IToken nextToken() {
current++;
if (current + 1 >= tokens.size()) {
return Token.EOF;
} else {
MyToken result = tokens.get(current);
return result;
}
}
@Override
public void setRange(IDocument document, int offset, int length) {
tokens.clear();
current = -1;
try {
String s = document.get(offset, length);
String[] data = s.split("abs");
int cos = 0;
for (int i=0; i < data.length; i++) {
MyToken token = new MyToken(getAttribute(DefaultLexicalHighlightingConfiguration.DEFAULT_ID), cos, data[i].length());
cos += data[i].length();
tokens.add(token);
token = new MyToken(getAttribute(MyDslLexicalHighlightingConfiguration.ABS_ID), cos, 3);
cos += 3;
tokens.add(token);
}
} catch (BadLocationException e) {
}
}
}
public class MyDslUiModule extends org.xtext.example.AbstractMyDslUiModule {
@Override
public Class<? extends ITokenScanner> bindITokenScanner() {
return MyDslTokenScanner.class;
}
public Class<? extends ILexicalHighlightingConfiguration> bindILexicalHighlightingConfiguration() {
return MyDslLexicalHighlightingConfiguration.class;
}
}
the disadvantage of using this approach is that you loose the default highlighting you get for free with xtext.
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Xtext Syntax Coloring [message #509358 is a reply to message #508580] |
Fri, 22 January 2010 08:55 |
Stefan Jäger Messages: 22 Registered: January 2010 |
Junior Member |
|
|
Thank you for your suggestions.
The problem is that I do have about 3000 functions such as 'abs'. I've extraced them from the help file. They look as follows:
ACCT_RecastBalanceHistory(int start_date);
int ACCT_RelProcGroupLock();
int ACCT_RemoveOrphanedPPSEntries();
TablePtr ACCT_ReverseFasHistory(int event_id, int underlying_deal_tracking_num, int hedge_deal_tracking_num, int composer_deal_tracking_num, int posting_date, int hedge_type, int start_seq_num, int end_seq_num, int currency);
int ACCT_RunProc(string sp_name, TablePtr arg_table);
int ACCT_SwitchEvent_Criteria(int status);
int ACCT_UpdateFasHistoryProcessFlag(int entry_id, intprocessed_flag);
int ACCT_UpdatePPSEntryTable(TablePtr acct_pps_entries_table);
int ACCT_UpdatePPSSentToGL(int entry_id, int general_int);
freeable TablePtr AFE_CreateServiceRequestArgTable();
int AFE_IssueServiceRequestByID (int service_id, TablePtr arg_table = 0);
...
I guess that it will become quite complicated to model that using LexicalHighlightingConfiguration and TokenScanner.
In an ideal world I'd like to place the functions in a seperate file and mark them to be of type 'functions' which need to be displayed in red and bold. For sure I'd need to reduce above lines to the function name only (without return type and parameter).
Cheers,
Stefan
|
|
| | | |
Re: Xtext Syntax Coloring [message #509788 is a reply to message #509441] |
Mon, 25 January 2010 12:39 |
Stefan Jäger Messages: 22 Registered: January 2010 |
Junior Member |
|
|
Hi Alex.
Thanks a lot for your support.
I think I could do progress on that.
What I've done right now is:
a) to define the MySemanticHighlightingConfiguration:
package org.xtext.example;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.IHighlightingConfigurationAcceptor;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.ISemanticHighlightingConfiguration;
import org.eclipse.xtext.ui.core.editor.utils.TextStyle;
public class MySemanticHighlightingConfiguration implements
ISemanticHighlightingConfiguration {
// provide an id string for the highlighting calculator
public static final String DUMMYHL = "dummyHighlighting";
// configure the acceptor providing the id, the description string
// that will appear in the preference page and the initial text style
public void configure(IHighlightingConfigurationAcceptor acceptor) {
acceptor.acceptDefaultHighlighting(DUMMYHL, "AdditionalDummyType",
dummytype());
}
// method for calculating an actual text styles
public TextStyle dummytype() {
TextStyle textStyle = new TextStyle();
textStyle.setBackgroundColor(new RGB(155, 55, 255));
textStyle.setColor(new RGB(5, 10, 20));
textStyle.setStyle(SWT.ITALIC);
return textStyle;
}
}
b) to bind the configuration and calculator in the UI Module:
/*
* generated by Xtext
*/
package org.xtext.example;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.ISemanticHighlightingCalculator;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.ISemanticHighlightingConfiguration;
/**
* Use this class to register components to be used within the IDE.
*/
public class MyDslUiModule extends org.xtext.example.AbstractMyDslUiModule {
public Class<? extends ISemanticHighlightingCalculator>
bindSemanticHighlightingCalculator() {
return MySemanticHighlightingCalculator.class;
}
public Class<? extends ISemanticHighlightingConfiguration>
bindSemanticConfig() {
return MySemanticHighlightingConfiguration.class;
}
}
c) to define the MySemanticHighlightingCalculator (not completely right):
package org.xtext.example;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.XtextPackage.Literals;
import org.eclipse.xtext.parsetree.AbstractNode;
import org.eclipse.xtext.parsetree.CompositeNode;
import org.eclipse.xtext.parsetree.LeafNode;
import org.eclipse.xtext.parsetree.NodeAdapter;
import org.eclipse.xtext.parsetree.NodeUtil;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.IHighlightedPositionAcceptor;
import org.eclipse.xtext.ui.common.editor.syntaxcoloring.ISemanticHighlightingCalculator;
import org.xtext.example.myDsl.Function;
import org.xtext.example.myDsl.Model;
public class MySemanticHighlightingCalculator implements
ISemanticHighlightingCalculator {
// helper method that takes care of highlighting the first feature element
// of a semantic object using a given text style ID
private void highlightFirstFeature(EObject semobject, String featurename,
String highlightID, IHighlightedPositionAcceptor acceptor) {
// fetch the parse node for the entity
LeafNode nodetohighlight = getFirstFeatureNode(semobject, featurename);
acceptor.addPosition(nodetohighlight.getOffset(), nodetohighlight
.getLength(), highlightID);
}
// adapted from Sebastian Zarnekow's semantic highlighting implementation
// navigate to the parse node corresponding to the semantic object and
// fetch the leaf node that corresponds to the first feature with the given
// name
public LeafNode getFirstFeatureNode(EObject semantic, String feature) {
NodeAdapter adapter = NodeUtil.getNodeAdapter(semantic);
if (adapter != null) {
CompositeNode node = adapter.getParserNode();
if (node != null) {
if (feature == null)
return null;
for (AbstractNode child : node.getChildren()) {
if (child instanceof LeafNode) {
if (feature.equals(((LeafNode) child).getFeature())) {
return (LeafNode) child;
}
}
}
}
}
return null;
}
public void provideHighlightingFor(XtextResource resource,
IHighlightedPositionAcceptor acceptor) {
Model m = (Model) resource.getContents().get(0);
// fetch functions
List modelfunctions = m.getFunctions();
List classes = EcoreUtil2.typeSelect(modelfunctions,
Function.class);
for (Function functionName :
EcoreUtil2.typeSelect(modelfunctions, Function.class)) {
highlightFirstFeature(functionName,
Literals.TYPE_REF.getName(),
MySemanticHighlightingConfiguration.DUMMYHL, acceptor);
}
}
}
Unfortunately I receive an error msg when testing the editor:
java.lang.NullPointerException
at org.xtext.example.MySemanticHighlightingCalculator.highlightFirstFeature(MySemanticHighlightingCalculator.java:28)
at org.xtext.example.MySemanticHighlightingCalculator.provideHighlightingFor(MySemanticHighlightingCalculator.java:80)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.MergingHighlightedPositionAcceptor.provideHighlightingFor(MergingHighlightedPositionAcceptor.java:46)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.HighlightingReconciler.reconcilePositions(HighlightingReconciler.java:87)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.HighlightingReconciler.modelChanged(HighlightingReconciler.java:275)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.HighlightingReconciler$1.process(HighlightingReconciler.java:246)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.HighlightingReconciler$1.process(HighlightingReconciler.java:1)
at org.eclipse.xtext.util.concurrent.IUnitOfWork$Void.exec(IUnitOfWork.java:36)
at org.eclipse.xtext.util.concurrent.IStateAccess$AbstractImpl.readOnly(IStateAccess.java:40)
at org.eclipse.xtext.ui.core.editor.model.XtextDocument.readOnly(XtextDocument.java:64)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.HighlightingReconciler.refresh(HighlightingReconciler.java:243)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.HighlightingReconciler.install(HighlightingReconciler.java:197)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.HighlightingHelper.enable(HighlightingHelper.java:76)
at org.eclipse.xtext.ui.common.editor.syntaxcoloring.HighlightingHelper.install(HighlightingHelper.java:64)
at org.eclipse.xtext.ui.core.editor.XtextEditor.installHighlightingHelper(XtextEditor.java:324)
at org.eclipse.xtext.ui.core.editor.XtextEditor.createPartControl(XtextEditor.java:301)
at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:662)
at org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:462)
at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
at org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
at org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1429)
at org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:942)
at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3906)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3527)
at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
at org.eclipse.ui.internal.Workbench$28.runWithException(Workbench.java:1384)
at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3906)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3527)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2315)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2220)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:367)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:611)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:566)
at org.eclipse.equinox.launcher.Main.run(Main.java:1363)
at org.eclipse.equinox.launcher.Main.main(Main.java:1339)
I think there is only a little change needed in the calculator to get it up and running.
Here's my grammar for the moment:
grammar org.xtext.example.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/MyDsl"
Model:
(functions+=Function)*;
Function:
returnType=ReturnType functionName=ID
'('(paramaters+=Parameter (',' parameters+=Parameter)*)?')'';';
ReturnType:
'void' | 'string' | 'TablePtr';
Parameter:
returnType=ReturnType name=ID;
I guess that I haven't done the follow right:
Quote: |
Then you adapt provideHighlightingFor in such a way
that you fetch all Functions-objects from the model (that is, those
types that have the "name" feature that is to be highlighted).
|
|
|
|
Re: Xtext Syntax Coloring [message #509805 is a reply to message #509788] |
Mon, 25 January 2010 13:25 |
Alexander Nittka Messages: 1193 Registered: July 2009 |
Senior Member |
|
|
Hi,
the method highlightFirstFeature should actually first test whether
nodetohighlight is not null before doing anything with it (bug in the
blog). This will be the cause of the NPE.
> highlightFirstFeature(functionName,
> Literals.TYPE_REF.getName(),
> MySemanticHighlightingConfiguration.DUMMYHL, acceptor);
Literals.TYPE_REF.getName() puzzles me. Did you try simply using
"functionName" here? Because that is the name of the feature you want to
highlight.
Otherwise it should rather look like
<MyDsl>Package.Literals.FUNCTION__FUNCTIONNAME.getName();
> List modelfunctions = m.getFunctions();
> List classes = EcoreUtil2.typeSelect(modelfunctions,
> Function.class);
Also modelfunctions should already be a List of functions, so the
typeSelect is not necessary.
List<Function> modelfunctions = m.getFunctions();
for (Function f : modelfunctions){
highlightFirstFeature(f,"functionName",
MySemanticHighlightingConfiguration.DUMMYHL, acceptor);
}
should be fine (untested).
Alex
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext@itemis.de
|
|
| |
Goto Forum:
Current Time: Sat Apr 27 02:53:01 GMT 2024
Powered by FUDForum. Page generated in 0.04579 seconds
|