Download - 1 Domain Specific Languages Based on
3PROGRAMS=ex1_connect ex2_select
all: $(PROGRAMS)
clean:
rm -f $(PROGRAMS) *.o
include $(ORACLE_HOME)/rdbms/lib/env_rdbms.mk
OPTIMIZE=$(OPTIMIZEG)
.SUFFIXES: .o .cc
.cc.o:
$(CCC) $(CFLAGSCC) -c $<
ex1_connect: ex1_connect.o
$(LINKCC) ex1_connect.o $(SHARED_OCCILIBS)
ex2_select: ex2_select.o
$(LINKCC) ex2_select.o $(SHARED_OCCILIBS)
4<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app>
<display-name>IMDB</display-name>
<description>Internet Movie Database</description>
<context-param>
<param-name>db-url</param-name>
<param-value>www.imdb.com/datacenter</param-value>
</context-param>
<servlet>
<servlet-name>search</servlet-name>
<servlet-class>my.package.SearchServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>search</servlet-name>
<url-pattern>/search.html</url-pattern>
</servlet-mapping>
</web-app>
5
<menubar>
<item name="File">
<item name="Open" mnemonic="O">commands.Open</item>
<item name="Save" mnemonic="S">commands.Save</item>
<item name="Save As" mnemonic="A">commands.SaveAs</item>
</item>
<item name="Edit">
<item name="Cut" mnemonic="T">commands.Cut</item>
<item name="Copy" mnemonic="C">commands.Copy</item>
<item name="Paste" mnemonic="P">commands.Paste</item>
</item>
</menubar>
7
DSL
• A language designed for solving a specific class of problems– “Do one thing well”
• Less powerful than a general-purpose language (GPL)– Usually not Turing complete– If it’s not simpler to use than a GPL – no reason to use it
9
DSL: Customizability
• Allow users to customize a program– Without recompiling it
• Imagine: Unix’s make without the DSL– Make will be a library– User will write a program that uses the library– Will use API for defining the dependencies, actions, etc.– Compile & Run
• In the good old days compilation was an issue
10
DSL: Productivity
• In its domain a DSL is more productive than a general purpose language– Because it does one thing well
• Example: String matching– Very easy with regular expressions– Much harder with manually written Java code
• The direct result: DSLs are all over the place– Even if no user-customizability is needed
11
DSL Oriented Development
• Development that focuses on building and using DSLs to develop a system
• Various DSLs float around – each one solves a particular problem within the broader context
• One cannot build a whole program with one DSL
• Don’t overdo it – implementing a DSL takes effort
13
External DSL Highlights
• Syntax– Custom-made– (Or) Follows a common format CSV, XML, etc.
• Stages– Parsing and tree Construction– Semantic Model construction– Execution
• Not all stages must exist– Developer may choose to do execution while parsing
14
[{ name: "File", shortcut:'F', children: [ { name:"Open", shortcut:'o', action:"p1.Main$FileOpen"}, { name:"Exit", shortcut:'x', action:"p1.Main$FileExit"} ] },{ name: "Edit", shortcut:'E', children: [ { name:"Cut", shortcut:'t', action:"p1.Main$EditCut"}, { name:"Paste", shortcut:'p', action:"p1.Main$EditPaste"} ] }]
15
Theory of Compilation & DSLs
• Compilation courses often focus on advanced parsing issues
• In practice, simple recursive descent parsers are fine– Even lexical scanners are not always needed
• => No need to use parser generators– If you do want to use them: modern tools (Antlr, Javacc)
are much simpler than Lex/Yacc
• Bottom line: don’t panic
16
Internal DSL
A DSL expressed within the syntax of a general purpose language.
A stylized use of the language for a domain specific purpose.
17
Menu Definition API
public class Menu { public Menu add(Menu m) { // add m as a child return this; } } public Menu item(String name) { ... } public Menu item(String name, char mnemonic) } ... } public Menu item(String name, char accelerator) } ... } public Menu item(String name, char mnemonic, char
accelerator) } ... } public Menu item(String name, char mnemonic, ActionListener l) { ... } public Menu menubar() { return new Menu(); }
18
Defining a Menu
menubar() .add( item("File", 'f') .add(item("Open", 'o', new FileOpen())) .add(item("Exit", 'o', new FileExit()))) .add( item("Edit", 'e') .add(item("Cut", 'c', new EditCut())) .add(item("Paste", 'p', new EditPaste())));
19
Difficulties of the Proposed API
• Order of parameters
• Too many parenthesis
• Must create an item() method for each subset of desired menu properties
20
A Better API
public interface MenuBuilder {
public MenuBuilder child(String name);
public MenuBuilder shortcut(char c);
public MenuBuilder action(ActionListener al);
public MenuBuilder up();
// ... and a few more
}
21
Defining a Menu (Again)new MenuBuilder() .child("File").shortcut('f') .child("Open") .shortcut('o').action(new FileOpen()) .up() .child("Exit") .shortcut('x').action(new FileExit()) .up() .up() .child("Edit").shortcut('e') .child("Cut") .shortcut('c').action(new EditCut()) .up() .child("Paste") .shortcut('p').action(new EditPaste()) .up() .up()
22
Internal DSL Highlights
• Syntax– Based on the API– Heavy use of fluent interfaces
• Stages– Semantic Model construction– Execution
• Not all stages must exist– API may do the actual execution when called
23
Comparison
• Pros: External DSL– Full control over syntax, semantics– User customizability
• Pros: Internal DSL– Integration with the host language– IDE support
24
Rake File
• Rake: A build system for the Ruby world– Similar to Java’s Ant, Unix’s Make
• As expected uses a DSL for building program
• Here’s a sample Rake file– Q: is this an internal or external DSL?
25
require 'rake/clean'
PROG = "foo" LIBNAME = PROGLIBFILE = "lib#{LIBNAME}.a"
SRC = FileList['**/*.c']
OBJDIR = 'obj'OBJ = SRC.collect { |fn| File.join(OBJDIR,
File.basename(fn).ext('o')) }
CLEAN.include(OBJ, OBJDIR, LIBFILE)CLOBBER.include(PROG)
task :default => [:build, :run]
# continued on next slide
26# continued from previous slide
task :build => [PROG]
task :run => [PROG] do sh "./#{PROG}" end
file PROG => [LIBFILE] do sh "cc -o #{PROG} -L . -l#{LIBNAME}" end
file LIBFILE => OBJ do sh "ar cr #{LIBFILE} #{OBJ}" sh "ranlib #{LIBFILE}" end
27
DSL & Dynamic Languages
• Dynamic languages are flexible– Syntax– Offer new constructs– Redefining semantics of existing constructs
• Thus, they can support a wide spectrum of internal DSL syntaxes
• The best of both worlds– Integration with the host language– IDE support– User customizability– (Almost) Flexible syntax