2015-07-31 3 views
0

Я тестирую Acceleo для проекта генерации кода исходного кода. В этом языке углубление очень важно.Acceleo. Стратегии отступа

Я нашел руководство по indent strategies, но, я думаю, устарел, потому что он имеет ссылки на indentSpace и indentTab, и я не нашел этих инструкций в версии Acceleo 3.5.

Я думал использовать последовательность var для хранения отступов, но очень сложно передать этот var во все шаблоны.

Вы знаете лучшую стратегию для отступов ?, любую ссылку?

ответ

0

Обработка новых линий, отступов и пробелов может быть сложной иногда в Акчелео. Вы можете просмотреть эту страницу: http://help.eclipse.org/juno/topic/org.eclipse.acceleo.doc/pages/reference/textproductionrules.html, она представляет собой текстовые правила.

Кроме того, поскольку Acceleo является воплощением стандарта MOFM2T (стандарт OMG). Существует также дополнительная информация в самой спецификации: http://www.omg.org/spec/MOFM2T/1.0/PDF/

Как быстрый ответ, шаблон вызывает «помнить» отступ, используемый при его вызове.

Вот пример:

[template public generate(c : Class)] 
[comment @main/] 
[file (c.name, false, 'UTF-8')] 
Class [c.name/] 
    [c.ownedAttribute.gen()/] [comment using implicit iterator/] 
[/file] 
[/template] 

[template public gen(p : Property)] 
name=[p.name/], type=[p.type.name/] 
            [comment notice the new line/] 
[/template] 

И тот же самый, но с использованием for вместо неявного итератора:

[template public generate(c : Class)] 
[comment @main/] 
[file (c.name, false, 'UTF-8')] 
Class [c.name/] 
    [for (p : Property | c.ownedAttribute)] 
    [p.gen()/] 
    [/for] 
[/file] 
[/template] 

[template public gen(p : Property)] 
name=[p.name/], type=[p.type.name/] [comment no more new line/] 
[/template] 

здесь полученный выход (в обоих случаях):

Class MyClass 
    name=attribute, type=MyInterface 
    name=attribute2, type=Boolean 
    name=attribute3, type=Char 

EDIT> Относительно вашего нового вопроса a bout indentation (на следующий ответ этой темы). Вы можете легко управлять отступом как частью шаблона, но обычно вам нужно избегать нахождения общего шаблона любой ценой в противном случае, это часто приводит к сложному сценарию для чтения и обслуживания.

Вот небольшой пример, по-прежнему использующий UML в качестве входной метамодели с использованием рекурсивных шаблонов.

вход test.uml

<uml:Model xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:uml="http://www.eclipse.org/uml2/4.0.0/UML" xmi:version="2.0" xmi:id="_wfUKcIkNEeWSIKoWblTvZg" name="HelloModel"> 
    <packageImport xmi:id="_wfUKc4kNEeWSIKoWblTvZg"> 
    <importedPackage href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#/"/> 
    </packageImport> 
    <packageImport xmi:id="_wfUKdokNEeWSIKoWblTvZg"> 
    <importedPackage href="pathmap://GENMYMODEL_LIBRARIES/GenMyModelPrimitiveTypes.library.uml#/"/> 
    </packageImport> 
    <packagedElement xsi:type="uml:Package" xmi:id="_wfUKeYkNEeWSIKoWblTvZg" name="TOP"> 
    <packagedElement xsi:type="uml:Class" xmi:id="_wfUKfIkNEeWSIKoWblTvZg" name="Class1"> 
     <ownedAttribute xmi:id="_wfUKf4kNEeWSIKoWblTvZg" name="a1"> 
     <type xsi:type="uml:PrimitiveType" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#//Boolean"/> 
     </ownedAttribute> 
     <ownedAttribute xmi:id="_wfUKgokNEeWSIKoWblTvZg" name="a2"> 
     <type xsi:type="uml:PrimitiveType" href="pathmap://GENMYMODEL_LIBRARIES/GenMyModelPrimitiveTypes.library.uml#//Char"/> 
     </ownedAttribute> 
    </packagedElement> 
    <packagedElement xsi:type="uml:Package" xmi:id="_wfUKhYkNEeWSIKoWblTvZg" name="INNER"> 
     <packagedElement xsi:type="uml:Class" xmi:id="_wfUKiIkNEeWSIKoWblTvZg" name="Class2"> 
     <ownedAttribute xmi:id="_wfUKi4kNEeWSIKoWblTvZg" name="a1"> 
      <type xsi:type="uml:PrimitiveType" href="pathmap://GENMYMODEL_LIBRARIES/GenMyModelPrimitiveTypes.library.uml#//Double"/> 
     </ownedAttribute> 
     <ownedAttribute xmi:id="_wfUKjokNEeWSIKoWblTvZg" name="a2"> 
      <type xsi:type="uml:PrimitiveType" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#//Integer"/> 
     </ownedAttribute> 
     </packagedElement> 
    </packagedElement> 
    </packagedElement> 
</uml:Model> 

Визуальное представление здесь (вы также можете просматривать дерево модели): https://repository.genmymodel.com/vincent.aranega/test1

И сценарий я использовал:

[module example_stack('http://www.eclipse.org/uml2/4.0.0/UML')/] 

