140 likes | 298 Views
CPSC 875. John D. McGregor C18 – Code generation. DSL Grammar. grammar org.xtext.example.HelloLanguage.MyDsl with org.eclipse.xtext.common.Terminals generate myDsl "http://www.xtext.org/example/HelloLanguage/MyDsl" Messages: (messages+=Message)*; Message:
E N D
CPSC 875 John D. McGregor C18 – Code generation
DSL Grammar grammar org.xtext.example.HelloLanguage.MyDsl with org.eclipse.xtext.common.Terminals generate myDsl "http://www.xtext.org/example/HelloLanguage/MyDsl" Messages: (messages+=Message)*; Message: HelloWorld|HappyFourthOfJuly; HelloWorld returns HelloWorld: 'Hello_World' name=STRING; HappyFourthOfJuly: 'Happy_Fourth_Of_July' name=STRING;
Workflow - 1 Workflow { bean = StandaloneSetup { platformUri = "${runtimeProject}/.." } component = DirectoryCleaner { directory = "${runtimeProject}/src-gen" } component = DirectoryCleaner { directory = "${runtimeProject}.ui/src-gen" }
Workflow - 2 component = Generator { pathRtProject = runtimeProject pathUiProject = "${runtimeProject}.ui" projectNameRt = projectName projectNameUi = "${projectName}.ui" language = { uri = grammarURI fileExtensions = file.extensions // Java API to access grammar elements (required by several other fragments) fragment = grammarAccess.GrammarAccessFragment {} // generates Java API for the generated EPackages fragment = ecore.EcoreGeneratorFragment { // referencedGenModels = "uri to genmodel, uri to next genmodel" } // the serialization component fragment = parseTreeConstructor.ParseTreeConstructorFragment {} // a custom ResourceFactory for use with EMF fragment = resourceFactory.ResourceFactoryFragment { fileExtensions = file.extensions }
Sample program • Hello_World "John" • Hello_World "Reed" • Happy_Fourth_Of_July "Jim" • Happy_Fourth_Of_July "Jill"
Main.xpt «IMPORT myDsl» «DEFINE main FOR Messages-» «EXPAND Template::main FOREACH (this.types.typeselect(HappyFourthOfJuly))» «EXPAND DAO::dao FOREACH (this.types.typeselect(HappyFourthOfJuly))» «EXPAND Template::main FOREACH (this.types.typeselect(HelloWorld))» «EXPAND DAO::dao FOREACH (this.types.typeselect(HelloWorld))» «ENDDEFINE»
HappyFourthofJuly.xpt «IMPORT myDsl» «DEFINE main FOR HappyFourthOfJuly» «FILE "Greeting_"+name+".java"» public class «"Greeting_"+name» { public static void main(String[] args) { System.out.println("«"Happy Fourth of July "+ name»"); } } «ENDFILE-» «ENDDEFINE»
DAO.xpt «IMPORT myDsl» «DEFINE dao FOR myDsl::HappyFourthOfJuly» «FILE this.name + "DAO.java"» import java.util.Collection; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.orm.hibernate3.*; import org.springframework.dao.*; import org.springframework.core.*; public class «this.name»DAO extends HibernateDaoSupport { «EXPAND crud FOR this» } «ENDFILE» «ENDDEFINE»
2nd workflow Workflow { component = org.eclipse.xtext.mwe.Reader { // lookup all resources on the classpath // useJavaClassPath = true // or define search scope explicitly path = modelPath // this class will be generated by the xtext generator register = org.xtext.example.HelloLanguage.MyDslStandaloneSetup {} load = { slot = "m" type = "HappyFourthOfJuly" } }
2nd workflow - 2 component = org.eclipse.xpand2.Generator { metaModel=org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel{} expand = "templates::HappyFourthOfJuly::main FOREACH m" outlet = { path = targetDir } fileEncoding = fileEncoding } component = org.eclipse.xpand2.Generator { metaModel=org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel{} expand = "templates::DAO::dao FOREACH m" outlet = { path = targetDir } fileEncoding = fileEncoding }
*.java public class Greeting_Jill { public static void main(String[] args) { System.out.println("Happy Fourth of July Jill"); } }
Generator architecture • https://diaspec.bordeaux.inria.fr/
DSSA • http://www.abssw.com/courses/JPL2006/Spring/06.1%20Domain-Specific%20Software%20Architectures%20%28DSSA%29.pdf • www.softwarearchitecturebook.com/.../24_DSSA_and_Product_Lines.ppt • http://csse.usc.edu/gsaw/gsaw2010/s6/woollard.pdf