1

これは、ドメイン固有言語 (DSL) を作成するためのクラス プロジェクトです。考慮すべき空想は何もありません。私自身は、このプロジェクトを、関連する手順を学ぶための純粋な演習として設定しました。

関連するファイル (添付のコード ファイルを含む)::

1) Xtext の文法 (entities.xtext)

grammar org.example.xbase.entities.Entities with org.eclipse.xtext.xbase.Xbase  

generate entities "http://www.example.org/xbase/entities/Entities"


Model:
    entities+=Entity*;


Entity:
    'entity' name=ID ('extends'
        superType=JvmParameterizedTypeReference)?
        '{'
            attributes+=Attribute*
            operations+=Operation*
        '}';

Attribute:
    'attr'(type=JvmTypeReference)? name=ID
    ('=' initexpression=XExpression)? ';';

Operation:
    'op'(type=JvmTypeReference)? name=ID
    '(' (params+=FullJvmFormalParameter (',' 
        params+=FullJvmFormalParameter)*)? ')'
    body=XBlockExpression;

2) xtend の JvmModelInferrer (entitiesJvmModelInferrer.xtend)

package org.example.xbase.entities.jvmmodel

import com.google.inject.Inject
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.example.xbase.entities.entities.Entity

class EntitiesJvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
@Inject extension IQualifiedNameProvider

    def dispatch void infer(Entity entity, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
        acceptor.accept(entity.toClass("Animals."+entity.name)).
            initializeLater[
                documentation= entity.documentation
                if(entity.superType !=null)
                    superTypes += entity.superType.cloneWithProxies

                    //Create fields for each attribute in the entity
                    entity.attributes.forEach[
                        a | val type = a.type ?: a.initexpression?.inferredType
                        members += a.toField(a.name,type) [
                            documentation=a.documentation
                            if(a.initexpression !=null)
                                initializer = a.initexpression
                        ]
                        //create getter method
                        members +=a.toGetter(a.name,type)
                        //create setter method
                        members +=a.toSetter(a.name,type)
                    ]   
                    //Create method for each operation in the entity
                    entity.operations.forEach[
                        op|
                        members+= op.toMethod(op.name,op.type?:inferredType)[
                            documentation=op.documentation
                            for (p:op.params){
                                parameters +=p.toParameter(p.name,p.parameterType)
                            }
                            //create a main method in one of the classes, when called. Make sure it is also static!!!
                            if(op.name.equals('main')){
                                static=true
                            }
                            body=op.body
                        ]
                    ]

            ]
}
}

3) 新しい言語のソース ファイル (Animal.xentities および Main.xentities)。.xentities 拡張子は、この DSL プロジェクトのファイルに固有のものです。- Main.xentities

entity Main{
    //define an instance of Animal
    attr me=new Animal;
    op main(){
        println('main-func')
    }
}

-生成された Main.java

package Animals;

import Animals.Animal;
import org.eclipse.xtext.xbase.lib.Functions.Function0;
import org.eclipse.xtext.xbase.lib.InputOutput;

@SuppressWarnings("all")
public class Main {
  private Animal me = new Function0<Animal>() {
    public Animal apply() {
      Animal _animal = new Animal();
      return _animal;
    }
  }.apply();

  public Animal getMe() {
    return this.me;
  }

  public void setMe(final Animal me) {
    this.me = me;
  }

  public static String main() {
    //This is the main function I created to
    //have an entry point for program execution
    String _println = InputOutput.<String>println("main-func");
    return _println;
  }
}

-Animal.xentities

entity Animal{
//define an equivalent class in my domain-specific language
attr int nlegs;
op printAnimalSound(){
    println('I grunt and sniff')
}
}

-生成された Animal.java コード

package Animals;

import org.eclipse.xtext.xbase.lib.InputOutput;

@SuppressWarnings("all")
public class Animal {
  private int nlegs;

  public int getNlegs() {
    return this.nlegs;
  }

  public void setNlegs(final int nlegs) {
    this.nlegs = nlegs;
  }

  public String printAnimalSound() {
    String _println = InputOutput.<String>println("I grunt and sniff");
    return _println;
  }
}

私の目的:: 関連する関数と属性を持つクラスを定義できるように、基本的なワークフロー インフラストラクチャを開発したいと考えています。それから私はそれらを実行できるようになりたいです。

私の問題:: 「選択にメインタイプが含まれていません」というメッセージが表示され続けます。

私の試み: エンティティ (クラス) 'Main.xentities' で、'op main()' 関数を作成します。生成された .java コードでは、これは public static String main() 関数として表示されます。これはうまくいくと思いました。しかし、そうではありませんでした。何が欠けているのかわからない。どんな助けでも大歓迎です。

4

1 に答える 1

0

もちろん、これではうまくいきません!! メイン メソッドは void を返し、型 String[] args の引数を取る必要があります。また

public static void main(String[] args){ ...}

これを実現するには、JvmModelInferrer ファイルを変更する必要があります。

于 2013-11-03T22:38:33.290 に答える