Home » Modeling » TMF (Xtext) » Problems getting ValueConverters to run(ValueConverters will not be called for some reason)
Problems getting ValueConverters to run [message #872538] |
Wed, 16 May 2012 09:46 |
Mikael Karpberg Messages: 8 Registered: April 2012 Location: Sweden |
Junior Member |
|
|
Hi!
I can't seem to get my value converters to be called, at all. I have this simple grammar example that should explain (XText 2, sorry about the ...., but I can't post "links" yet):
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl ".... MyDsl"
import ".... Ecore" as ecore
TestFile:
pairs+=Pair*;
terminal fragment DIGIT: '0'..'9';
terminal fragment HEX_DIGIT: (DIGIT |'a'..'f'|'A'..'F');
terminal fragment ALPHANUM: ('a'..'z'|'A'..'Z'|'_'|DIGIT);
terminal STRING : '"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|'"') )* '"';
terminal CHAR_CONST: "'" ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|"'") )* "'";
terminal ID : ('a'..'z'|'A'..'Z'|'_') ALPHANUM*;
terminal HEXINT: '0' ('x'|'X') HEX_DIGIT+;
terminal OCTINT: '0' ('0'..'7')+;
terminal DOUBLE returns ecore::EDouble: DECINT (('.' DIGIT*) | (('.' DIGIT*)? ('E'|'e') ('-'|'+')? DECINT)); // Use terminal to avoid 'e' turning into a keyword
terminal DECINT: '0' | ('1'..'9' DIGIT*);
terminal INT returns ecore::EInt: 'this is never used, and just overrides the built in INT';
Pair:
name=ID '=' value=Value;
Value:
AnyIntegerLiteral | DoubleLiteral | STRING | CHAR_CONST;
DoubleLiteral returns ecore::EDouble hidden():
// DECINT (('.' (DECINT | OCTINT)*) | (('.' (DECINT | OCTINT)*)? ('E'|'e') ('-'|'+')? DECINT));
DOUBLE;
AnyIntegerLiteral returns ecore::EInt:
HEXINT | OCTINT | DECINT;
The Runtime module contains:
public class MyDslRuntimeModule extends org.xtext.example.mydsl.AbstractMyDslRuntimeModule {
@Override
public Class<? extends IValueConverterService> bindIValueConverterService() {
return CommonValueConverter.class;
}
}
And then I have a CommonValueConverter.java with:
package org.xtext.example.mydsl;
import org.eclipse.xtext.common.services.DefaultTerminalConverters;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverter;
import org.eclipse.xtext.conversion.ValueConverterException;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.util.Strings;
public class CommonValueConverter extends DefaultTerminalConverters {
private IValueConverter<Integer> intValueConverter = new IValueConverter<Integer>() {
@Override
public Integer toValue(String string, INode node) throws ValueConverterException {
if (Strings.isEmpty(string)) {
throw new ValueConverterException("Couldn't convert empty string to int", node, null);
}
int radix = 10;
if (radix < 20)
throw new ValueConverterException("uh oh" + string, node, null);
if (string.startsWith("0x")) {
radix = 16;
string = string.substring(2);
} else if (string.startsWith("0")) {
radix = 8;
string = string.substring(1);
}
try {
return Integer.parseInt(string, radix);
} catch (NumberFormatException e) {
throw new ValueConverterException("'"+string+"' is not a valid integer", node, e);
}
}
@Override
public String toString(Integer value) throws ValueConverterException {
return Integer.toString(value);
}
};
@ValueConverter(rule = "AnyIntegerLiteral")
public IValueConverter<Integer> AnyIntegerLiteral() {
return intValueConverter;
}
}
As you can see, this should always throw an exception at the moment, since I wanted to test that it was called, and see that I got an error message. It's not called.
I can't figure out why it's not called, the documentation is incomplete, and all examples and documentation vary in interfaces and completeness. Nothing I tried worked, though.
Can anyone help me figure this out, please?
Regards,
/Mikael
PS.
This value converter seems unnecessary in this example as it seems to accept hex numbers without problem for some reason, but in the code I cut it from, I just get "For Input: 0x15" errors on hex numbers, so I figured that I needed a value converter. Either way I can't get the value converter called in my big project nor in this example.
|
|
|
Re: Problems getting ValueConverters to run [message #872549 is a reply to message #872538] |
Wed, 16 May 2012 10:08 |
Sebastian Zarnekow Messages: 3118 Registered: July 2009 |
Senior Member |
|
|
Mikael,
value converters will not be called for rules that are used from within
data types rules. This would make it rather impossible to implement
something a converter for rules like:
Date: INT '/' INT '/' INT;
You have to register your impl for the rule Value, too.
Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Am 16.05.12 11:46, schrieb Mikael Karpberg:
> Hi!
>
> I can't seem to get my value converters to be called, at all. I have
> this simple grammar example that should explain (XText 2, sorry about
> the ...., but I can't post "links" yet):
>
>
> grammar org.xtext.example.mydsl.MyDsl with
> org.eclipse.xtext.common.Terminals
>
> generate myDsl ".... MyDsl"
>
> import ".... Ecore" as ecore
>
> TestFile:
> pairs+=Pair*;
>
> terminal fragment DIGIT: '0'..'9';
> terminal fragment HEX_DIGIT: (DIGIT |'a'..'f'|'A'..'F');
> terminal fragment ALPHANUM: ('a'..'z'|'A'..'Z'|'_'|DIGIT);
>
> terminal STRING : '"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') |
> !('\\'|'"') )* '"';
> terminal CHAR_CONST: "'" ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') |
> !('\\'|"'") )* "'";
>
> terminal ID : ('a'..'z'|'A'..'Z'|'_') ALPHANUM*;
> terminal HEXINT: '0' ('x'|'X') HEX_DIGIT+;
> terminal OCTINT: '0' ('0'..'7')+;
> terminal DOUBLE returns ecore::EDouble: DECINT (('.' DIGIT*) | (('.'
> DIGIT*)? ('E'|'e') ('-'|'+')? DECINT)); // Use terminal to avoid 'e'
> turning into a keyword
> terminal DECINT: '0' | ('1'..'9' DIGIT*);
>
> terminal INT returns ecore::EInt: 'this is never used, and just
> overrides the built in INT';
>
> Pair:
> name=ID '=' value=Value;
> Value:
> AnyIntegerLiteral | DoubleLiteral | STRING | CHAR_CONST;
> DoubleLiteral returns ecore::EDouble hidden():
> // DECINT (('.' (DECINT | OCTINT)*) | (('.' (DECINT | OCTINT)*)?
> ('E'|'e') ('-'|'+')? DECINT));
> DOUBLE;
>
> AnyIntegerLiteral returns ecore::EInt:
> HEXINT | OCTINT | DECINT;
>
>
>
> The Runtime module contains:
>
> public class MyDslRuntimeModule extends
> org.xtext.example.mydsl.AbstractMyDslRuntimeModule {
> @Override
> public Class<? extends IValueConverterService>
> bindIValueConverterService() {
> return CommonValueConverter.class;
> }
> }
>
>
> And then I have a CommonValueConverter.java with:
>
> package org.xtext.example.mydsl;
>
> import org.eclipse.xtext.common.services.DefaultTerminalConverters;
> import org.eclipse.xtext.conversion.IValueConverter;
> import org.eclipse.xtext.conversion.ValueConverter;
> import org.eclipse.xtext.conversion.ValueConverterException;
> import org.eclipse.xtext.nodemodel.INode;
> import org.eclipse.xtext.util.Strings;
>
> public class CommonValueConverter extends DefaultTerminalConverters {
> private IValueConverter<Integer> intValueConverter = new
> IValueConverter<Integer>() {
> @Override
> public Integer toValue(String string, INode node) throws
> ValueConverterException {
> if (Strings.isEmpty(string)) {
> throw new ValueConverterException("Couldn't convert empty string to
> int", node, null);
> }
> int radix = 10;
> if (radix < 20)
> throw new ValueConverterException("uh oh" + string, node, null);
> if (string.startsWith("0x")) {
> radix = 16;
> string = string.substring(2);
> } else if (string.startsWith("0")) {
> radix = 8;
> string = string.substring(1);
> }
> try {
> return Integer.parseInt(string, radix);
> } catch (NumberFormatException e) {
> throw new ValueConverterException("'"+string+"' is not a valid integer",
> node, e);
> }
> }
> @Override
> public String toString(Integer value) throws ValueConverterException {
> return Integer.toString(value);
> }
> };
>
> @ValueConverter(rule = "AnyIntegerLiteral")
> public IValueConverter<Integer> AnyIntegerLiteral() {
> return intValueConverter;
> }
> }
>
>
> As you can see, this should always throw an exception at the moment,
> since I wanted to test that it was called, and see that I got an error
> message. It's not called. :(
>
> I can't figure out why it's not called, the documentation is incomplete,
> and all examples and documentation vary in interfaces and completeness.
> Nothing I tried worked, though.
>
> Can anyone help me figure this out, please?
>
> Regards,
> /Mikael
>
> PS.
> This value converter seems unnecessary in this example as it seems to
> accept hex numbers without problem for some reason, but in the code I
> cut it from, I just get "For Input: 0x15" errors on hex numbers, so I
> figured that I needed a value converter. Either way I can't get the
> value converter called in my big project nor in this example.
>
>
|
|
|
Re: Problems getting ValueConverters to run [message #874655 is a reply to message #872549] |
Mon, 21 May 2012 10:19 |
Mikael Karpberg Messages: 8 Registered: April 2012 Location: Sweden |
Junior Member |
|
|
Hi Sebastian!
Thanks for your help, but I'm still confused...
Value converters are not run for Terminals, you mean? I can't quite figure
out what you mean. The date example you gave should not make it hard to
implement a value converter for a date, if you put it on your DataType Rule
called "Date"? In my example "AnyIntegerLiteral" is also a DataType Rule, so
that should be fine, I would think? "Value" is a much too varied type for
my value converter to handle.
Any chance of a bit of clarification?
Also, looking at something like this page, it should be possible to have
value converters for Terminals also?
[Can't post URLs yet]
wiki.eclipse.org/Xtext/Documentation/ValueConverter
Regards,
Mikael
Sebastian Zarnekow wrote on Wed, 16 May 2012 12:08Mikael,
value converters will not be called for rules that are used from within
data types rules. This would make it rather impossible to implement
something a converter for rules like:
Date: INT '/' INT '/' INT;
You have to register your impl for the rule Value, too.
Regards,
Sebastian
Am 16.05.12 11:46, schrieb Mikael Karpberg:
> Hi!
>
> I can't seem to get my value converters to be called, at all. I have
> this simple grammar example that should explain (XText 2, sorry about
> the ...., but I can't post "links" yet):
......
>
|
|
| | | | |
Re: Problems getting ValueConverters to run [message #889689 is a reply to message #874719] |
Tue, 19 June 2012 13:34 |
Mikael Karpberg Messages: 8 Registered: April 2012 Location: Sweden |
Junior Member |
|
|
Wanted to put a note down on another thing I stumbled on.
The problem i found with both ValueConverters and other things like LabelProvider and OutlineTreeProvider was to a large degree because of my structure. I used a common language and built two languages on top of that, and I had to change the common providers and converters as expected. However, all the languages built on top of that must then inherit from the common instead of from the default to get all the common functionality (and then sometimes extend that a bit).
So, for example... my CommonLabelProvider inherits from DefaultEObjectLabelProvider, as per default:
public class CommonLabelProvider extends DefaultEObjectLabelProvider {
@Inject
public CommonLabelProvider(AdapterFactoryLabelProvider delegate) {
super(delegate);
}
public String image(Variable var) {
return "Variable.png";
}
}
However, my other two languages, X and Y has to inherit from that instead of the default:
public class XLabelProvider extends CommonLabelProvider {
@Inject
public AsmLabelProvider(AdapterFactoryLabelProvider delegate) {
super(delegate);
}
}
and:
public class YLabelProvider extends CommonLabelProvider {
@Inject
public AsmLabelProvider(AdapterFactoryLabelProvider delegate) {
super(delegate);
}
public String image(YSpecial spec) {
return "Y.png";
}
}
It seems obvious in hindsight, but when I first fought with it, it wasn't.
Also, when it comes to images, you have to copy the icons between all language projects, since the path will be different when the inherited method is called as part of an inheriting class.
|
|
|
Goto Forum:
Current Time: Thu Apr 25 21:47:57 GMT 2024
Powered by FUDForum. Page generated in 0.03018 seconds
|