Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » [Acceleo] init rules don't work
[Acceleo] init rules don't work [message #64234] Sun, 12 July 2009 20:23 Go to next message
Alexis Muller is currently offline Alexis Muller
Messages: 13
Registered: July 2009
Junior Member
Hi,

I am trying to use the new MOF2Text Acceleo implementation.

Using the init section either in the [template] or [for] rule make
acceleo script stop working.

Sample :
[template public essai(pa : Package) {count : Integer;}]

Can you help me to use this feature ?

I need something like <%i()%> in the previous Acceleo version.

Regards,
Re: [Acceleo] init rules don't work [message #64257 is a reply to message #64234] Mon, 13 July 2009 07:41 Go to previous messageGo to next message
Robert Walter is currently offline Robert Walter
Messages: 11
Registered: July 2009
Junior Member
Hi Alexis,

I'm new to Acceleo, but as I tested it right now, I think you need to
assign a value to your counter, like:

[template public essai(pa : Package) {count : Integer = 0;}]

I hope that helps!
Best wishes,
Robert
Re: [Acceleo] init rules don't work [message #64348 is a reply to message #64257] Mon, 13 July 2009 14:30 Go to previous messageGo to next message
Alexis Muller is currently offline Alexis Muller
Messages: 13
Registered: July 2009
Junior Member
On Mon, 13 Jul 2009 07:41:50 +0000, Robert Walter wrote:
> I'm new to Acceleo, but as I tested it right now, I think you need to
> assign a value to your counter, like:
>
> [template public essai(pa : Package) {count : Integer = 0;}]

Thanks Robert for testing,

this is syntactically correct but don't work.

I hope someone from acceleo can help on this.
Please find here a full script that must work :

[module essai('http://www.eclipse.org/uml2/2.1.0/UML')/]

[template public essai(c : Class) {counter : Integer = 1;}]
[file (c.name, false)]
start [name/]
[for (p : Property | c.ownedAttribute) {counter : Integer = counter + 1;}]
[p.name/]_[counter/]
[/for]
end [name/]
[/file]
[/template]

The [for] is not executed with this error in eclipse log :
org.eclipse.acceleo.engine.AcceleoEvaluationException: Undefined variable
counter : Integer = counter.+(1) for init section at position 195 in
Module essai for block for (c.ownedAttribute) {counter : Integer =
counter.+(1)}.

I have also try with :
[for (p : Property | c.ownedAttribute) {counter = counter + 1;}]

How to get the loop iteration number ?

Regards,

Alexis
Re: [Acceleo] init rules don't work [message #64393 is a reply to message #64348] Tue, 14 July 2009 08:06 Go to previous messageGo to next message
Robert Walter is currently offline Robert Walter
Messages: 11
Registered: July 2009
Junior Member
Hi Alexis,

I might have found a "not so beautiful" workaround. Actually, I haven't
found anything like an assignment operator, but according to the OMG
specification, I think your example should work. Try it like this, and it
does work:

[template public TEST(d : Database) {counter : Integer = 0;} ]
[file (d.name.concat('.txt'), false)]
start [name/]
[for (t : Table | d.tables) ]
[let counter : Integer = counter+1]
[t.name/]_[counter/]
[/let]
[/for]
end [name/]
[/file]
[/template]

Brrrr... this is ugly, so I'm also really looking forward to hear from a
Acceleo Pro!

Bob
Re: [Acceleo] init rules don't work [message #64414 is a reply to message #64393] Tue, 14 July 2009 09:08 Go to previous messageGo to next message
Alexis Muller is currently offline Alexis Muller
Messages: 13
Registered: July 2009
Junior Member
Hi Robert,

On Tue, 14 Jul 2009 08:06:50 +0000, Robert Walter wrote:
> I might have found a "not so beautiful" workaround.
[...]
> Try it like this, and it does work:
>
> [template public TEST(d : Database) {counter : Integer = 0;} ] [file
> (d.name.concat('.txt'), false)] start [name/]
> [for (t : Table | d.tables) ]
> [let counter : Integer = counter+1]
> [t.name/]_[counter/]
> [/let]
> [/for]
> end [name/]
> [/file]
> [/template]

