astrapi 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/astrapi +9 -0
- data/doc/astrapi.html +149 -0
- data/lib/ast.rb +68 -0
- data/lib/checker.rb +61 -0
- data/lib/class_diagram_printer.rb +83 -0
- data/lib/code.rb +48 -0
- data/lib/compiler.rb +149 -0
- data/lib/dbg.rb +7 -0
- data/lib/dot_printer.rb +72 -0
- data/lib/indent.rb +19 -0
- data/lib/lexer.rb +152 -0
- data/lib/parser.rb +110 -0
- data/lib/pretty_printer.rb +68 -0
- data/lib/ruby_generator.rb +329 -0
- data/lib/template_ast_printer.rb +79 -0
- data/lib/template_code.rb +48 -0
- data/lib/template_compiler.rb +59 -0
- data/lib/template_indent.rb +19 -0
- data/lib/template_lexer.rb +139 -0
- data/lib/template_parser.rb +75 -0
- data/lib/template_pretty_printer.rb +46 -0
- data/lib/template_visitor.rb +18 -0
- data/lib/version.rb +3 -0
- data/lib/visitor.rb +53 -0
- data/tests/geometry.mm +32 -0
- metadata +72 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
require_relative 'indent'
|
2
|
+
require_relative 'code'
|
3
|
+
|
4
|
+
module <%=mm.name%>
|
5
|
+
|
6
|
+
class DotPrinter
|
7
|
+
|
8
|
+
include Indent
|
9
|
+
|
10
|
+
attr_accessor :code,:nodes_decl,:nodes_cnx
|
11
|
+
|
12
|
+
def print ast #entry method
|
13
|
+
@verbose=false
|
14
|
+
@nodes_decl=Code.new
|
15
|
+
@nodes_cnx=Code.new
|
16
|
+
@printed_cnx={} #Cosmetic ! to keep track of already printed cnx source->sink
|
17
|
+
@code=Code.new
|
18
|
+
code << "digraph G {"
|
19
|
+
code.indent=2
|
20
|
+
code << "ordering=out;"
|
21
|
+
code << "ranksep=.4;"
|
22
|
+
code << "bgcolor=\"lightgrey\";"
|
23
|
+
code.newline
|
24
|
+
code << "node [shape=box, fixedsize=false, fontsize=12, fontname=\"Helvetica-bold\", fontcolor=\"blue\""
|
25
|
+
code << " width=.25, height=.25, color=\"black\", fillcolor=\"white\", style=\"filled, solid, bold\"];"
|
26
|
+
code << "edge [arrowsize=.5, color=\"black\", style=\"bold\"]"
|
27
|
+
process(ast)
|
28
|
+
code << @nodes_decl
|
29
|
+
code << @nodes_cnx
|
30
|
+
code.indent=0
|
31
|
+
code << "}"
|
32
|
+
return code
|
33
|
+
end
|
34
|
+
|
35
|
+
def process node,level=0
|
36
|
+
id=node.object_id
|
37
|
+
if node.is_a? Token
|
38
|
+
sink="#{id}"
|
39
|
+
val=node.val
|
40
|
+
nodes_decl << "#{sink} [label=\"#{val}\",color=\"red\"]"
|
41
|
+
else
|
42
|
+
|
43
|
+
kname=node.class.name.split("::")[1]
|
44
|
+
id=node.object_id
|
45
|
+
nodes_decl << "#{id} [label=\"#{kname}\"]"
|
46
|
+
|
47
|
+
node.instance_variables.each{|vname|
|
48
|
+
ivar=node.instance_variable_get(vname)
|
49
|
+
vname=vname.to_s[1..-1]
|
50
|
+
case ivar
|
51
|
+
when Array
|
52
|
+
ivar.each_with_index{|e,idx|
|
53
|
+
sink=process(e,level+2)
|
54
|
+
@printed_cnx[id]||=[]
|
55
|
+
nodes_cnx << "#{id} -> #{sink} [label=\"#{vname}[#{idx}]\"]" if not @printed_cnx[id].include? sink
|
56
|
+
@printed_cnx[id] << sink
|
57
|
+
}
|
58
|
+
when Token
|
59
|
+
val=ivar.val
|
60
|
+
sink="#{ivar.object_id}"
|
61
|
+
nodes_decl << "#{sink} [label=\"#{val}\",color=\"red\"]"
|
62
|
+
@printed_cnx[id]||=[]
|
63
|
+
nodes_cnx << "#{id} -> #{sink} [label=\"#{vname}\"]" if not @printed_cnx[id].include? sink
|
64
|
+
@printed_cnx[id] << sink
|
65
|
+
when nil
|
66
|
+
else
|
67
|
+
sink=process(ivar,level+2)
|
68
|
+
@printed_cnx[id]||=[]
|
69
|
+
nodes_cnx << "#{id} -> #{sink} [label=\"#{vname}\"]" if not @printed_cnx[id].include? sink
|
70
|
+
@printed_cnx[id] << sink
|
71
|
+
end
|
72
|
+
|
73
|
+
}
|
74
|
+
end
|
75
|
+
return id
|
76
|
+
end
|
77
|
+
|
78
|
+
end #class
|
79
|
+
end #module
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Code
|
2
|
+
|
3
|
+
attr_accessor :indent,:code
|
4
|
+
|
5
|
+
def initialize indent=0
|
6
|
+
@code=[]
|
7
|
+
@indent=indent
|
8
|
+
end
|
9
|
+
|
10
|
+
def <<(str)
|
11
|
+
if str.is_a? Code
|
12
|
+
str.code.each do |line|
|
13
|
+
@code << " "*@indent+line
|
14
|
+
end
|
15
|
+
elsif str.is_a? Array
|
16
|
+
str.each do |kode|
|
17
|
+
@code << kode
|
18
|
+
end
|
19
|
+
elsif str.nil?
|
20
|
+
else
|
21
|
+
@code << " "*@indent+str
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def finalize dot=false
|
26
|
+
if dot
|
27
|
+
return @code.join('\n')
|
28
|
+
end
|
29
|
+
@code.join("\n") if @code.any?
|
30
|
+
end
|
31
|
+
|
32
|
+
def newline
|
33
|
+
@code << " "
|
34
|
+
end
|
35
|
+
|
36
|
+
def save_as filename,verbose=true,sep="\n"
|
37
|
+
str=self.finalize
|
38
|
+
File.open(filename,'w'){|f| f.puts(str)}
|
39
|
+
puts "saved code in file #{filename}" if verbose
|
40
|
+
return filename
|
41
|
+
end
|
42
|
+
|
43
|
+
def size
|
44
|
+
@code.size
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative '<%=mm.name.to_s.downcase%>_parser'
|
2
|
+
require_relative '<%=mm.name.to_s.downcase%>_pp'
|
3
|
+
require_relative '<%=mm.name.to_s.downcase%>_ast_printer'
|
4
|
+
require_relative '<%=mm.name.to_s.downcase%>_visitor'
|
5
|
+
|
6
|
+
module <%=mm.name%>
|
7
|
+
|
8
|
+
class Compiler
|
9
|
+
attr_accessor :ast
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
puts "<%=mm.name%> compiler"
|
13
|
+
end
|
14
|
+
|
15
|
+
def compile filename
|
16
|
+
@ast=parse(filename)
|
17
|
+
visit
|
18
|
+
pretty_print
|
19
|
+
dot_print
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse filename
|
23
|
+
@filename=filename
|
24
|
+
name,@suffix=filename.split("/").last.split(".")
|
25
|
+
@basename=File.basename(filename,"."+@suffix)
|
26
|
+
puts "==> parsing #{filename}"
|
27
|
+
<%=mm.name%>::Parser.new.parse(filename)
|
28
|
+
end
|
29
|
+
|
30
|
+
def visit
|
31
|
+
puts "==> dummy visit"
|
32
|
+
<%=mm.name%>::Visitor.new.visit(ast)
|
33
|
+
end
|
34
|
+
|
35
|
+
def pretty_print
|
36
|
+
target="#{@basename}_pp.#{@suffix}"
|
37
|
+
puts "==> pretty print to ............ #{target}"
|
38
|
+
code_str=<%=mm.name%>::PrettyPrinter.new.print(ast)
|
39
|
+
File.open("#{target}",'w'){|f| f.puts code_str}
|
40
|
+
end
|
41
|
+
|
42
|
+
def dot_print
|
43
|
+
target="#{@basename}.dot"
|
44
|
+
puts "==> generate dot for AST in .... #{target}"
|
45
|
+
code=<%=mm.name%>::DotPrinter.new.print(ast)
|
46
|
+
code.save_as(target,verbose=false)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if $PROGRAM_NAME == __FILE__
|
53
|
+
filename=ARGV[0]
|
54
|
+
raise "need a <%=mm.name%> file !" if filename.nil?
|
55
|
+
t1 = Time.now
|
56
|
+
<%=mm.name%>::Compiler.new.compile(filename)
|
57
|
+
t2 = Time.now
|
58
|
+
puts "compiled in : #{t2-t1} s"
|
59
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'strscan'
|
3
|
+
#require 'benchmark'
|
4
|
+
|
5
|
+
class Token
|
6
|
+
attr_accessor :kind,:val,:pos
|
7
|
+
def initialize tab
|
8
|
+
@kind,@val,@pos=*tab
|
9
|
+
end
|
10
|
+
|
11
|
+
def is_a? kind
|
12
|
+
case kind
|
13
|
+
when Symbol
|
14
|
+
return @kind==kind
|
15
|
+
when Array
|
16
|
+
for sym in kind
|
17
|
+
return true if @kind==sym
|
18
|
+
end
|
19
|
+
return false
|
20
|
+
when Class
|
21
|
+
return kind==Token
|
22
|
+
else
|
23
|
+
raise "wrong type for token test"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def accept dummy,args=nil
|
28
|
+
val
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module <%=mm.name%>
|
33
|
+
|
34
|
+
class Lexer
|
35
|
+
#................................................
|
36
|
+
NEWLINE = /[\n]/
|
37
|
+
SPACE = /[ \t]+/
|
38
|
+
#.............punctuation........................
|
39
|
+
LPAREN = /\A\(/
|
40
|
+
RPAREN = /\A\)/
|
41
|
+
COMMENT = /\A\#(.*)/
|
42
|
+
# .............M3E specific literals.............
|
43
|
+
IDENT = /\A[a-zA-Z]+[0-9a-zA-Z_]*/i
|
44
|
+
FLOAT = /\A[0-9]+\.[0-9]+/
|
45
|
+
FRAC = /\A[0-9]+\/[0-9]+/
|
46
|
+
INTEGER = /\A[0-9]+/
|
47
|
+
RANGE = /\A#{INTEGER}\.\.#{INTEGER}/
|
48
|
+
STRING = /\A\"(.*)\"/ # need to check!
|
49
|
+
NIL = /\Anil/
|
50
|
+
TRUE = /\A\true/
|
51
|
+
FALSE = /\Afalse/
|
52
|
+
#..............DSL keywords......................
|
53
|
+
<%=keywords_regexp%>
|
54
|
+
|
55
|
+
def initialize str=''
|
56
|
+
init(str)
|
57
|
+
end
|
58
|
+
|
59
|
+
def init str
|
60
|
+
@ss=StringScanner.new(str)
|
61
|
+
@line=0
|
62
|
+
end
|
63
|
+
|
64
|
+
def tokenize str
|
65
|
+
@tokens=[]
|
66
|
+
init(str)
|
67
|
+
until @ss.eos?
|
68
|
+
@tokens << next_token()
|
69
|
+
end
|
70
|
+
return @tokens[0..-2]
|
71
|
+
end
|
72
|
+
|
73
|
+
#next token can detect spaces length
|
74
|
+
def next_token
|
75
|
+
|
76
|
+
if @ss.bol?
|
77
|
+
@line+=1
|
78
|
+
@old_pos=@ss.pos
|
79
|
+
end
|
80
|
+
|
81
|
+
position=[@line,@ss.pos-@old_pos+1]
|
82
|
+
|
83
|
+
return :eos if @ss.eos?
|
84
|
+
|
85
|
+
case
|
86
|
+
when text = @ss.scan(NEWLINE)
|
87
|
+
next_token()
|
88
|
+
when text = @ss.scan(SPACE)
|
89
|
+
next_token()
|
90
|
+
when text = @ss.scan(LPAREN)
|
91
|
+
return Token.new [:lparen,text,position]
|
92
|
+
when text = @ss.scan(COMMENT)
|
93
|
+
return Token.new [:m3e_comment,text,position]
|
94
|
+
when text = @ss.scan(RPAREN)
|
95
|
+
return Token.new [:rparen,text,position]
|
96
|
+
when text = @ss.scan(FLOAT)
|
97
|
+
return Token.new [:float_lit,text,position]
|
98
|
+
when text = @ss.scan(FRAC)
|
99
|
+
return Token.new [:frac_lit,text,position]
|
100
|
+
when text = @ss.scan(RANGE)
|
101
|
+
return Token.new [:range_lit,text,position]
|
102
|
+
when text = @ss.scan(INTEGER)
|
103
|
+
return Token.new [:integer_lit,text,position]
|
104
|
+
when text = @ss.scan(STRING)
|
105
|
+
return Token.new [:string_lit,text,position]
|
106
|
+
when text = @ss.scan(FRAC)
|
107
|
+
return Token.new [:frac_lit,text,position]
|
108
|
+
when text = @ss.scan(IDENT)
|
109
|
+
case
|
110
|
+
<%=apply_regexp%>
|
111
|
+
when value = text.match(NIL)
|
112
|
+
return Token.new [:nil,text,position]
|
113
|
+
when value = text.match(TRUE)
|
114
|
+
return Token.new [:true,text,position]
|
115
|
+
when value = text.match(FALSE)
|
116
|
+
return Token.new [:false,text,position]
|
117
|
+
else
|
118
|
+
return Token.new [:identifier,text,position]
|
119
|
+
end
|
120
|
+
else
|
121
|
+
x = @ss.getch
|
122
|
+
return Token.new [x, x,position]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
if $PROGRAM_NAME == __FILE__
|
129
|
+
str=IO.read(ARGV[0])
|
130
|
+
#str.downcase!
|
131
|
+
puts str
|
132
|
+
t1 = Time.now
|
133
|
+
lexer=<%=mm.name%>::Lexer.new
|
134
|
+
tokens=lexer.tokenize(str)
|
135
|
+
t2 = Time.now
|
136
|
+
pp tokens
|
137
|
+
puts "number of tokens : #{tokens.size}"
|
138
|
+
puts "tokenized in : #{t2-t1} s"
|
139
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require_relative 'indent'
|
3
|
+
require_relative '<%=mm.name.to_s.downcase%>_lexer'
|
4
|
+
require_relative '<%=mm.name.to_s.downcase%>_ast'
|
5
|
+
|
6
|
+
module <%=mm.name%>
|
7
|
+
|
8
|
+
class Parser
|
9
|
+
include Indent #helper methods mixed in
|
10
|
+
|
11
|
+
attr_accessor :lexer,:tokens
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@verbose=false
|
15
|
+
@lexer=Lexer.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse filename
|
19
|
+
str=::IO.read(filename)
|
20
|
+
@tokens=lexer.tokenize(str)
|
21
|
+
last_pos = @tokens.last.pos
|
22
|
+
@tokens << Token.new([:eos,'',last_pos])
|
23
|
+
pp @tokens if @verbose
|
24
|
+
parse<%=mm.classes.first.name%>
|
25
|
+
end
|
26
|
+
|
27
|
+
def acceptIt
|
28
|
+
tok=tokens.shift
|
29
|
+
say "consuming #{tok.val} (#{tok.kind})"
|
30
|
+
tok
|
31
|
+
end
|
32
|
+
|
33
|
+
def showNext n=0
|
34
|
+
tokens[n]
|
35
|
+
end
|
36
|
+
|
37
|
+
def expect kind
|
38
|
+
if (actual=showNext.kind)!=kind
|
39
|
+
abort "ERROR at #{showNext.pos}. Expecting #{kind}. Got #{actual}"
|
40
|
+
else
|
41
|
+
return acceptIt()
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def nil_maybe?
|
46
|
+
if showNext.is_a?(:nil)
|
47
|
+
return acceptIt
|
48
|
+
else
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_comments
|
54
|
+
ret=nil
|
55
|
+
while showNext.is_a? :m3e_comment
|
56
|
+
str||=""
|
57
|
+
str << acceptIt.val
|
58
|
+
end
|
59
|
+
if str
|
60
|
+
ret=Token.new([:comment,str,[0,0]])
|
61
|
+
end
|
62
|
+
ret
|
63
|
+
end
|
64
|
+
<%=parsing_methods%>
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
if $PROGRAM_NAME == __FILE__
|
69
|
+
filename=ARGV[0]
|
70
|
+
raise "need a file !" if filename.nil?
|
71
|
+
t1 = Time.now
|
72
|
+
<%=mm.name%>::Parser.new.parse(filename)
|
73
|
+
t2 = Time.now
|
74
|
+
puts "parsed in : #{t2-t1} s"
|
75
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require_relative '<%=mm.name.to_s.downcase%>_ast'
|
3
|
+
require_relative 'indent'
|
4
|
+
require_relative 'code'
|
5
|
+
|
6
|
+
module <%=mm.name%>
|
7
|
+
|
8
|
+
class PrettyPrinter
|
9
|
+
|
10
|
+
include Indent
|
11
|
+
|
12
|
+
def print ast
|
13
|
+
ary=ast.accept(self)
|
14
|
+
str=prpr(ary)
|
15
|
+
end
|
16
|
+
|
17
|
+
def prpr ary
|
18
|
+
print_rec(ary).lstrip
|
19
|
+
end
|
20
|
+
|
21
|
+
def print_rec ary,indent=0
|
22
|
+
str=""
|
23
|
+
case e=ary
|
24
|
+
when Array
|
25
|
+
str << "\n"
|
26
|
+
if e.first.to_s.start_with? "#"
|
27
|
+
str << " "*indent+ary.shift+"\n"
|
28
|
+
end
|
29
|
+
str << " "*indent+"("
|
30
|
+
ary.each do |e|
|
31
|
+
str << print_rec(e,indent+2)
|
32
|
+
end
|
33
|
+
if ary.last.is_a? Array
|
34
|
+
str << "\n"+" "*indent+")"
|
35
|
+
else
|
36
|
+
str<< "\b)"
|
37
|
+
end
|
38
|
+
else
|
39
|
+
str << e.to_s+ " "
|
40
|
+
end
|
41
|
+
return str
|
42
|
+
end
|
43
|
+
|
44
|
+
<%=visiting_methods%>
|
45
|
+
end #class
|
46
|
+
end #module
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '<%=mm.name.to_s.downcase%>_ast'
|
2
|
+
require_relative 'indent'
|
3
|
+
require_relative 'code'
|
4
|
+
|
5
|
+
module <%=mm.name%>
|
6
|
+
|
7
|
+
class Visitor
|
8
|
+
|
9
|
+
include Indent
|
10
|
+
|
11
|
+
def visit ast
|
12
|
+
@verbose=true
|
13
|
+
ast.accept(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
<%=visiting_methods%>
|
17
|
+
end #class
|
18
|
+
end #module
|
data/lib/version.rb
ADDED
data/lib/visitor.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'ast'
|
2
|
+
require_relative 'indent'
|
3
|
+
require_relative 'code'
|
4
|
+
|
5
|
+
module Astrapi
|
6
|
+
|
7
|
+
class Visitor
|
8
|
+
|
9
|
+
include Indent
|
10
|
+
|
11
|
+
def visit ast
|
12
|
+
ast.accept(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def visitModule modul,args=nil
|
16
|
+
indent "visitModule"
|
17
|
+
name=modul.name.accept(self)
|
18
|
+
modul.classes.each{|k| k.accept(self)}
|
19
|
+
dedent
|
20
|
+
end
|
21
|
+
|
22
|
+
def visitKlass klass,args=nil
|
23
|
+
indent "visitKlass #{klass.name.sym}"
|
24
|
+
klass.inheritance.accept(self)
|
25
|
+
klass.attrs.each{|attr| attr.accept(self)}
|
26
|
+
dedent
|
27
|
+
end
|
28
|
+
|
29
|
+
def visitAttr attr,args=nil
|
30
|
+
indent "visitAttr"
|
31
|
+
attr.name.accept(self)
|
32
|
+
attr.type.accept(self)
|
33
|
+
dedent
|
34
|
+
end
|
35
|
+
|
36
|
+
def visitType type,args=nil
|
37
|
+
indent "visitType"
|
38
|
+
end
|
39
|
+
|
40
|
+
def visitArrayOf arrayOf,args=nil
|
41
|
+
indent "visitArrayOf"
|
42
|
+
arrayOf.type.accept(self)
|
43
|
+
dedent
|
44
|
+
end
|
45
|
+
|
46
|
+
def visitIdentifier id,args=nil
|
47
|
+
indent "visitIdentifier"
|
48
|
+
say " - #{id.sym}"
|
49
|
+
dedent
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/tests/geometry.mm
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Geometry
|
2
|
+
|
3
|
+
class Scene
|
4
|
+
attr name => IDENT
|
5
|
+
attr elements => Shape[]
|
6
|
+
end
|
7
|
+
|
8
|
+
class Shape
|
9
|
+
attr id => IDENT
|
10
|
+
attr position => Position
|
11
|
+
end
|
12
|
+
|
13
|
+
class Square < Shape
|
14
|
+
attr size => Size
|
15
|
+
end
|
16
|
+
|
17
|
+
class Circle < Shape
|
18
|
+
attr radius => Size
|
19
|
+
end
|
20
|
+
|
21
|
+
class Rectangle < Shape
|
22
|
+
attr size => Size
|
23
|
+
end
|
24
|
+
|
25
|
+
class Size
|
26
|
+
attr dims => INTEGER[]
|
27
|
+
end
|
28
|
+
|
29
|
+
class Position
|
30
|
+
attr coord => INTEGER[]
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: astrapi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jean-Christophe Le Lann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-17 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Starting from the metamodel of a DSL (abstract classes and their relationship),
|
14
|
+
Astrapi generates a compiler front end for this DSL. The model itself is expressed
|
15
|
+
in S-expressions
|
16
|
+
email: lelannje@ensta-bretagne.fr
|
17
|
+
executables:
|
18
|
+
- astrapi
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- bin/astrapi
|
23
|
+
- doc/astrapi.html
|
24
|
+
- lib/ast.rb
|
25
|
+
- lib/checker.rb
|
26
|
+
- lib/class_diagram_printer.rb
|
27
|
+
- lib/code.rb
|
28
|
+
- lib/compiler.rb
|
29
|
+
- lib/dbg.rb
|
30
|
+
- lib/dot_printer.rb
|
31
|
+
- lib/indent.rb
|
32
|
+
- lib/lexer.rb
|
33
|
+
- lib/parser.rb
|
34
|
+
- lib/pretty_printer.rb
|
35
|
+
- lib/ruby_generator.rb
|
36
|
+
- lib/template_ast_printer.rb
|
37
|
+
- lib/template_code.rb
|
38
|
+
- lib/template_compiler.rb
|
39
|
+
- lib/template_indent.rb
|
40
|
+
- lib/template_lexer.rb
|
41
|
+
- lib/template_parser.rb
|
42
|
+
- lib/template_pretty_printer.rb
|
43
|
+
- lib/template_visitor.rb
|
44
|
+
- lib/version.rb
|
45
|
+
- lib/visitor.rb
|
46
|
+
- tests/geometry.mm
|
47
|
+
homepage: http://www.jcll.fr/astrapi.html
|
48
|
+
licenses:
|
49
|
+
- MIT
|
50
|
+
metadata: {}
|
51
|
+
post_install_message: Thanks for installing! A small doc & examples are in astrapi/doc
|
52
|
+
and astrapi/tests.
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 2.0.0
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 2.4.6
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: meta-compiler for S-expression based Domain Specific Languages (DSL)
|
72
|
+
test_files: []
|