[template public generate(m : Model)] 
[comment @main/] 
[file ('res.txt', false, 'UTF-8')] 
[m.name/] 
['['/] 
    [for (p : Package | m.packagedElement.oclAsType(Package)) separator('\n,\n')] 
    [p.gen()/][/for] 

] 
[/file] 
[/template] 

[template public gen(o : OclAny)/] 
[template public gen(p : Package)] 
Container [p.name/] 
['['/] 
    [for (o : OclAny | p.packagedElement)] 
    [o.gen()/][if (p.packagedElement->asOrderedSet()->last() <> o)],[/if] 

    [/for] 
] 
[/template] 

[template public gen(c : Class)] 
Module [c.name/] 
['['/] 
    In 
    ['['/] 
     [for (p : Property | c.ownedAttribute)] 
     [p.gen()/][if (c.ownedAttribute->last() <> p)],[/if] 
     [/for] 
    ] 
] 
[/template] 

[template public gen(p : Property)] 
[p.name/] : [p.type.name/] 
[/template] 

И вывод:

HelloModel 
[ 
    Container TOP 
    [ 
     Module Class1 
     [ 
      In 
      [ 
       a1 : Boolean, 
       a2 : Char 
      ] 
     ], 

     Container INNER 
     [ 
      Module Class2 
      [ 
       In 
       [ 
        a1 : Double, 
        a2 : Integer 
       ] 
      ] 

     ] 

    ]  
] 

Идея состоит в том, чтобы создать специальный шаблон для каждого элемента, а не только один общий. Таким образом, вы управляете рекурсивным вызовом и отступом. В этом скрипте есть одна вещь, которой я не горжусь, так это управление «,» (используя if вместо separator). Вероятно, есть лучший способ сделать это.

+0

Спасибо за ваш ответ, я пересмотрел документы и протестировал новую строку и отступы. Поставьте на мой вопрос еще один пример –

0

Чтобы разместить дополнительную информацию.
Для итерационных шаблонов информация @VincentAranega в полезной форме, но я не нашел никакой стратегии отступов в рекурсивных шаблонах.
Я считаю, что невозможно определить globar var для хранения отступа, и нет функции для отметки желаемого отступа, для этого вам необходимо передать шаблон параметра, чтобы сообщить отступ и поместить в каждый элемент подметку для создания пространства вдавливания.
После просмотра ссылок, я проверил этот случай. Мой вывод: это сложно, чтобы получить желаемый результат и сохранить читаемость кода шаблона
Входной модель:

<?xml version="1.0" encoding="UTF-8"?> 
<hellomodel:Hellomodel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hellomodel="http://es.bancopopular.osgi.hellomodel"> 
    <calls tabla="T1001PE" name="MODULO" codNotFound="sqlcode = 100"> 
    <entrada> 
     <datos xsi:type="hellomodel:Columna" campo="MODULO-CAMPO1" nombre="CAMPO1"/> 
     <datos xsi:type="hellomodel:Literal" campo="MODULO-CAMPO2" value="2"/> 
    </entrada> 
    <callCode>call modulo</callCode> 
    <callCode>retorno</callCode> 
    </calls> 
    <calls tabla="T1001PE" name="MODULO2" codNotFound="sqlcode = 100"> 
    <entrada> 
     <datos xsi:type="hellomodel:Columna" campo="MODULO2-CAMPO1" nombre="CAMPO1"/> 
     <datos xsi:type="hellomodel:Literal" campo="MODULO2-CAMPO2" value="2"/> 
    </entrada> 
    <callCode>call modulo</callCode> 
    <callCode>retorno</callCode> 
    </calls> 
</hellomodel:Hellomodel> 

Файл MTL:

[module generate('http://es.bancopopular.osgi.hellomodel')] 

[template public generateElement(aHellomodel : Hellomodel)] 
[comment @main/] 
[file ('res.txt', false, 'UTF-8')] 
[generateR (aHellomodel,0)/] 
[/file] 
[/template] 

[template public generateR(ele : OclAny, count: Integer)] 
[ indent(count)/][generate(ele)/] [for (child : OclAny | ele.eContents()) 
              before ('\n'+indent(count)+'[\n') 
              separator (',\n') 
              after ('\n'+indent(count)+']\n')][ 
              generateR (child,count+4)/] [/for] 
[/template] 

[template public indent(count: Integer)] 
[let spaces : String = '              ' 
    ][spaces.first(count)/][/let] 
[/template] 

[template public generate(ele : OclAny) ][ele.eClass().name/][/template] 
[template public generate(ele : Call) ]Module [ele.name/][/template] 
[template public generate(ele : Entrada)]In[/template] 
[template public generate(ele : Columna)]Col->[ele.campo/]=[ele.nombre/][/template] 
[template public generate(ele : Literal)]Lit->[ele.campo/]=[ele.value/][/template] 

Генерировать файл:

Hellomodel 
[ 
    Module MODULO 
    [ 
     In 
     [ 
      Col->MODULO-CAMPO1=CAMPO1, 
      Lit->MODULO-CAMPO2=2 
     ] 

    ] 
, 
    Module MODULO2 
    [ 
     In 
     [ 
      Col->MODULO2-CAMPO1=CAMPO1, 
      Lit->MODULO2-CAMPO2=2 
     ] 

    ] 

] 
+0

Извините, я пропустил ваше сообщение, я редактировал сообщение, чтобы добавить новую информацию и пример о рекурсивных шаблонах. –

Смежные вопросы