2013-03-14 5 views
4

я пытаюсь определить некоторые XText для specifiying переменных в соответствии со следующим синтаксисомXText разделенные запятой объявление переменной

variables 
    MyVar1 : Bool at 0x020 value=true; 
    MyVar2, MyVar3 : Int at 0x030 value 200; 
end-variables 

Так каждое определение синтаксически

VarName ["," VarName]* ":" Type ["at" HEX]? ["value" VALUE]? ";" 

Все переменные должны быть доступными для их ведения и результат в виде контура должен быть примерно следующим образом:

variables 
+-MyVar1 : Bool 
+-MyVar2 : Int 
+-MyVar3 : Int 

Редактировать: В соответствии с запрошенной здесь моей фактической грамматикой, которая эквивалентна синтаксическому определению некоторых строк выше.

Variable: 
    name=ID 
; 
Declaration_Var: 
    'variables' 
    vars+=Declaration_Var_Body+ 
    'end-variables' ';' 
; 
Declaration_Var_Body: 
    varDecl+=Variable(',' varDecl +=Variable)* 
    ':' type=[TR_Any] 
    ('at' address=HEX)? 
; 
TR_Any: 
    ... 
; 
terminal HEX: 
    ... 
; 

При этом, следуя последовательности символов

variables 
    Test1, Test2, Test3 : DWORD at 0x20; 
end_var; 

результаты в общих чертах, как это:

<unnamed> 
+-- 0x20 
| +-- Test1 
| +-- Test2 
| +-- Test3 

который почти противоположное тому, что я ожидал. То, что я ожидал, и то, что я хочу сгенерировать в контуре, похоже на это (тип данных и адрес не должны отображаться там, но по крайней мере они должны быть доступны как свойства генерируемого класса для объявлений переменных)

Test1 
+-- DWORD 
+-- 0x20 
Test2 
+-- DWORD 
+-- 0x20 
Test3 
+-- DWORD 
+-- 0x20 
+0

Не могли бы вы изложить свою текущую грамматику и задать конкретные вопросы? –

+0

Я добавил еще более подробное описание – abs

+0

Хорошо, теперь я понимаю вашу проблему.Вы на самом деле заинтересованы только в том, чтобы получить красивый внешний вид или изменить внутренние структуры так, как вы описали? –

ответ

1

Смотрите здесь: http://xtextcasts.org/episodes/18-model-optimization

Необходимо изменить модель и метамоду. Чтобы изменить метамодель, вам нужно определить постпроцессор. Следующий пост-процессор добавляет type каталог атрибутов к классу Variable.

Для получения более подробной информации см: http://christiandietrich.wordpress.com/tag/postprocessor/

class MyXtext2EcorePostProcessor implements IXtext2EcorePostProcessor { 
    override process(GeneratedMetamodel metamodel) { 
    metamodel.EPackage.process 
    } 

    def process(EPackage p) { 
    for (clazz : p.EClassifiers.filter(typeof(EClass))) { 
     if (clazz.name == typeof(Variable).simpleName) { 
     val typeAttribute = EcoreFactory::eINSTANCE.createEAttribute 
     typeAttribute.name = "type" 
     typeAttribute.EType = EcorePackage::eINSTANCE.EString 
     clazz.EStructuralFeatures += typeAttribute 
     } 
    } 
    } 
} 

Тогда вы должны связать его расширение Generator как это:

public class ExtendedGenerator extends Generator { 
    public ExtendedGenerator() { 
    new XtextStandaloneSetup() { 
     @Override 
     public Injector createInjector() { 
     return Guice.createInjector(new XtextRuntimeModule() { 
      @Override 
      public Class<? extends IXtext2EcorePostProcessor> 
           bindIXtext2EcorePostProcessor() { 
      return MyXtext2EcorePostProcessor.class; 
      } 
     }); 
     } 
    }.createInjectorAndDoEMFRegistration(); 
    } 
} 

И, наконец, использовать новый ExtendedGenerator в вашем mwe2 документооборота:

... 
Workflow { 
    ... 
    bean = StandaloneSetup { 
    ... 
    component = postprocessor.ExtendedGenerator { // Set ExtendedGenerator! 
     ... 
    } 
    ... 
    } 
    ... 
} 
... 

Затем вы должны заполнить свой новый type атрибут с данными. Вы можете сделать это, используя интерфейс IDerivedStateComputer.

class MyDerivedStateComputer implements IDerivedStateComputer { 

    override discardDerivedState(DerivedStateAwareResource resource) { 
    resource.allContents.filter(typeof(VariableDefinition)).forEach [ 
     type = null 
    ] 
    } 

    override installDerivedState(DerivedStateAwareResource resource, 
           boolean preLinkingPhase) { 
    resource.allContents.filter(typeof(VariableDefinition)).forEach [ 
     type = (eContainer as DefinitionBlock).type 
    ] 
    } 
} 

Тогда вы должны связать его, как это (второй и третий Bind-методы необходимы только для не Xbase-проектов)

public class MyDslRuntimeModule extends AbstractMyDslRuntimeModule { 
    public Class<? extends IDerivedStateComputer> bindIDerivedStateComputer() { 
    return MyDerivedStateComputer.class; 
    } 

    // Not needed for Xbase-projects 
    @Override 
    public Class<? extends XtextResource> bindXtextResource() { 
    return DerivedStateAwareResource.class; 
    } 

    // Not needed for Xbase-projects 
    public Class<? extends IResourceDescription.Manager> 
         bindIResourceDescriptionManager() { 
    return DerivedStateAwareResourceDescriptionManager.class; 
    } 
} 

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

+0

Не совсем то, что я ищу. В вашей грамматике список переменных может быть указан как 'MyVar1: MyType, MyVar2: MyType, ...' Мне нужно указать их следующим образом: 'MyVar1, MyVar2, ...: MyType' (см. Синтаксическое определение в вопросе) – abs

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