Unfortunately it does not work :( It don't "like" counter + 1, I dont
know why...

But I have found another workaround :

[query next(i : Integer) : Integer = self + 1/]

[template public essai(c : Class) {counter : Integer = 0;}]
[file (c.name, false)]
start [name/]
[for (p : Property | c.ownedAttribute)]
[let counter : Integer = next (counter)]
[p.name/]_[counter/]
[/let]
[/for]
end [name/]
[/file]
[/template]

This is very ugly, but it works.
I hope this will be corrected in a future release.

Many thanks for your help !
regards,

Alexis
Re: [Acceleo] init rules don't work [message #64554 is a reply to message #64414] Wed, 15 July 2009 12:38 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent Goubet
Messages: 1625
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------080704070109040705060505
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

Hi Alexis, Robert,

There's been a number of things here. First of all, "init" sections are
used to create _new_ variables; and variables declared in the init
section of a for have a really limited scope : they'll only live for a
single iteration. What this mean is :

----------8<----------
[template public test(c : EClass) {counter : Integer = 0;}]
[file ('src-gen/counter.txt', false)]
[for (sf : EStructuralFeature | c.eStructuralFeatures) {counter =
counter + 1;}]
[counter/]
[/for]
[/file]
[/template]
---------->8----------

will produce a file "counter.txt" with a number of "1" equal to the
number of features the class contains (the general "counter" has never
been incremented, we only created a number of short-lived variables).

----------8<----------
[template public test(c : EClass) {counter : Integer = 0;}]
[file ('src-gen/counter.txt', false)]
[for (sf : EStructuralFeature | c.eStructuralFeatures)]
[let counter : Integer = counter + 1]
[counter/]
[/let]
[/for]
[/file]
[/template]
---------->8----------

Produces the desired output as the MTL "let" is only an instanceof on
the result of the init expression and has here the side effect of
incrementing the general variable since the "let" variable has the same
name.

As a matter of fact, I don't think OCL has assignment operators. "=" is
a boolean operator equivalent to Java's "==". You only assign values to
a variable at their initialisation time. Thus creating a "counter"
variable that counts the number of iterations of a for would be :

----------8<----------
[template public test(c : EClass)]
[file ('src-gen/counter.txt', false)]
[for (sf : EStructuralFeature | c.eStructuralFeatures) {counter :
Integer = c.eStructuralFeatures->indexOf(sf);}]
[counter/]
[/for]
[/file]
[/template]
---------->8----------
(Note that this particular example fails at runtime ... and that is a
bug :p)

Alternately, you can achieve the very same result without any variable :

----------8<----------
[template public test(c : EClass)]
[file ('src-gen/counter.txt', false)]
[for (sf : EStructuralFeature | c.eStructuralFeatures)]
[c.eStructuralFeatures->indexOf(sf)/]
[/for]
[/file]
[/template]
---------->8----------

All of these examples (except for the third) compile and run as intended
with Acceleo 0.8 in Galileo (OCL 1.3).

Hope this helps,

Laurent Goubet
Obeo

Alexis Muller a écrit :
> Hi Robert,
>
> On Tue, 14 Jul 2009 08:06:50 +0000, Robert Walter wrote:
>> I might have found a "not so beautiful" workaround.
> [...]
>> Try it like this, and it does work:
>>
>> [template public TEST(d : Database) {counter : Integer = 0;} ] [file
>> (d.name.concat('.txt'), false)] start [name/]
>> [for (t : Table | d.tables) ]
>> [let counter : Integer = counter+1]
>> [t.name/]_[counter/]
>> [/let]
>> [/for]
>> end [name/]
>> [/file]
>> [/template]
>
> Unfortunately it does not work :( It don't "like" counter + 1, I dont
> know why...
>
> But I have found another workaround :
>
> [query next(i : Integer) : Integer = self + 1/]
>
> [template public essai(c : Class) {counter : Integer = 0;}]
> [file (c.name, false)]
> start [name/]
> [for (p : Property | c.ownedAttribute)]
> [let counter : Integer = next (counter)]
> [p.name/]_[counter/]
> [/let]
> [/for]
> end [name/]
> [/file]
> [/template]
>
> This is very ugly, but it works.
> I hope this will be corrected in a future release.
>
> Many thanks for your help !
> regards,
>
> Alexis


--------------080704070109040705060505
Content-Type: text/x-vcard; charset=utf-8;
name="laurent_goubet.vcf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="laurent_goubet.vcf"

YmVnaW46dmNhcmQNCmZuOkxhdXJlbnQgR291YmV0DQpuOkdvdWJldDtMYXVy ZW50DQpvcmc6
PGEgaHJlZj0iaHR0cDovL3d3dy5vYmVvLmZyLyI+T2JlbzwvYT4NCmVtYWls O2ludGVybmV0
OmxhdXJlbnQuZ291YmV0QG9iZW8uZnINCnVybDpodHRwOi8vd3d3Lm9iZW8u ZnINCnZlcnNp
b246Mi4xDQplbmQ6dmNhcmQNCg0K
--------------080704070109040705060505--
Re: [Acceleo] init rules don't work [message #64949 is a reply to message #64554] Sat, 25 July 2009 17:10 Go to previous messageGo to next message
Alexis Muller is currently offline Alexis Muller
Messages: 13
Registered: July 2009
Junior Member
Hi Laurent,

On Wed, 15 Jul 2009 14:38:59 +0200, laurent Goubet wrote:
[...]
> ----------8<----------
> [template public test(c : EClass) {counter : Integer = 0;}]
> [file ('src-gen/counter.txt', false)] [for (sf :
EStructuralFeature |
> c.eStructuralFeatures) {counter =
> counter + 1;}]
> [counter/]
> [/for]
> [/file]
> [/template]
> ---------->8----------
>
> will produce a file "counter.txt" with a number of "1" equal to the
> number of features the class contains (the general "counter" has never
> been incremented, we only created a number of short-lived variables).

This is not what the specification says.
From MOF Model to Text V1.0 example 3 (normative) :

---------->8----------
[template public class_header(c : Class) { int count = -1; } ]
[file (c.name +'.cpp', false)]
[trace(c.id() +'_header')]
// Bit vector #definies
[for(a : Attribute) | c.attribute) { count = count + 1; }]
#define [a.name/]_BIT [count/]
[/for]
....
---------->8----------
Expected output :

#define name_BIT 0
#define dept_BIT 1
#define salary_BIT 2


I assume using 'int' instead of 'Integer' is an error but the expected
behavior defined by the spec is exactly what I need.

Using 'col->indexOf (x)' suppose col is ordered
It works for me with 'col->asOrderedSet()->indexOf(x)'.

Thanks it's better as my workaround.

> All of these examples (except for the third) compile and run as intended
> with Acceleo 0.8 in Galileo (OCL 1.3).

Your first sample do not compile with my version. I get :
"The variable counter = counter + 1 isn't valid"

I have Eclipse 3.5 with Acceleo 2.6.0.200906261352, OCL 1.3

Thanks for your help,
regards

--
Alexis
Re: [Acceleo] init rules don't work [message #65064 is a reply to message #64949] Mon, 27 July 2009 09:40 Go to previous message
Laurent Goubet is currently offline Laurent Goubet
Messages: 1625
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------020004020101080001030604
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

Hi Alexis,

Unfortunately, the specification as a fair number of 'examples' that
simply cannot work as they're either contradicting other parts of the
specification or they contradict the OCL specification. The very example
you've pasted here sports two syntax error (quite a feat for 7 lines
with one being a comment ... which itself sports a spelling error). The
first error being the use of "int" instead of "Integer" as you stated,
the second being a closing parenthesis in the middle of the 'for'
declaration.

