Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Serialization Issue with Mathematical Expression(When serializing EObjects more the wrong rule is taken from my grammar)
Serialization Issue with Mathematical Expression [message #1273046] Wed, 19 March 2014 11:49 Go to next message
Marcus Höpfner is currently offline Marcus HöpfnerFriend
Messages: 56
Registered: February 2014
Member
Hello,

I have a grammar for mathematical expressions (formula) generated from my Ecore model.
When serializing a certain expression from EObject it uses the wrong ParserRule which results in a wrong formula string.

I cutted it down to what is relevant.

Here is the grammar:
grammar org.xtext.example.math.Math with org.eclipse.xtext.common.Terminals

import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate math "http://www.eclipse.org/example/math/Math"

FormulaDefinition returns FormulaDefinition:
	{FormulaDefinition}
	formulaToken=FormulaToken?;

FormulaToken returns FormulaToken:
	Prio1Operation;

Prio1Operation returns FormulaToken: // like +
	InfixOperand ({FormulaOperator.childToken+=current} code=InfixOperatorPrio1
	childToken+=InfixOperand)*;

InfixOperand returns FormulaToken:
	'(' FormulaToken ')' | FormulaConstant | PrefixOperation2Operands;

PrefixOperation2Operands returns FormulaOperator:
	code=PrefixOperator2Operands '(' childToken+=FormulaToken ',' childToken+=FormulaToken ')';

InfixOperatorPrio1 returns ecore::EString:
	('+');
	
PrefixOperator2Operands returns ecore::EString:
	'MAX';	
	
FormulaConstant returns FormulaConstant:
	value=INT;


Here is the test which fails:
	@Test
	def void testTwoArgPrefixOperation() {
		val op = MathFactory.eINSTANCE.createFormulaOperator
		op.code = 'MAX'
		var arg1 = MathFactory.eINSTANCE.createFormulaConstant
		arg1.value = 5
		op.childToken += arg1
		var arg2 = MathFactory.eINSTANCE.createFormulaConstant
		arg2.value = 8
		op.childToken += arg2
		
		var formulaDef = MathFactory.eINSTANCE.createFormulaDefinition()
		formulaDef.formulaToken = op
		
		val formula = serializer.serialize(formulaDef)
		
		assertEquals("MAX ( 5 , 8 )", formula)
	}

The serializer returns
5 MAX 8
instead of expected
MAX ( 5, 8 )


Xtext is assuming an Prio1Operation instead of PrefixOperator2Operands.

BTW: I formula expressing 5 + 8 is working as expected!

I was already able to solve by either
1.) Create new EMF-Objects which inherit from FormulaOperator. These would be FormulaOperatorInfix and FormulaOperatorPrefix and adapt the test accordingly.
grammar org.xtext.example.math.Math with org.eclipse.xtext.common.Terminals

import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate math "http://www.eclipse.org/example/math/Math"

FormulaDefinition returns FormulaDefinition:
	{FormulaDefinition}
	formulaToken=FormulaToken?;

FormulaToken returns FormulaToken:
	Prio1Operation;

Prio1Operation returns FormulaToken: // like +
	InfixOperand ({FormulaOperatorInfix.childToken+=current} code=InfixOperatorPrio1
	childToken+=InfixOperand)*;

InfixOperand returns FormulaToken:
	'(' FormulaToken ')' | FormulaConstant | PrefixOperation2Operands;

PrefixOperation2Operands returns FormulaOperatorPrefix:
	code=PrefixOperator2Operands '(' childToken+=FormulaToken ',' childToken+=FormulaToken ')';

InfixOperatorPrio1 returns ecore::EString:
	('+');
	
PrefixOperator2Operands returns ecore::EString:
	'MAX';	
	
FormulaConstant returns FormulaConstant:
	value=INT;

2.) Instead of pointing to rule InfixOperatorPrio1 and PrefixOperator2Operands use the strings directly in Prio1Operation and PrefixOperation2Operands in respect. So the grammar would look like this
grammar org.xtext.example.math.Math with org.eclipse.xtext.common.Terminals

import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate math "http://www.eclipse.org/example/math/Math"

FormulaDefinition returns FormulaDefinition:
	{FormulaDefinition}
	formulaToken=FormulaToken?;

FormulaToken returns FormulaToken:
	Prio1Operation;

Prio1Operation returns FormulaToken: // like +
	InfixOperand ({FormulaOperator.childToken+=current} code=('+')
	childToken+=InfixOperand)*;

InfixOperand returns FormulaToken:
	'(' FormulaToken ')' | FormulaConstant | PrefixOperation2Operands;

PrefixOperation2Operands returns FormulaOperator:
	code='MAX' '(' childToken+=FormulaToken ',' childToken+=FormulaToken ')';


FormulaConstant returns FormulaConstant:
	value=INT;


But actally option 1.) I don't want to go.
For option 2.) I wonder why I need to do that. It decreases usability and reuse. I though that there is no difference whether I write a String directly or reference a parser rule (which indeed returns a unique return).

Is there any other solution or way I can force Xtext to kind of "follow" the rules containing the operators.

Thanks, Marcus
Re: Serialization Issue with Mathematical Expression [message #1287141 is a reply to message #1273046] Mon, 07 April 2014 12:57 Go to previous messageGo to next message
Pawel Pogorzelski is currently offline Pawel PogorzelskiFriend
Messages: 40
Registered: July 2009
Member
Marcus,
try looking here:

ISequenceAcceptor.acceptAssignedDatatype


Maybe these two require modifications as well:

ElementMatcherProvider.getAllStates
ElementMatcherProvider.matchNext


Cheers,
Paweł

Re: Serialization Issue with Mathematical Expression [message #1287153 is a reply to message #1287141] Mon, 07 April 2014 13:13 Go to previous message
Pawel Pogorzelski is currently offline Pawel PogorzelskiFriend
Messages: 40
Registered: July 2009
Member
Marcus,
one more thing. In general flattering your model with:

InfixOperatorPrio1 returns ecore::EString:
	('+');


is not the best idea. It creates more problems than solves. And the three pointers I gave you in the previous reply might not the only code that requires modifications. In this case I'd simply use a dedicated type for the operator.
Previous Topic:Importing implicit global scope
Next Topic:XtextCON
Goto Forum:
  


Current Time: Thu Apr 25 04:06:05 GMT 2024

Powered by FUDForum. Page generated in 0.02395 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top