Home » Modeling » M2T (model-to-text transformation) » [Acceleo] init rules don't work
| | | |
Re: [Acceleo] init rules don't work [message #64414 is a reply to message #64393] |
Tue, 14 July 2009 09:08 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Alexis Muller![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=Alexis.Muller%40inria.fr) 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 message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
|
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 #65064 is a reply to message #64949] |
Mon, 27 July 2009 09:40 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
|
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--
|
|
|
Goto Forum:
Current Time: Sun Sep 01 00:51:43 GMT 2024
Powered by FUDForum. Page generated in 0.04050 seconds
|