luobo 0.0.1
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.
- data/README.rdoc +7 -0
- data/Rakefile +3 -0
- data/bin/tuzi +12 -0
- data/example/parser.lub +111 -0
- data/lib/luobo.rb +5 -0
- data/lib/luobo/base.rb +211 -0
- data/lib/luobo/driver.rb +46 -0
- data/lib/luobo/token.rb +28 -0
- data/lib/luobo/version.rb +4 -0
- data/luobo.gemspec +18 -0
- data/spec/driver_spec.rb +30 -0
- data/spec/parser_spec.rb +78 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/token_spec.rb +32 -0
- metadata +102 -0
data/README.rdoc
ADDED
data/Rakefile
ADDED
data/bin/tuzi
ADDED
data/example/parser.lub
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
DRIVER: ast
|
2
|
+
|
3
|
+
Raw line passed as it is.
|
4
|
+
AST: Raw line passed as it is.
|
5
|
+
|
6
|
+
## SPLIT: abc df
|
7
|
+
AST: abc
|
8
|
+
AST: df
|
9
|
+
|
10
|
+
Raw line contains ->
|
11
|
+
fake block
|
12
|
+
AST: Raw line contains -> ->
|
13
|
+
AST: 2,fake block
|
14
|
+
|
15
|
+
## SPEC: a spec blog ->
|
16
|
+
do that
|
17
|
+
do this
|
18
|
+
## SPEC: nested spec ->
|
19
|
+
redo that
|
20
|
+
redo this
|
21
|
+
doing outside
|
22
|
+
doing further outside
|
23
|
+
AST: spec "a spec blog" do
|
24
|
+
AST: 2,do that
|
25
|
+
AST: 2,do this
|
26
|
+
AST: end
|
27
|
+
AST: 2,spec "nested spec" do
|
28
|
+
AST: 4,redo that
|
29
|
+
AST: 4,redo this
|
30
|
+
AST: 2,end
|
31
|
+
AST: 2,doing outside
|
32
|
+
AST: doing further outside
|
33
|
+
|
34
|
+
% =================
|
35
|
+
Give me a loop for <%= loop_name %>
|
36
|
+
SPEC: and has spec <%= loop_spec %> ->
|
37
|
+
specify a value as <%= value %>
|
38
|
+
% -----
|
39
|
+
% loop_name: looper
|
40
|
+
% loop_spec: spec a loop
|
41
|
+
% value: 89
|
42
|
+
% -----
|
43
|
+
% loop_name: looper again
|
44
|
+
% loop_spec: spec a loop again
|
45
|
+
% value: 899090
|
46
|
+
AST: Give me a loop for looper
|
47
|
+
AST: spec "and has spec spec a loop" do
|
48
|
+
AST: 2,specify a value as 89
|
49
|
+
AST: end
|
50
|
+
AST: Give me a loop for looper again
|
51
|
+
AST: spec "and has spec spec a loop again" do
|
52
|
+
AST: 2,specify a value as 899090
|
53
|
+
AST: end
|
54
|
+
|
55
|
+
Test a loop inside a block argument
|
56
|
+
AST: Test a loop inside a block argument
|
57
|
+
|
58
|
+
SPEC: loop inside ->
|
59
|
+
% ========================
|
60
|
+
key value <%= store %>
|
61
|
+
% -----
|
62
|
+
% store: factory
|
63
|
+
% -----
|
64
|
+
% store: firm
|
65
|
+
% ------
|
66
|
+
% store: person
|
67
|
+
|
68
|
+
AST: spec "loop inside" do
|
69
|
+
AST: 2, key value factory
|
70
|
+
AST: 2, key value firm
|
71
|
+
AST: 2, key value person
|
72
|
+
AST: end
|
73
|
+
|
74
|
+
Pure raw test in indent
|
75
|
+
Indent with 1 level
|
76
|
+
Indent with 2 levels
|
77
|
+
|
78
|
+
Indent with 2 levels again
|
79
|
+
Back!
|
80
|
+
|
81
|
+
AST: Pure raw test in indent
|
82
|
+
AST: 2,Indent with 1 level
|
83
|
+
AST: 4,Indent with 2 levels
|
84
|
+
AST: 4,Indent with 2 levels again
|
85
|
+
AST: Back!
|
86
|
+
|
87
|
+
UNKNOWN: unknown processor name treated as it is
|
88
|
+
AST: UNKNOWN: unknown processor name treated as it is
|
89
|
+
|
90
|
+
UNKBLOK: unknown with a block ->
|
91
|
+
This is quite strange!
|
92
|
+
Send back.
|
93
|
+
AST: UNKBLOK: unknown with a block -> ->
|
94
|
+
AST: 2,This is quite strange!
|
95
|
+
AST: Send back.
|
96
|
+
|
97
|
+
HASH: key_name: value_name
|
98
|
+
AST: key: key_name
|
99
|
+
AST: value: value_name
|
100
|
+
|
101
|
+
HASH: ->
|
102
|
+
blockkey: blockvalue
|
103
|
+
blockkey2: blockvalue2
|
104
|
+
blockkey3: blockvalue3
|
105
|
+
|
106
|
+
AST: key: blockkey
|
107
|
+
AST: value: blockvalue
|
108
|
+
AST: key: blockkey2
|
109
|
+
AST: value: blockvalue2
|
110
|
+
AST: key: blockkey3
|
111
|
+
AST: value: blockvalue3
|
data/lib/luobo.rb
ADDED
data/lib/luobo/base.rb
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "erubis"
|
4
|
+
|
5
|
+
module Luobo
|
6
|
+
## entry class for the carrot module
|
7
|
+
class Base
|
8
|
+
attr_accessor :driver
|
9
|
+
def initialize file, output
|
10
|
+
@source_file = file
|
11
|
+
|
12
|
+
@output = output.is_a?(IO) ? output : File.open(output, "w")
|
13
|
+
|
14
|
+
# initialize:
|
15
|
+
@token_stack = Array.new
|
16
|
+
|
17
|
+
# initialize loop template and examples
|
18
|
+
self.reset_loop
|
19
|
+
end
|
20
|
+
|
21
|
+
# initialize the holders for a example based loop,
|
22
|
+
# or reset after a loop expansion
|
23
|
+
def reset_loop
|
24
|
+
@loop_start_ln = 0
|
25
|
+
@loop_template = nil
|
26
|
+
@loop_examples = Array.new
|
27
|
+
end
|
28
|
+
|
29
|
+
# extend a loop be examples
|
30
|
+
def expand_loop
|
31
|
+
raise "no examples found for loop start on line #{@loop_start_ln}" unless @loop_examples.size > 0
|
32
|
+
loop_n = 0
|
33
|
+
@loop_examples.each do |exa|
|
34
|
+
loop_n += 1
|
35
|
+
vars = YAML.load(exa)
|
36
|
+
# erubie the template
|
37
|
+
rslt = Erubis::Eruby.new(@loop_template).result(vars)
|
38
|
+
li = 0
|
39
|
+
rslt.split("\n").each do |line|
|
40
|
+
li += 1
|
41
|
+
self.process_line line, @loop_start_ln + li, loop_n
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# clear up holders
|
46
|
+
self.reset_loop
|
47
|
+
end
|
48
|
+
|
49
|
+
def dump contents
|
50
|
+
@output.print contents if contents
|
51
|
+
end
|
52
|
+
|
53
|
+
# travel up through the token stack, close all token with
|
54
|
+
# indent level larger or equal to the parameter
|
55
|
+
def close_stack indent_level
|
56
|
+
source = ''
|
57
|
+
while @token_stack.size > 0 and @token_stack[-1].indent_level >= indent_level
|
58
|
+
if @token_stack.size > 1
|
59
|
+
@token_stack[-2].add_block_code @driver.convert(@token_stack[-1])
|
60
|
+
else # this is the last token in the stack
|
61
|
+
self.dump(@driver.convert(@token_stack[-1]))
|
62
|
+
end
|
63
|
+
@token_stack.pop
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# add a new line to the existing token if it requires block codes
|
68
|
+
# or write the last token out before a new token
|
69
|
+
# this function invokes after a loop expansion.
|
70
|
+
def process_line line, ln, loop_n = 0
|
71
|
+
indent_level = 0
|
72
|
+
if /^(?<head_space_>\s+)/ =~ line
|
73
|
+
indent_level = head_space_.size
|
74
|
+
end
|
75
|
+
|
76
|
+
# try to close stack if applicable
|
77
|
+
self.close_stack indent_level
|
78
|
+
|
79
|
+
# starts a named_processor or starts a raw_processor
|
80
|
+
processor_name = '_raw'
|
81
|
+
line_code = line.gsub(/^\s*/,"")
|
82
|
+
block_code = nil
|
83
|
+
if matches = /#{regex_proc_line}/.match(line)
|
84
|
+
processor_name = matches["proc_name_"]
|
85
|
+
line_code = matches["line_code_"]
|
86
|
+
block_code = '' if line_code.gsub!(/#{regex_block_start}/, '')
|
87
|
+
end
|
88
|
+
|
89
|
+
@token_stack << Token.new(ln, line, indent_level, processor_name, line_code, block_code)
|
90
|
+
|
91
|
+
# unless it opens for block code close it soon,
|
92
|
+
# (dedicate the dump function to close_stack())
|
93
|
+
self.close_stack indent_level unless block_code
|
94
|
+
end
|
95
|
+
|
96
|
+
# add a new line to the example, separate examples to array
|
97
|
+
def add_example_line line
|
98
|
+
if /#{regex_new_example}/.match(line)
|
99
|
+
# start a new loop example with a placeholder nil
|
100
|
+
@loop_examples << nil
|
101
|
+
else
|
102
|
+
raise "you need use '#{regex_new_example}' to start a loop example" unless @loop_examples.size > 0
|
103
|
+
line.gsub!(/#{regex_example_head}/, '')
|
104
|
+
@loop_examples[-1] = @loop_examples[-1] ? @loop_examples[-1] + "\n" + line : line
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# regex configurations
|
109
|
+
# match characters before a processor keyword
|
110
|
+
def regex_proc_head
|
111
|
+
"\s*(\#{2,}|\-{2,}|\/{2,})?\s*"
|
112
|
+
end
|
113
|
+
|
114
|
+
def regex_proc_name
|
115
|
+
"(?<proc_name_>[A-Z][A-Z0-9_]+)"
|
116
|
+
end
|
117
|
+
|
118
|
+
def regex_proc_end
|
119
|
+
"\s*\:?\s*"
|
120
|
+
end
|
121
|
+
|
122
|
+
def regex_proc_line
|
123
|
+
"^" + regex_proc_head + regex_proc_name + regex_proc_end + "(?<line_code_>.+)"
|
124
|
+
end
|
125
|
+
|
126
|
+
def regex_block_start
|
127
|
+
"\s*(?<block_start_>\-\>)?\s*$"
|
128
|
+
end
|
129
|
+
|
130
|
+
def regex_loop_line
|
131
|
+
"^" + regex_proc_head + "\%\s*\=\=\=\=+\s*"
|
132
|
+
end
|
133
|
+
|
134
|
+
def regex_new_example
|
135
|
+
"^" + regex_proc_head + "\%\s*\-\-\-\-+\s*"
|
136
|
+
end
|
137
|
+
|
138
|
+
def regex_example_head
|
139
|
+
"^" + regex_proc_head + "\%\s*"
|
140
|
+
end
|
141
|
+
|
142
|
+
def regex_example_line
|
143
|
+
"^" + regex_proc_head + "\%\s*(?<example_>.+)\s*"
|
144
|
+
end
|
145
|
+
|
146
|
+
# parse the file, whenever found a token, use driver to convert
|
147
|
+
# it and send to output
|
148
|
+
def process
|
149
|
+
in_loop = false
|
150
|
+
in_example = false
|
151
|
+
|
152
|
+
fh = File.open(@source_file, 'r:utf-8')
|
153
|
+
fh.each do |line|
|
154
|
+
line.chomp!
|
155
|
+
line.gsub!("\t", " ") # convert tab to 2 spaces
|
156
|
+
|
157
|
+
# ensure first line as driver definition
|
158
|
+
unless @driver
|
159
|
+
if matches = /^#{regex_proc_head}DRIVER#{regex_proc_end}(?<dname_>\w+)\s*$/.match(line)
|
160
|
+
@driver = Driver.create(matches["dname_"])
|
161
|
+
self.dump(@driver.setup)
|
162
|
+
next
|
163
|
+
else
|
164
|
+
raise "You must specify a driver on the first line"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# interrupt for loops
|
169
|
+
if matches = /#{regex_loop_line}/.match(line)
|
170
|
+
in_loop = true
|
171
|
+
@loop_start_ln = $.
|
172
|
+
next
|
173
|
+
end
|
174
|
+
|
175
|
+
# expand and end current loop
|
176
|
+
if in_example
|
177
|
+
unless /#{regex_example_head}/.match(line)
|
178
|
+
self.expand_loop
|
179
|
+
in_example = false
|
180
|
+
in_loop = false
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# end a loop template and start a loop example
|
185
|
+
if in_loop
|
186
|
+
in_example = true if /#{regex_example_head}/.match(line)
|
187
|
+
end
|
188
|
+
|
189
|
+
# dispatch the current line to different holders
|
190
|
+
if in_example
|
191
|
+
self.add_example_line line
|
192
|
+
elsif in_loop
|
193
|
+
@loop_template = @loop_template ? @loop_template + "\n" + line : line
|
194
|
+
else
|
195
|
+
self.process_line line, $.
|
196
|
+
end
|
197
|
+
end
|
198
|
+
fh.close
|
199
|
+
|
200
|
+
# do not forget expand last loop if it reaches over EOF.
|
201
|
+
self.expand_loop if @loop_start_ln > 0
|
202
|
+
|
203
|
+
# close all remain stacks
|
204
|
+
self.close_stack 0
|
205
|
+
|
206
|
+
self.dump(@driver.exit)
|
207
|
+
@output.close
|
208
|
+
self
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
data/lib/luobo/driver.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Luobo
|
4
|
+
class Driver
|
5
|
+
|
6
|
+
## implements the factory pattern
|
7
|
+
@@drivers = {}
|
8
|
+
|
9
|
+
def self.create type
|
10
|
+
c = @@drivers[type.to_sym]
|
11
|
+
raise "No registered driver for type #{type.to_s}" unless c
|
12
|
+
c.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.register_driver type
|
16
|
+
raise "Driver for #{type.to_s} already registed." if @@drivers[type.to_sym]
|
17
|
+
@@drivers[type.to_sym] = self
|
18
|
+
end
|
19
|
+
|
20
|
+
## cross-drivers methods and callbacks
|
21
|
+
def convert token
|
22
|
+
pname = "do_" + token.processor_name.downcase
|
23
|
+
if self.respond_to?(pname)
|
24
|
+
self.send(pname.to_sym, token)
|
25
|
+
else
|
26
|
+
self.do__missing(token)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def exit; end
|
31
|
+
def setup; end
|
32
|
+
|
33
|
+
def indent token
|
34
|
+
" " * token.indent_level
|
35
|
+
end
|
36
|
+
|
37
|
+
def do__raw token
|
38
|
+
indent(token) + token.line_code.gsub(/^\s*/, "") + "\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
def do__missing token
|
42
|
+
src = indent(token) + token.line
|
43
|
+
src += token.block_code + "\n" if token.block_code
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/luobo/token.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Luobo
|
2
|
+
## this class holds a block of carrot source code tokenized by the parser.
|
3
|
+
class Token
|
4
|
+
attr_accessor :ln, :line, :indent_level, :processor_name, :line_code, :block_code
|
5
|
+
|
6
|
+
def initialize ln, line, indent_level, processor_name, line_code, block_code
|
7
|
+
@ln, @line, @indent_level, @processor_name, @line_code, @block_code = ln, line, indent_level, processor_name, line_code, block_code
|
8
|
+
end
|
9
|
+
|
10
|
+
# add a line to current block args, separate each line with "\n"
|
11
|
+
def add_block_code line
|
12
|
+
line.chomp!
|
13
|
+
if self.block_code
|
14
|
+
self.block_code += "\n" + line
|
15
|
+
else
|
16
|
+
self.block_code = line
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def block_args
|
21
|
+
YAML.load(block_code)
|
22
|
+
end
|
23
|
+
|
24
|
+
def line_args
|
25
|
+
YAML.load(line_code)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/luobo.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
require 'luobo/version'
|
3
|
+
|
4
|
+
Gem::Specification.new 'luobo', Luobo::VERSION do |s|
|
5
|
+
s.description = "Luobo is a simple, easy to extend code generator."
|
6
|
+
s.summary = "Easy to extend code generator"
|
7
|
+
s.authors = ["Huang Wei"]
|
8
|
+
s.email = "huangw@pe-po.com"
|
9
|
+
s.homepage = "https://github.com/huangw/luobo-gem"
|
10
|
+
s.executables << "tuzi"
|
11
|
+
s.files = `git ls-files`.split("\n") - %w[.gitignore]
|
12
|
+
s.test_files = Dir.glob("{spec,test}/**/*.rb")
|
13
|
+
s.rdoc_options = %w[--line-numbers --inline-source --title Luobo --main README.rdoc --encoding=UTF-8]
|
14
|
+
|
15
|
+
s.add_development_dependency 'rspec', '~> 2.5'
|
16
|
+
s.add_dependency 'erubis'
|
17
|
+
end
|
18
|
+
|
data/spec/driver_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Luobo::Driver do
|
4
|
+
class TestDriver < Luobo::Driver
|
5
|
+
def do_test_met(tk)
|
6
|
+
"test method"
|
7
|
+
end
|
8
|
+
register_driver :test_driver
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "create test driver" do
|
12
|
+
subject(:test_driver) do
|
13
|
+
Luobo::Driver.create(:test_driver)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "is a test driver object" do
|
17
|
+
test_driver.is_a?(TestDriver).should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
its :class do
|
21
|
+
should eq(TestDriver)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "inherit driver methods" do
|
25
|
+
tk = Luobo::Token.new(1, '', 1, 'test_met', '', '')
|
26
|
+
test_driver.convert(tk).should eq("test method")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Luobo::Base do
|
4
|
+
class OutputHolder < IO
|
5
|
+
attr_accessor :text
|
6
|
+
def initialize; @text = {} end
|
7
|
+
def print(str)
|
8
|
+
str.split("\n").each {|t| @text[t] = true}
|
9
|
+
end
|
10
|
+
def close; end
|
11
|
+
end
|
12
|
+
|
13
|
+
class AstDriver < Luobo::Driver
|
14
|
+
attr_accessor :asserts
|
15
|
+
def initialize
|
16
|
+
super()
|
17
|
+
@asserts = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def do_ast token
|
21
|
+
str = ''
|
22
|
+
if /(?<ident_>\d+),\s*(?<rm_>.+)/ =~ token.line_code
|
23
|
+
str = " "*ident_.to_i + rm_
|
24
|
+
else
|
25
|
+
str = token.line_code
|
26
|
+
end
|
27
|
+
@asserts << str
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def do_split token
|
32
|
+
src = ""
|
33
|
+
token.line_code.split(/\s+/).each do |line|
|
34
|
+
src += line + "\n"
|
35
|
+
end
|
36
|
+
src
|
37
|
+
end
|
38
|
+
|
39
|
+
def do_spec token
|
40
|
+
src = indent(token) + "spec \"#{token.line_code}\" do"
|
41
|
+
src += token.block_code ? token.block_code : ""
|
42
|
+
src += "\n" + indent(token) + "end\n"
|
43
|
+
src
|
44
|
+
end
|
45
|
+
|
46
|
+
def do_hash token
|
47
|
+
hash = token.line_args if token.line_code.size > 0
|
48
|
+
if token.block_code.size > 0
|
49
|
+
hash = hash.is_a?(Hash) ? hash.merge(token.block_args) : token.block_args
|
50
|
+
end
|
51
|
+
src = ""
|
52
|
+
hash.each do |k,v|
|
53
|
+
src += indent(token) + "key: #{k}\n"
|
54
|
+
src += indent(token) + "value: #{v}\n"
|
55
|
+
end
|
56
|
+
src
|
57
|
+
end
|
58
|
+
|
59
|
+
register_driver :ast
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "convert" do
|
63
|
+
oh = OutputHolder.new
|
64
|
+
base = Luobo::Base.new("example/parser.lub", oh).process
|
65
|
+
|
66
|
+
it "base should have a AstDriver" do
|
67
|
+
base.driver.is_a?(AstDriver)
|
68
|
+
p oh.text
|
69
|
+
end
|
70
|
+
|
71
|
+
base.driver.asserts.each do |line|
|
72
|
+
it "can parse #{line}" do
|
73
|
+
oh.text[line].should be_true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/token_spec.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Luobo::Token do
|
4
|
+
subject (:token) do
|
5
|
+
Luobo::Token.new(1, "line", 4, "Echo", "same: hash", "['block', 'in', 'array']")
|
6
|
+
end
|
7
|
+
|
8
|
+
its :ln do
|
9
|
+
should eq(1)
|
10
|
+
end
|
11
|
+
|
12
|
+
its :line do
|
13
|
+
should eq("line")
|
14
|
+
end
|
15
|
+
|
16
|
+
its :indent_level do
|
17
|
+
should eq(4)
|
18
|
+
end
|
19
|
+
|
20
|
+
its :processor_name do
|
21
|
+
should eq("Echo")
|
22
|
+
end
|
23
|
+
|
24
|
+
its :line_args do
|
25
|
+
token.line_args["same"].should eq("hash")
|
26
|
+
end
|
27
|
+
|
28
|
+
its :block_args do
|
29
|
+
token.block_args[2].should eq("array")
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: luobo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Huang Wei
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.5'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.5'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: erubis
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Luobo is a simple, easy to extend code generator.
|
47
|
+
email: huangw@pe-po.com
|
48
|
+
executables:
|
49
|
+
- tuzi
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- README.rdoc
|
54
|
+
- Rakefile
|
55
|
+
- bin/tuzi
|
56
|
+
- example/parser.lub
|
57
|
+
- lib/luobo.rb
|
58
|
+
- lib/luobo/base.rb
|
59
|
+
- lib/luobo/driver.rb
|
60
|
+
- lib/luobo/token.rb
|
61
|
+
- lib/luobo/version.rb
|
62
|
+
- luobo.gemspec
|
63
|
+
- spec/driver_spec.rb
|
64
|
+
- spec/parser_spec.rb
|
65
|
+
- spec/spec_helper.rb
|
66
|
+
- spec/token_spec.rb
|
67
|
+
homepage: https://github.com/huangw/luobo-gem
|
68
|
+
licenses: []
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options:
|
71
|
+
- --line-numbers
|
72
|
+
- --inline-source
|
73
|
+
- --title
|
74
|
+
- Luobo
|
75
|
+
- --main
|
76
|
+
- README.rdoc
|
77
|
+
- --encoding=UTF-8
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.8.24
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Easy to extend code generator
|
98
|
+
test_files:
|
99
|
+
- spec/driver_spec.rb
|
100
|
+
- spec/parser_spec.rb
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
- spec/token_spec.rb
|