If we take into account the definition of init sections at 8.1.4 page
15, "A block can have init section that initializes a set of variables
that can be used in its body.". AFAIU, this means that the declared
variable can only be used in the scope of the block's body; and that's
how it's been implemented (the examples I gave earlier show that). Still
according to this description, _all_ block _could_ have init sections
.... and yet the grammar (8.2) and metamodel (A.4) only define init
sections on "for" and "template"...

All this to say, we implemented the specification as best as we could,
coping with the ambiguities it contains while keeping Acceleo as useable
as can be. Your question still raises an interesting issue : the
specification should provide "non generating" blocks for variable
manipulations. With the specification as it stands, we can declare and
initialize variables ... but we can't alter their initialization values
without relying on side effects such as the "let" block you've shown
earlier.

Laurent Goubet
Obeo


Alexis Muller a écrit :
> Hi Laurent,
>
> On Wed, 15 Jul 2009 14:38:59 +0200, laurent Goubet wrote:
> [...]
>> ----------8<----------
>> [template public test(c : EClass) {counter : Integer = 0;}]
>> [file ('src-gen/counter.txt', false)] [for (sf :
> EStructuralFeature |
>> c.eStructuralFeatures) {counter =
>> counter + 1;}]
>> [counter/]
>> [/for]
>> [/file]
>> [/template]
>> ---------->8----------
>>
>> will produce a file "counter.txt" with a number of "1" equal to the
>> number of features the class contains (the general "counter" has never
>> been incremented, we only created a number of short-lived variables).
>
> This is not what the specification says.
> From MOF Model to Text V1.0 example 3 (normative) :
>
> ---------->8----------
> [template public class_header(c : Class) { int count = -1; } ]
> [file (c.name +'.cpp', false)]
> [trace(c.id() +'_header')]
> // Bit vector #definies
> [for(a : Attribute) | c.attribute) { count = count + 1; }]
> #define [a.name/]_BIT [count/]
> [/for]
> ...
> ---------->8----------
> Expected output :
>
> #define name_BIT 0
> #define dept_BIT 1
> #define salary_BIT 2
>
>
> I assume using 'int' instead of 'Integer' is an error but the expected
> behavior defined by the spec is exactly what I need.
>
> Using 'col->indexOf (x)' suppose col is ordered
> It works for me with 'col->asOrderedSet()->indexOf(x)'.
>
> Thanks it's better as my workaround.
>
>> All of these examples (except for the third) compile and run as intended
>> with Acceleo 0.8 in Galileo (OCL 1.3).
>
> Your first sample do not compile with my version. I get :
> "The variable counter = counter + 1 isn't valid"
>
> I have Eclipse 3.5 with Acceleo 2.6.0.200906261352, OCL 1.3
>
> Thanks for your help,
> regards
>


--------------020004020101080001030604
Content-Type: text/x-vcard; charset=utf-8;
name="laurent_goubet.vcf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="laurent_goubet.vcf"

YmVnaW46dmNhcmQNCmZuOkxhdXJlbnQgR291YmV0DQpuOkdvdWJldDtMYXVy ZW50DQpvcmc6
PGEgaHJlZj0iaHR0cDovL3d3dy5vYmVvLmZyLyI+T2JlbzwvYT4NCmVtYWls O2ludGVybmV0
OmxhdXJlbnQuZ291YmV0QG9iZW8uZnINCnVybDpodHRwOi8vd3d3Lm9iZW8u ZnINCnZlcnNp
b246Mi4xDQplbmQ6dmNhcmQNCg0K
--------------020004020101080001030604--
Previous Topic:[EMF] use annotation in "body" of EOperation
Next Topic:[Acceleo] extending Module
Goto Forum:
  


Current Time: Wed Sep 17 07:31:40 GMT 2014

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

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