xtend 代码生成调用来自 xtext 语法的实体

xtend code generation calling entities from an xtext grammar

我正在为我创建的语法开发代码生成器:

Domainmodel:
    (elements+=AbstractElement)*;

PackageDeclaration:
    'package' name=QualifiedName '{'
        (elements+=AbstractElement)*
    '}';

AbstractElement:
    PackageDeclaration | Type | Import;

QualifiedName:
    ID ('-' ID)*;

QualifiedDate:
    INT('-' INT)*
;

Import:
    'import' importedNamespace=QualifiedNameWithWildcard;

QualifiedNameWithWildcard:
    QualifiedName '.*'?;

Type:
     (data+= DataType)* man+=Entity  ;


DataType:
    'tag' name=Tag;

Tag:
    Hobbies='hobbies' | Work= 'work' |Fun='fun'
;

Entity:
    name=Category '{'
       feature+=Feature*
    '}'
    ;
Feature:
    component+=Man(',' component+=Opt)*
;    
enum Category:
    Blog='blog' | Article='articles'
;

Man:
    name='title' '=' type=QualifiedName
 ;

 Opt:
    Tags|Date
 ;

 Tags:
    name='tags' '=' '['type= Tag(','tag+=Tag)*']' 
    |
    name='tags' '=' '[' ']' 
    ;

Date:
    name='date' '=' type=QualifiedDate
    ;

我希望代码生成器的输出如下所示:

---
layout: post
title: "My Trip"
categories: blog
excerpt:
tags: [fun,hobbies]
image:
feature:
date: 2016-06-01T14:19:19-04:00
modified:
---

我只能得到正确的静态文本,我似乎无法调用:类别、标题、标签、日期 我已经尝试了很长时间,但我似乎无处可去,我不断收到我不理解的奇怪错误

我只是想看看我能生成什么的尝试之一是:

class MyDslGenerator implements IGenerator2 {

def compile(Entity e) 
{

    '''

    ---
    layout: post
    title: "My Trip"
    categories:«e.name»
    excerpt:
    tags: [fun,hobbies]
    image:
    feature:
    date: 2016-06-01T14:19:19-04:00
    modified:
    ---
    '''
}
override doGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
    for (e : input.allContents.toIterable.filter(Entity)) {
        fsa.generateFile(
            e.generateName,
            e.compile)
    }
}

当我 运行 生成器时,我没有用 <> 替换任何东西。我似乎无法弄清楚。

这是一个关于如何走 AST 的问题。你的语法和推断的元模型相当 "bad" 走路所以你可能必须做类似

title: «(e.feature.head.component.head as Man).type»

所以我建议你重组你的 grammar/AST 以适应你需要的东西。

您可以像这样为 xtend/xtext 插件设置编码

tasks.withType(org.xtext.gradle.tasks.XtextGenerate) {
    options.encoding = 'ISO-8859-1'
}

有帮助吗?

/**
 * generated by Xtext 2.10.0
 */
package org.xtext.example.mydsl.tests;

import com.google.inject.Inject;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.XtextRunner;
import org.eclipse.xtext.junit4.util.ParseHelper;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xtext.example.mydsl.myDsl.Domainmodel;
import org.xtext.example.mydsl.tests.MyDslInjectorProvider;

@RunWith(XtextRunner.class)
@InjectWith(MyDslInjectorProvider.class)
@SuppressWarnings("all")
public class MyDslParsingTest {
  @Inject
  private ParseHelper<Domainmodel> parseHelper;

  @Test
  public void loadModel() {
    try {
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("Hello Xtext!");
      _builder.newLine();
      final Domainmodel result = this.parseHelper.parse(_builder);
      Assert.assertNotNull(result);
    } catch (Throwable _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }
}