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);
}
}
}
我正在为我创建的语法开发代码生成器:
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);
}
}
}