manamana 0.0.1 → 0.0.2
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/.gitignore +0 -1
- data/Gemfile +11 -0
- data/Gemfile.lock +58 -0
- data/Guardfile +27 -0
- data/Rakefile +42 -0
- data/bin/mana +7 -0
- data/lib/manamana/compiler.rb +63 -0
- data/lib/manamana/rdsl/lexer.rb +484 -0
- data/lib/manamana/rdsl/nodes.rb +97 -0
- data/lib/manamana/rdsl/parser.rb +311 -0
- data/lib/manamana/runner.rb +27 -0
- data/lib/manamana/steps.rb +49 -0
- data/lib/manamana/tdsl/lexer.rb +483 -0
- data/lib/manamana/tdsl/nodes.rb +149 -0
- data/lib/manamana/tdsl/parser.rb +282 -0
- data/lib/manamana/version.rb +2 -2
- data/lib/manamana.rb +6 -5
- data/manamana.gemspec +4 -2
- data/src/rdsl/lexer.rl +86 -0
- data/src/rdsl/parser.y +71 -0
- data/src/tdsl/lexer.rl +76 -0
- data/src/tdsl/parser.y +74 -0
- data/test/lib/manamana/rdsl/lexer_test.rb +171 -0
- data/test/lib/manamana/rdsl/parser_test.rb +189 -0
- data/test/lib/manamana/rdsl/requirements_node_test.rb +36 -0
- data/test/lib/manamana/tdsl/lexer_test.rb +72 -0
- data/test/lib/manamana/tdsl/parser_test.rb +171 -0
- data/test/lib/manamana/tdsl/test_case_node_test.rb +122 -0
- data/test/lib/manamana/version_test.rb +9 -0
- data/test/test_helper.rb +21 -0
- metadata +61 -6
@@ -0,0 +1,282 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by Racc 1.4.9
|
4
|
+
# from Racc grammer file "".
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'racc/parser.rb'
|
8
|
+
|
9
|
+
require 'manamana/tdsl/lexer'
|
10
|
+
require 'manamana/tdsl/nodes'
|
11
|
+
|
12
|
+
module ManaMana
|
13
|
+
module TDSL
|
14
|
+
class Parser < Racc::Parser
|
15
|
+
|
16
|
+
module_eval(<<'...end parser.y/module_eval...', 'parser.y', 66)
|
17
|
+
def parse(code, show_tokens=false)
|
18
|
+
@tokens = Lexer.new.tokenize(code)
|
19
|
+
puts @tokens.inspect if show_tokens
|
20
|
+
do_parse
|
21
|
+
end
|
22
|
+
|
23
|
+
def next_token
|
24
|
+
@tokens.shift
|
25
|
+
end
|
26
|
+
...end parser.y/module_eval...
|
27
|
+
##### State transition tables begin ###
|
28
|
+
|
29
|
+
racc_action_table = [
|
30
|
+
-3, 16, 3, 8, 3, 9, 3, 12, 14, 4,
|
31
|
+
18, 14, 21, 18, 18, 18 ]
|
32
|
+
|
33
|
+
racc_action_check = [
|
34
|
+
3, 11, 3, 3, 0, 4, 6, 7, 8, 1,
|
35
|
+
12, 14, 15, 16, 18, 21 ]
|
36
|
+
|
37
|
+
racc_action_pointer = [
|
38
|
+
2, 9, nil, 0, 5, nil, 4, 3, 1, nil,
|
39
|
+
nil, -4, 3, nil, 4, 6, 6, nil, 7, nil,
|
40
|
+
nil, 8, nil, nil, nil ]
|
41
|
+
|
42
|
+
racc_action_default = [
|
43
|
+
-1, -20, -2, -8, -20, -4, -5, -12, -20, 25,
|
44
|
+
-6, -14, -20, -9, -10, -16, -20, -13, -18, -11,
|
45
|
+
-7, -20, -15, -19, -17 ]
|
46
|
+
|
47
|
+
racc_goto_table = [
|
48
|
+
17, 13, 2, 11, 22, 5, 23, 19, 10, 24,
|
49
|
+
7, 15, 20, 6, 1 ]
|
50
|
+
|
51
|
+
racc_goto_check = [
|
52
|
+
9, 8, 2, 5, 9, 2, 9, 8, 2, 9,
|
53
|
+
4, 6, 7, 3, 1 ]
|
54
|
+
|
55
|
+
racc_goto_pointer = [
|
56
|
+
nil, 14, 2, 10, 7, -4, 0, -3, -7, -12 ]
|
57
|
+
|
58
|
+
racc_goto_default = [
|
59
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ]
|
60
|
+
|
61
|
+
racc_reduce_table = [
|
62
|
+
0, 0, :racc_error,
|
63
|
+
0, 9, :_reduce_1,
|
64
|
+
1, 9, :_reduce_2,
|
65
|
+
1, 10, :_reduce_3,
|
66
|
+
2, 10, :_reduce_4,
|
67
|
+
2, 10, :_reduce_5,
|
68
|
+
3, 10, :_reduce_6,
|
69
|
+
4, 11, :_reduce_7,
|
70
|
+
0, 12, :_reduce_8,
|
71
|
+
2, 12, :_reduce_9,
|
72
|
+
1, 16, :_reduce_10,
|
73
|
+
2, 16, :_reduce_11,
|
74
|
+
0, 13, :_reduce_12,
|
75
|
+
2, 13, :_reduce_13,
|
76
|
+
0, 14, :_reduce_14,
|
77
|
+
2, 14, :_reduce_15,
|
78
|
+
0, 15, :_reduce_16,
|
79
|
+
2, 15, :_reduce_17,
|
80
|
+
1, 17, :_reduce_18,
|
81
|
+
2, 17, :_reduce_19 ]
|
82
|
+
|
83
|
+
racc_reduce_n = 20
|
84
|
+
|
85
|
+
racc_shift_n = 25
|
86
|
+
|
87
|
+
racc_token_table = {
|
88
|
+
false => 0,
|
89
|
+
:error => 1,
|
90
|
+
:TEST_CASE => 2,
|
91
|
+
:VARIABLES => 3,
|
92
|
+
:PRECONDITIONS => 4,
|
93
|
+
:CLEANUP => 5,
|
94
|
+
:SCRIPT => 6,
|
95
|
+
:LINE => 7 }
|
96
|
+
|
97
|
+
racc_nt_base = 8
|
98
|
+
|
99
|
+
racc_use_result_var = true
|
100
|
+
|
101
|
+
Racc_arg = [
|
102
|
+
racc_action_table,
|
103
|
+
racc_action_check,
|
104
|
+
racc_action_default,
|
105
|
+
racc_action_pointer,
|
106
|
+
racc_goto_table,
|
107
|
+
racc_goto_check,
|
108
|
+
racc_goto_default,
|
109
|
+
racc_goto_pointer,
|
110
|
+
racc_nt_base,
|
111
|
+
racc_reduce_table,
|
112
|
+
racc_token_table,
|
113
|
+
racc_shift_n,
|
114
|
+
racc_reduce_n,
|
115
|
+
racc_use_result_var ]
|
116
|
+
|
117
|
+
Racc_token_to_s_table = [
|
118
|
+
"$end",
|
119
|
+
"error",
|
120
|
+
"TEST_CASE",
|
121
|
+
"VARIABLES",
|
122
|
+
"PRECONDITIONS",
|
123
|
+
"CLEANUP",
|
124
|
+
"SCRIPT",
|
125
|
+
"LINE",
|
126
|
+
"$start",
|
127
|
+
"Root",
|
128
|
+
"TestCases",
|
129
|
+
"TestCaseBody",
|
130
|
+
"Variables",
|
131
|
+
"Preconditions",
|
132
|
+
"Cleanup",
|
133
|
+
"Script",
|
134
|
+
"Assignments",
|
135
|
+
"Lines" ]
|
136
|
+
|
137
|
+
Racc_debug_parser = false
|
138
|
+
|
139
|
+
##### State transition tables end #####
|
140
|
+
|
141
|
+
# reduce 0 omitted
|
142
|
+
|
143
|
+
module_eval(<<'.,.,', 'parser.y', 11)
|
144
|
+
def _reduce_1(val, _values, result)
|
145
|
+
result = RootNode.new
|
146
|
+
result
|
147
|
+
end
|
148
|
+
.,.,
|
149
|
+
|
150
|
+
module_eval(<<'.,.,', 'parser.y', 12)
|
151
|
+
def _reduce_2(val, _values, result)
|
152
|
+
result = RootNode.new('', val[0])
|
153
|
+
result
|
154
|
+
end
|
155
|
+
.,.,
|
156
|
+
|
157
|
+
module_eval(<<'.,.,', 'parser.y', 16)
|
158
|
+
def _reduce_3(val, _values, result)
|
159
|
+
result = [ TestCaseNode.new(val[0]) ]
|
160
|
+
result
|
161
|
+
end
|
162
|
+
.,.,
|
163
|
+
|
164
|
+
module_eval(<<'.,.,', 'parser.y', 17)
|
165
|
+
def _reduce_4(val, _values, result)
|
166
|
+
result = [ TestCaseNode.new(val[0]) ] + val[1]
|
167
|
+
result
|
168
|
+
end
|
169
|
+
.,.,
|
170
|
+
|
171
|
+
module_eval(<<'.,.,', 'parser.y', 18)
|
172
|
+
def _reduce_5(val, _values, result)
|
173
|
+
result = [ TestCaseNode.new(val[0], val[1]) ]
|
174
|
+
result
|
175
|
+
end
|
176
|
+
.,.,
|
177
|
+
|
178
|
+
module_eval(<<'.,.,', 'parser.y', 19)
|
179
|
+
def _reduce_6(val, _values, result)
|
180
|
+
result = [ TestCaseNode.new(val[0], val[1]) ] + val[2]
|
181
|
+
result
|
182
|
+
end
|
183
|
+
.,.,
|
184
|
+
|
185
|
+
module_eval(<<'.,.,', 'parser.y', 26)
|
186
|
+
def _reduce_7(val, _values, result)
|
187
|
+
result = val[0].merge(val[1]).merge(val[2]).merge(val[3])
|
188
|
+
result
|
189
|
+
end
|
190
|
+
.,.,
|
191
|
+
|
192
|
+
module_eval(<<'.,.,', 'parser.y', 30)
|
193
|
+
def _reduce_8(val, _values, result)
|
194
|
+
result = { :variables => VariablesNode.new }
|
195
|
+
result
|
196
|
+
end
|
197
|
+
.,.,
|
198
|
+
|
199
|
+
module_eval(<<'.,.,', 'parser.y', 31)
|
200
|
+
def _reduce_9(val, _values, result)
|
201
|
+
result = { :variables => VariablesNode.new('', val[1]) }
|
202
|
+
result
|
203
|
+
end
|
204
|
+
.,.,
|
205
|
+
|
206
|
+
module_eval(<<'.,.,', 'parser.y', 35)
|
207
|
+
def _reduce_10(val, _values, result)
|
208
|
+
result = [ AssignmentNode.new(val[0]) ]
|
209
|
+
result
|
210
|
+
end
|
211
|
+
.,.,
|
212
|
+
|
213
|
+
module_eval(<<'.,.,', 'parser.y', 36)
|
214
|
+
def _reduce_11(val, _values, result)
|
215
|
+
result = [ AssignmentNode.new(val[0]) ] + val[1]
|
216
|
+
result
|
217
|
+
end
|
218
|
+
.,.,
|
219
|
+
|
220
|
+
module_eval(<<'.,.,', 'parser.y', 40)
|
221
|
+
def _reduce_12(val, _values, result)
|
222
|
+
result = { :preconditions => PreconditionsNode.new }
|
223
|
+
result
|
224
|
+
end
|
225
|
+
.,.,
|
226
|
+
|
227
|
+
module_eval(<<'.,.,', 'parser.y', 41)
|
228
|
+
def _reduce_13(val, _values, result)
|
229
|
+
result = { :preconditions => PreconditionsNode.new('', val[1]) }
|
230
|
+
result
|
231
|
+
end
|
232
|
+
.,.,
|
233
|
+
|
234
|
+
module_eval(<<'.,.,', 'parser.y', 45)
|
235
|
+
def _reduce_14(val, _values, result)
|
236
|
+
result = { :cleanup => CleanupNode.new }
|
237
|
+
result
|
238
|
+
end
|
239
|
+
.,.,
|
240
|
+
|
241
|
+
module_eval(<<'.,.,', 'parser.y', 46)
|
242
|
+
def _reduce_15(val, _values, result)
|
243
|
+
result = { :cleanup => CleanupNode.new('', val[1]) }
|
244
|
+
result
|
245
|
+
end
|
246
|
+
.,.,
|
247
|
+
|
248
|
+
module_eval(<<'.,.,', 'parser.y', 50)
|
249
|
+
def _reduce_16(val, _values, result)
|
250
|
+
result = { :script => ScriptNode.new }
|
251
|
+
result
|
252
|
+
end
|
253
|
+
.,.,
|
254
|
+
|
255
|
+
module_eval(<<'.,.,', 'parser.y', 51)
|
256
|
+
def _reduce_17(val, _values, result)
|
257
|
+
result = { :script => ScriptNode.new('', val[1]) }
|
258
|
+
result
|
259
|
+
end
|
260
|
+
.,.,
|
261
|
+
|
262
|
+
module_eval(<<'.,.,', 'parser.y', 55)
|
263
|
+
def _reduce_18(val, _values, result)
|
264
|
+
result = [ StepNode.new(val[0]) ]
|
265
|
+
result
|
266
|
+
end
|
267
|
+
.,.,
|
268
|
+
|
269
|
+
module_eval(<<'.,.,', 'parser.y', 56)
|
270
|
+
def _reduce_19(val, _values, result)
|
271
|
+
result = [ StepNode.new(val[0]) ] + val[1]
|
272
|
+
result
|
273
|
+
end
|
274
|
+
.,.,
|
275
|
+
|
276
|
+
def _reduce_none(val, _values, result)
|
277
|
+
val[0]
|
278
|
+
end
|
279
|
+
|
280
|
+
end # class Parser
|
281
|
+
end # module TDSL
|
282
|
+
end # module ManaMana
|
data/lib/manamana/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module
|
2
|
-
VERSION = "0.0.
|
1
|
+
module ManaMana
|
2
|
+
VERSION = "0.0.2"
|
3
3
|
end
|
data/lib/manamana.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
require 'manamana/version'
|
2
|
+
require 'manamana/rdsl/parser'
|
3
|
+
require 'manamana/tdsl/parser'
|
4
|
+
require 'manamana/steps'
|
5
|
+
require 'manamana/compiler'
|
6
|
+
require 'manamana/runner'
|
data/manamana.gemspec
CHANGED
@@ -6,12 +6,14 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.email = ["mmaglana@gmail.com"]
|
7
7
|
gem.description = %q{Capture project requirements better}
|
8
8
|
gem.summary = %q{Organize your project's requirements and their associated test cases in a way that makes sense to your organization. Then keep track of the status of each as your project progresses.}
|
9
|
-
gem.homepage = "https://github.com/
|
9
|
+
gem.homepage = "https://github.com/ManaManaFramework/manamana"
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
12
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
14
|
gem.name = "manamana"
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.version =
|
16
|
+
gem.version = ManaMana::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'racc', '1.4.9'
|
17
19
|
end
|
data/src/rdsl/lexer.rl
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# lib/manamana/rdsl/lexer.rb is autogenerated by
|
2
|
+
# ragel from src/rdsl/lexer.rl. Please edit the
|
3
|
+
# .rl file and not the .rb file.
|
4
|
+
|
5
|
+
%%{
|
6
|
+
|
7
|
+
machine lexer;
|
8
|
+
|
9
|
+
newline = ('\n' | '\r\n');
|
10
|
+
tab_or_space = [\t ];
|
11
|
+
string = [A-Za-z0-9\(\)\[\]\{\}] print*;
|
12
|
+
req_string = [A-Za-z0-9<] print*;
|
13
|
+
underline = '===' '='*;
|
14
|
+
pipe = '|';
|
15
|
+
|
16
|
+
group_name = string tab_or_space* newline tab_or_space* underline;
|
17
|
+
text = string tab_or_space* (newline tab_or_space* string)* (newline newline)*;
|
18
|
+
requirement = '* ' req_string tab_or_space* (newline tab_or_space* req_string)* (newline newline)*;
|
19
|
+
table_row = pipe print* pipe;
|
20
|
+
|
21
|
+
main := |*
|
22
|
+
|
23
|
+
group_name => { emit_group_name(token_array, data, ts, te) };
|
24
|
+
requirement => { emit_requirement(token_array, data, ts, te) };
|
25
|
+
table_row => { emit_row(data, token_array, ts, te) };
|
26
|
+
text => { emit_text(token_array, data, ts, te) };
|
27
|
+
|
28
|
+
space;
|
29
|
+
|
30
|
+
*|;
|
31
|
+
}%%
|
32
|
+
|
33
|
+
module ManaMana
|
34
|
+
|
35
|
+
module RDSL
|
36
|
+
|
37
|
+
class Lexer
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
%% write data;
|
41
|
+
# %% this just fixes syntax highlighting in TextMate et al.
|
42
|
+
end
|
43
|
+
|
44
|
+
def emit_group_name(token_array, data, ts, te)
|
45
|
+
value = data[ts...te].pack("c*").split(/=+/)[0].strip
|
46
|
+
token_array << [:GROUP, value]
|
47
|
+
end
|
48
|
+
|
49
|
+
def emit_row(data, target_array, ts, te)
|
50
|
+
cells = data[(ts + 1)...( te - 1)].pack("c*")
|
51
|
+
|
52
|
+
# ignore borders
|
53
|
+
return if /^\-+/ =~ cells
|
54
|
+
|
55
|
+
target_array << [:ROW, 'Row']
|
56
|
+
cells.split('|').each do |cell|
|
57
|
+
target_array << [:CELL, cell.strip]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def emit_requirement(token_array, data, ts, te)
|
62
|
+
value = data[ts...te].pack("c*").gsub(/^\* /, '').split.join(' ')
|
63
|
+
token_array << [:REQUIREMENT, value]
|
64
|
+
end
|
65
|
+
|
66
|
+
def emit_text(token_array, data, ts, te)
|
67
|
+
value = data[ts...te].pack("c*").strip.split.join(' ')
|
68
|
+
token_array << [:TEXT, value]
|
69
|
+
end
|
70
|
+
|
71
|
+
def tokenize(data)
|
72
|
+
data = data.unpack("c*") if(data.is_a?(String))
|
73
|
+
eof = data.length
|
74
|
+
token_array = []
|
75
|
+
|
76
|
+
%% write init;
|
77
|
+
%% write exec;
|
78
|
+
|
79
|
+
token_array
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
data/src/rdsl/parser.y
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
class ManaMana::RDSL::Parser
|
2
|
+
|
3
|
+
token GROUP
|
4
|
+
token REQUIREMENT
|
5
|
+
token TEXT
|
6
|
+
token ROW
|
7
|
+
token CELL
|
8
|
+
|
9
|
+
rule
|
10
|
+
Root:
|
11
|
+
/* empty array */ { result = RootNode.new }
|
12
|
+
| Groups { result = RootNode.new('', val[0]) }
|
13
|
+
;
|
14
|
+
|
15
|
+
Groups:
|
16
|
+
GROUP { result = [ GroupNode.new(val[0]) ] }
|
17
|
+
| GROUP Text { result = [ GroupNode.new(val[0]) ] }
|
18
|
+
| GROUP Groups { result = [ GroupNode.new(val[0]) ] + val[1] }
|
19
|
+
| GROUP Requirements { result = [ GroupNode.new(val[0], val[1]) ] }
|
20
|
+
| GROUP Text Requirements { result = [ GroupNode.new(val[0], val[2]) ] }
|
21
|
+
| GROUP Requirements Groups { result = [ GroupNode.new(val[0], val[1]) ] + val[2] }
|
22
|
+
;
|
23
|
+
|
24
|
+
Requirements:
|
25
|
+
REQUIREMENT { result = [ RequirementNode.new(val[0]) ] }
|
26
|
+
| REQUIREMENT Requirements { result = [ RequirementNode.new(val[0]) ] + val[1] }
|
27
|
+
| REQUIREMENT RequirementBody { result = [ RequirementNode.new(val[0], val[1]) ] }
|
28
|
+
| REQUIREMENT RequirementBody Requirements { result = [ RequirementNode.new(val[0], val[1]) ] + val[2] }
|
29
|
+
;
|
30
|
+
|
31
|
+
RequirementBody:
|
32
|
+
Text { result = val[0] }
|
33
|
+
| Table { result = val[0] }
|
34
|
+
| Text Table { result = val[0] + val[1] }
|
35
|
+
| Text Table Text { result = val[0] + val[1] + val[2] }
|
36
|
+
;
|
37
|
+
|
38
|
+
Text:
|
39
|
+
TEXT { result = [] }
|
40
|
+
| TEXT Text { result = [] }
|
41
|
+
;
|
42
|
+
|
43
|
+
Table:
|
44
|
+
Rows { result = [ ExamplesNode.new('', val[0]) ] }
|
45
|
+
;
|
46
|
+
|
47
|
+
Rows:
|
48
|
+
ROW Cells { result = [ RowNode.new('', val[1]) ] }
|
49
|
+
| ROW Cells Rows { result = [ RowNode.new('', val[1]) ] + val[2] }
|
50
|
+
;
|
51
|
+
|
52
|
+
Cells:
|
53
|
+
CELL { result = [ val[0] ] }
|
54
|
+
| CELL Cells { result = [ val[0] ] + val[1] }
|
55
|
+
;
|
56
|
+
|
57
|
+
end
|
58
|
+
---- header
|
59
|
+
require 'manamana/rdsl/lexer'
|
60
|
+
require 'manamana/rdsl/nodes'
|
61
|
+
|
62
|
+
---- inner
|
63
|
+
def parse(code, show_tokens=false)
|
64
|
+
@tokens = Lexer.new.tokenize(code)
|
65
|
+
puts @tokens.inspect if show_tokens
|
66
|
+
do_parse
|
67
|
+
end
|
68
|
+
|
69
|
+
def next_token
|
70
|
+
@tokens.shift
|
71
|
+
end
|
data/src/tdsl/lexer.rl
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# lib/manamana/tdsl/lexer.rb is autogenerated by
|
2
|
+
# ragel from src/tdsl/lexer.rl. Please edit the
|
3
|
+
# .rl file and not the .rb file.
|
4
|
+
|
5
|
+
%%{
|
6
|
+
|
7
|
+
machine lexer;
|
8
|
+
|
9
|
+
newline = ('\n' | '\r\n');
|
10
|
+
tab_or_space = [\t ];
|
11
|
+
string = [A-Za-z0-9\=\'\"\<] print*;
|
12
|
+
tc_string = [A-Za-z0-9\.\+\?\(\)] print*;
|
13
|
+
tc_label = 'Test Case:';
|
14
|
+
section_label = ('Variables' | 'Preconditions' | 'Cleanup' | 'Script') ':';
|
15
|
+
|
16
|
+
|
17
|
+
test_case = tc_label tab_or_space* newline
|
18
|
+
tab_or_space* tc_string tab_or_space* (newline
|
19
|
+
tab_or_space* tc_string)* (newline newline)*;
|
20
|
+
|
21
|
+
line = '* ' string tab_or_space* (newline tab_or_space* string)*;
|
22
|
+
|
23
|
+
main := |*
|
24
|
+
|
25
|
+
test_case => { emit_test_case(token_array, data, ts, te) };
|
26
|
+
section_label => { emit_label(token_array, data, ts, te) };
|
27
|
+
line => { emit_line(token_array, data, ts, te) };
|
28
|
+
|
29
|
+
space;
|
30
|
+
|
31
|
+
*|;
|
32
|
+
}%%
|
33
|
+
|
34
|
+
|
35
|
+
module ManaMana
|
36
|
+
|
37
|
+
module TDSL
|
38
|
+
|
39
|
+
class Lexer
|
40
|
+
|
41
|
+
def initialize
|
42
|
+
%% write data;
|
43
|
+
# %% this just fixes syntax highlighting in TextMate et al.
|
44
|
+
end
|
45
|
+
|
46
|
+
def emit_label(token_array, data, ts, te)
|
47
|
+
value = data[ts...te].pack("c*").gsub(/\:/, '')
|
48
|
+
token_array << [value.upcase.to_sym, value]
|
49
|
+
end
|
50
|
+
|
51
|
+
def emit_line(token_array, data, ts, te)
|
52
|
+
value = data[ts...te].pack("c*").split.join(' ').gsub(/\* /, '').strip
|
53
|
+
token_array << [:LINE, value]
|
54
|
+
end
|
55
|
+
|
56
|
+
def emit_test_case(token_array, data, ts, te)
|
57
|
+
value = data[ts...te].pack("c*").split.join(' ').gsub(/Test Case\:/, '').strip
|
58
|
+
token_array << [:TEST_CASE, value]
|
59
|
+
end
|
60
|
+
|
61
|
+
def tokenize(data)
|
62
|
+
data = data.unpack("c*") if(data.is_a?(String))
|
63
|
+
eof = data.length
|
64
|
+
token_array = []
|
65
|
+
|
66
|
+
%% write init;
|
67
|
+
%% write exec;
|
68
|
+
|
69
|
+
token_array
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/src/tdsl/parser.y
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
class ManaMana::TDSL::Parser
|
2
|
+
|
3
|
+
token TEST_CASE
|
4
|
+
token VARIABLES
|
5
|
+
token PRECONDITIONS
|
6
|
+
token CLEANUP
|
7
|
+
token SCRIPT
|
8
|
+
token LINE
|
9
|
+
|
10
|
+
rule
|
11
|
+
Root:
|
12
|
+
/* empty array */ { result = RootNode.new }
|
13
|
+
| TestCases { result = RootNode.new('', val[0]) }
|
14
|
+
;
|
15
|
+
|
16
|
+
TestCases:
|
17
|
+
TEST_CASE { result = [ TestCaseNode.new(val[0]) ] }
|
18
|
+
| TEST_CASE TestCases { result = [ TestCaseNode.new(val[0]) ] + val[1] }
|
19
|
+
| TEST_CASE TestCaseBody { result = [ TestCaseNode.new(val[0], val[1]) ] }
|
20
|
+
| TEST_CASE TestCaseBody TestCases { result = [ TestCaseNode.new(val[0], val[1]) ] + val[2] }
|
21
|
+
;
|
22
|
+
|
23
|
+
TestCaseBody:
|
24
|
+
Variables
|
25
|
+
Preconditions
|
26
|
+
Cleanup
|
27
|
+
Script { result = val[0].merge(val[1]).merge(val[2]).merge(val[3]) }
|
28
|
+
;
|
29
|
+
|
30
|
+
Variables:
|
31
|
+
/* No Variables Section */ { result = { :variables => VariablesNode.new } }
|
32
|
+
| VARIABLES Assignments { result = { :variables => VariablesNode.new('', val[1]) } }
|
33
|
+
;
|
34
|
+
|
35
|
+
Assignments:
|
36
|
+
LINE { result = [ AssignmentNode.new(val[0]) ] }
|
37
|
+
| LINE Assignments { result = [ AssignmentNode.new(val[0]) ] + val[1] }
|
38
|
+
;
|
39
|
+
|
40
|
+
Preconditions:
|
41
|
+
/* No Precon Section */ { result = { :preconditions => PreconditionsNode.new } }
|
42
|
+
| PRECONDITIONS Lines { result = { :preconditions => PreconditionsNode.new('', val[1]) } }
|
43
|
+
;
|
44
|
+
|
45
|
+
Cleanup:
|
46
|
+
/* No Cleanup Section */ { result = { :cleanup => CleanupNode.new } }
|
47
|
+
| CLEANUP Lines { result = { :cleanup => CleanupNode.new('', val[1]) } }
|
48
|
+
;
|
49
|
+
|
50
|
+
Script:
|
51
|
+
/* No Script Section */ { result = { :script => ScriptNode.new } }
|
52
|
+
| SCRIPT Lines { result = { :script => ScriptNode.new('', val[1]) } }
|
53
|
+
;
|
54
|
+
|
55
|
+
Lines:
|
56
|
+
LINE { result = [ StepNode.new(val[0]) ] }
|
57
|
+
| LINE Lines { result = [ StepNode.new(val[0]) ] + val[1] }
|
58
|
+
;
|
59
|
+
|
60
|
+
end
|
61
|
+
---- header
|
62
|
+
require 'manamana/tdsl/lexer'
|
63
|
+
require 'manamana/tdsl/nodes'
|
64
|
+
|
65
|
+
---- inner
|
66
|
+
def parse(code, show_tokens=false)
|
67
|
+
@tokens = Lexer.new.tokenize(code)
|
68
|
+
puts @tokens.inspect if show_tokens
|
69
|
+
do_parse
|
70
|
+
end
|
71
|
+
|
72
|
+
def next_token
|
73
|
+
@tokens.shift
|
74
|
+
end
|