cucumber 0.1.10 → 0.1.11
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/History.txt +18 -0
- data/Manifest.txt +1 -0
- data/Rakefile +1 -2
- data/config/hoe.rb +0 -1
- data/gem_tasks/rspec.rake +28 -14
- data/lib/autotest/cucumber_mixin.rb +23 -1
- data/lib/cucumber.rb +0 -1
- data/lib/cucumber/cli.rb +46 -11
- data/lib/cucumber/core_ext/string.rb +7 -0
- data/lib/cucumber/executor.rb +0 -2
- data/lib/cucumber/languages.yml +11 -0
- data/lib/cucumber/platform.rb +1 -0
- data/lib/cucumber/step_mother.rb +1 -1
- data/lib/cucumber/tree.rb +0 -2
- data/lib/cucumber/tree/scenario.rb +2 -1
- data/lib/cucumber/treetop_parser/feature_en-lol.rb +1591 -0
- data/lib/cucumber/version.rb +1 -1
- data/rails_generators/cucumber/templates/env.rb +4 -1
- data/rails_generators/cucumber/templates/webrat_steps.rb +14 -16
- data/spec/cucumber/cli_spec.rb +158 -1
- metadata +4 -13
data/History.txt
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
== 0.1.11
|
2
|
+
|
3
|
+
Bugfix release with a couple of minor additional features to the command line options.
|
4
|
+
|
5
|
+
== New features
|
6
|
+
* Capture output from cucumber in Autotest (Alan Larkin)
|
7
|
+
* Update cucumber generator to work with latest Webrat (Bryan Helkamp)
|
8
|
+
* CUCUMBR LIKEZ 2 SPEEK WIF KATS. KTHXBAI (Aimee Daniells)
|
9
|
+
* Support for dynamically pluggable formatters (#99 Joseph Wilk)
|
10
|
+
* --verbose mode to see ruby files and feature files loaded by Cucumber (#106 Joseph Wilk)
|
11
|
+
|
12
|
+
== Bugfixes
|
13
|
+
* The jcode library is not loaded on JRuby/Rails. Workaround for http://tinyurl.com/55uu3u. (Aslak Hellesøy)
|
14
|
+
* Support including modules for class passed to --format (#109 Joseph Wilk)
|
15
|
+
|
16
|
+
== Removed features
|
17
|
+
* The cucumber gem no longer depends on the rspec gem. It must be downloaded manually if RSpec is used.
|
18
|
+
|
1
19
|
== 0.1.10 2008-11-25
|
2
20
|
|
3
21
|
This release mostly has smaller bugfixes. The most significant new feature is how
|
data/Manifest.txt
CHANGED
@@ -166,6 +166,7 @@ lib/cucumber/treetop_parser/feature_ar.rb
|
|
166
166
|
lib/cucumber/treetop_parser/feature_cy.rb
|
167
167
|
lib/cucumber/treetop_parser/feature_da.rb
|
168
168
|
lib/cucumber/treetop_parser/feature_de.rb
|
169
|
+
lib/cucumber/treetop_parser/feature_en-lol.rb
|
169
170
|
lib/cucumber/treetop_parser/feature_en-tx.rb
|
170
171
|
lib/cucumber/treetop_parser/feature_en.rb
|
171
172
|
lib/cucumber/treetop_parser/feature_es.rb
|
data/Rakefile
CHANGED
@@ -5,5 +5,4 @@ require 'config/hoe' # setup Hoe + all gem configuration
|
|
5
5
|
Dir['gem_tasks/**/*.rake'].each { |rake| load rake }
|
6
6
|
|
7
7
|
# Hoe gives us :default => :test, but we don't have Test::Unit tests.
|
8
|
-
Rake::Task[:default].clear_prerequisites
|
9
|
-
task :default => [:spec, :features]
|
8
|
+
Rake::Task[:default].clear_prerequisites
|
data/config/hoe.rb
CHANGED
@@ -58,7 +58,6 @@ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
|
58
58
|
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
59
59
|
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
60
60
|
p.extra_deps = [ ['term-ansicolor', '>= 1.0.3'], ['treetop', '>= 1.2.4'], ['diff-lcs', '>= 1.1.2'] ]
|
61
|
-
p.extra_dev_deps = [ ['rspec', '>= 1.1.11'] ]
|
62
61
|
|
63
62
|
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
64
63
|
|
data/gem_tasks/rspec.rake
CHANGED
@@ -1,21 +1,35 @@
|
|
1
|
-
|
1
|
+
def unable_to_load
|
2
|
+
STDERR.puts <<-EOS
|
3
|
+
To use rspec for testing you must install rspec gem:
|
4
|
+
gem install rspec
|
5
|
+
|
6
|
+
EOS
|
7
|
+
nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def require_spec
|
2
11
|
require 'spec'
|
3
12
|
rescue LoadError
|
13
|
+
require_spec_with_rubygems
|
14
|
+
end
|
15
|
+
|
16
|
+
def require_spec_with_rubygems
|
4
17
|
require 'rubygems'
|
5
18
|
require 'spec'
|
6
|
-
end
|
7
|
-
begin
|
8
|
-
require 'spec/rake/spectask'
|
9
19
|
rescue LoadError
|
10
|
-
|
11
|
-
To use rspec for testing you must install rspec gem:
|
12
|
-
gem install rspec
|
13
|
-
EOS
|
14
|
-
exit(0)
|
20
|
+
unable_to_load
|
15
21
|
end
|
16
22
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
23
|
+
if require_spec
|
24
|
+
begin
|
25
|
+
require 'spec/rake/spectask'
|
26
|
+
rescue LoadError
|
27
|
+
unable_to_load
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Run the Cucumber specs"
|
31
|
+
Spec::Rake::SpecTask.new do |t|
|
32
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
33
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
34
|
+
end
|
35
|
+
end
|
@@ -70,7 +70,29 @@ module Autotest::CucumberMixin
|
|
70
70
|
cmd = self.make_cucumber_cmd self.scenarios_to_run, dirty_scenarios_file.path
|
71
71
|
return if cmd.empty?
|
72
72
|
puts cmd unless $q
|
73
|
-
|
73
|
+
old_sync = $stdout.sync
|
74
|
+
$stdout.sync = true
|
75
|
+
self.results = []
|
76
|
+
line = []
|
77
|
+
begin
|
78
|
+
open("| #{cmd}", "r") do |f|
|
79
|
+
until f.eof? do
|
80
|
+
c = f.getc
|
81
|
+
putc c
|
82
|
+
line << c
|
83
|
+
if c == ?\n then
|
84
|
+
self.results << if RUBY_VERSION >= "1.9" then
|
85
|
+
line.join
|
86
|
+
else
|
87
|
+
line.pack "c*"
|
88
|
+
end
|
89
|
+
line.clear
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
ensure
|
94
|
+
$stdout.sync = old_sync
|
95
|
+
end
|
74
96
|
self.scenarios_to_run = dirty_scenarios_file.readlines.map { |l| l.chomp }
|
75
97
|
self.tainted = true unless self.scenarios_to_run == []
|
76
98
|
end
|
data/lib/cucumber.rb
CHANGED
data/lib/cucumber/cli.rb
CHANGED
@@ -69,12 +69,11 @@ module Cucumber
|
|
69
69
|
end
|
70
70
|
opts.on("-f FORMAT", "--format FORMAT", "How to format features (Default: #{DEFAULT_FORMAT})",
|
71
71
|
"Available formats: #{FORMATS.join(", ")}",
|
72
|
+
"You can also provide your own formatter classes as long as they have been",
|
73
|
+
"previously required using --require or if they are in the folder",
|
74
|
+
"structure such that cucumber will require them automatically.",
|
72
75
|
"This option can be specified multiple times.") do |v|
|
73
|
-
|
74
|
-
@error_stream.puts "Invalid format: #{v}\n"
|
75
|
-
@error_stream.puts opts.help
|
76
|
-
exit 1
|
77
|
-
end
|
76
|
+
|
78
77
|
@options[:formats][v] ||= []
|
79
78
|
@options[:formats][v] << @out_stream
|
80
79
|
@active_format = v
|
@@ -114,13 +113,16 @@ module Cucumber
|
|
114
113
|
@options[:snippets] = false
|
115
114
|
@options[:source] = false
|
116
115
|
end
|
116
|
+
opts.on("-v", "--verbose", "Show the files and features loaded") do
|
117
|
+
@options[:verbose] = true
|
118
|
+
end
|
117
119
|
opts.on_tail("--version", "Show version") do
|
118
|
-
puts VERSION::STRING
|
119
|
-
exit
|
120
|
+
@out_stream.puts VERSION::STRING
|
121
|
+
Kernel.exit
|
120
122
|
end
|
121
123
|
opts.on_tail("--help", "You're looking at it") do
|
122
|
-
puts opts.help
|
123
|
-
exit
|
124
|
+
@out_stream.puts opts.help
|
125
|
+
Kernel.exit
|
124
126
|
end
|
125
127
|
end.parse!
|
126
128
|
|
@@ -159,8 +161,8 @@ Defined profiles in cucumber.yml:
|
|
159
161
|
def execute!(step_mother, executor, features)
|
160
162
|
Term::ANSIColor.coloring = @options[:color] unless @options[:color].nil?
|
161
163
|
Cucumber.load_language(@options[:lang])
|
162
|
-
executor.formatters = build_formatter_broadcaster(step_mother)
|
163
164
|
require_files
|
165
|
+
executor.formatters = build_formatter_broadcaster(step_mother)
|
164
166
|
load_plain_text_features(features)
|
165
167
|
executor.lines_for_features = @options[:lines_for_features]
|
166
168
|
executor.scenario_names = @options[:scenario_names] if @options[:scenario_names]
|
@@ -188,6 +190,7 @@ Defined profiles in cucumber.yml:
|
|
188
190
|
require "cucumber/treetop_parser/feature_#{@options[:lang]}"
|
189
191
|
require "cucumber/treetop_parser/feature_parser"
|
190
192
|
|
193
|
+
verbose_log("Ruby files required:")
|
191
194
|
requires = @options[:require] || feature_dirs
|
192
195
|
libs = requires.map do |path|
|
193
196
|
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
@@ -196,11 +199,13 @@ Defined profiles in cucumber.yml:
|
|
196
199
|
libs.each do |lib|
|
197
200
|
begin
|
198
201
|
require lib
|
202
|
+
verbose_log(" * #{lib}")
|
199
203
|
rescue LoadError => e
|
200
204
|
e.message << "\nFailed to load #{lib}"
|
201
205
|
raise e
|
202
206
|
end
|
203
207
|
end
|
208
|
+
verbose_log("\n")
|
204
209
|
end
|
205
210
|
|
206
211
|
def feature_files
|
@@ -226,9 +231,12 @@ Defined profiles in cucumber.yml:
|
|
226
231
|
def load_plain_text_features(features)
|
227
232
|
parser = TreetopParser::FeatureParser.new
|
228
233
|
|
234
|
+
verbose_log("Features:")
|
229
235
|
feature_files.each do |f|
|
230
236
|
features << parser.parse_feature(f)
|
237
|
+
verbose_log(" * #{f}")
|
231
238
|
end
|
239
|
+
verbose_log("\n"*2)
|
232
240
|
end
|
233
241
|
|
234
242
|
def build_formatter_broadcaster(step_mother)
|
@@ -247,7 +255,15 @@ Defined profiles in cucumber.yml:
|
|
247
255
|
when 'autotest'
|
248
256
|
formatter_broadcaster.register(Formatters::AutotestFormatter.new(output_broadcaster))
|
249
257
|
else
|
250
|
-
|
258
|
+
begin
|
259
|
+
formatter_class = constantize(format)
|
260
|
+
formatter_broadcaster.register(formatter_class.new(output_broadcaster, step_mother, @options))
|
261
|
+
rescue NameError => e
|
262
|
+
@error_stream.puts "Invalid format: #{format}\n"
|
263
|
+
exit_with_help
|
264
|
+
rescue Exception => e
|
265
|
+
exit_with_error("Error creating formatter: #{format}\n#{e}\n")
|
266
|
+
end
|
251
267
|
end
|
252
268
|
end
|
253
269
|
formatter_broadcaster
|
@@ -263,6 +279,25 @@ Defined profiles in cucumber.yml:
|
|
263
279
|
|
264
280
|
private
|
265
281
|
|
282
|
+
def constantize(camel_cased_word)
|
283
|
+
names = camel_cased_word.split('::')
|
284
|
+
names.shift if names.empty? || names.first.empty?
|
285
|
+
|
286
|
+
constant = Object
|
287
|
+
names.each do |name|
|
288
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
289
|
+
end
|
290
|
+
constant
|
291
|
+
end
|
292
|
+
|
293
|
+
def verbose_log(string)
|
294
|
+
@out_stream.puts(string) if @options[:verbose]
|
295
|
+
end
|
296
|
+
|
297
|
+
def exit_with_help
|
298
|
+
parse_options!(%w{--help})
|
299
|
+
end
|
300
|
+
|
266
301
|
def exit_with_error(error_message)
|
267
302
|
@error_stream << error_message
|
268
303
|
Kernel.exit 1
|
data/lib/cucumber/executor.rb
CHANGED
data/lib/cucumber/languages.yml
CHANGED
@@ -63,6 +63,17 @@
|
|
63
63
|
then: Dann
|
64
64
|
and: Und
|
65
65
|
but: Aber
|
66
|
+
# LOLCAT
|
67
|
+
"en-lol":
|
68
|
+
feature: OH HAI
|
69
|
+
scenario: MISHUN
|
70
|
+
more_examples: MOAR EXAMPLZ
|
71
|
+
given_scenario: SRSLY
|
72
|
+
given: GIVN
|
73
|
+
when: WEN
|
74
|
+
then: DEN
|
75
|
+
and: AN
|
76
|
+
but: BUT
|
66
77
|
# Texan
|
67
78
|
"en-tx":
|
68
79
|
feature: Feature
|
data/lib/cucumber/platform.rb
CHANGED
@@ -6,6 +6,7 @@ $CUCUMBER_JRUBY = defined?(JRUBY_VERSION)
|
|
6
6
|
$CUCUMBER_IRONRUBY = Config::CONFIG['sitedir'] =~ /IronRuby/
|
7
7
|
$CUCUMBER_WINDOWS = Config::CONFIG['host_os'] =~ /mswin|mingw/
|
8
8
|
$CUCUMBER_WINDOWS_MRI = $CUCUMBER_WINDOWS && !$CUCUMBER_JRUBY && !$CUCUMBER_IRONRUBY
|
9
|
+
$CUCUMBER_RAILS = defined?(Rails)
|
9
10
|
|
10
11
|
if $CUCUMBER_IRONRUBY
|
11
12
|
ENV['GEM_PATH'] ||= "C:/ruby/lib/ruby/gems/1.8"
|
data/lib/cucumber/step_mother.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'cucumber/tree/top_down_visitor'
|
2
|
-
require 'cucumber/core_ext/proc'
|
3
2
|
|
4
3
|
module Cucumber
|
5
4
|
class Pending < StandardError
|
@@ -21,6 +20,7 @@ module Cucumber
|
|
21
20
|
PENDING = lambda do |*_|
|
22
21
|
raise Pending
|
23
22
|
end
|
23
|
+
require 'cucumber/core_ext/proc'
|
24
24
|
PENDING.extend(CoreExt::CallIn)
|
25
25
|
PENDING.name = "PENDING"
|
26
26
|
|
data/lib/cucumber/tree.rb
CHANGED
@@ -43,6 +43,7 @@ module Cucumber
|
|
43
43
|
attr_reader :name, :line
|
44
44
|
|
45
45
|
def initialize(feature, name, line, &proc)
|
46
|
+
require 'cucumber/core_ext/string'
|
46
47
|
@feature, @name, @line = feature, name, line
|
47
48
|
@steps_and_given_scenarios = []
|
48
49
|
instance_eval(&proc) if block_given?
|
@@ -148,7 +149,7 @@ module Cucumber
|
|
148
149
|
def steps
|
149
150
|
if template_steps_bound?
|
150
151
|
@unbound_steps = nil
|
151
|
-
@
|
152
|
+
@bound_steps ||= build_steps
|
152
153
|
else
|
153
154
|
@unbound_steps ||= build_steps
|
154
155
|
end
|
@@ -0,0 +1,1591 @@
|
|
1
|
+
module Cucumber
|
2
|
+
# :stopdoc:
|
3
|
+
module TreetopParser
|
4
|
+
module Feature
|
5
|
+
include Treetop::Runtime
|
6
|
+
|
7
|
+
def root
|
8
|
+
@root || :root
|
9
|
+
end
|
10
|
+
|
11
|
+
module Root0
|
12
|
+
def header
|
13
|
+
elements[1]
|
14
|
+
end
|
15
|
+
|
16
|
+
def scenario_sequence
|
17
|
+
elements[2]
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
module Root1
|
23
|
+
def compile
|
24
|
+
feature = Tree::Feature.new(header.text_value.strip)
|
25
|
+
scenario_sequence.compile(feature)
|
26
|
+
feature
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def _nt_root
|
31
|
+
start_index = index
|
32
|
+
if node_cache[:root].has_key?(index)
|
33
|
+
cached = node_cache[:root][index]
|
34
|
+
@index = cached.interval.end if cached
|
35
|
+
return cached
|
36
|
+
end
|
37
|
+
|
38
|
+
i0, s0 = index, []
|
39
|
+
r2 = _nt_space
|
40
|
+
if r2
|
41
|
+
r1 = r2
|
42
|
+
else
|
43
|
+
r1 = SyntaxNode.new(input, index...index)
|
44
|
+
end
|
45
|
+
s0 << r1
|
46
|
+
if r1
|
47
|
+
r3 = _nt_header
|
48
|
+
s0 << r3
|
49
|
+
if r3
|
50
|
+
r4 = _nt_scenario_sequence
|
51
|
+
s0 << r4
|
52
|
+
if r4
|
53
|
+
r6 = _nt_space
|
54
|
+
if r6
|
55
|
+
r5 = r6
|
56
|
+
else
|
57
|
+
r5 = SyntaxNode.new(input, index...index)
|
58
|
+
end
|
59
|
+
s0 << r5
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
if s0.last
|
64
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
65
|
+
r0.extend(Root0)
|
66
|
+
r0.extend(Root1)
|
67
|
+
else
|
68
|
+
self.index = i0
|
69
|
+
r0 = nil
|
70
|
+
end
|
71
|
+
|
72
|
+
node_cache[:root][start_index] = r0
|
73
|
+
|
74
|
+
return r0
|
75
|
+
end
|
76
|
+
|
77
|
+
module Header0
|
78
|
+
end
|
79
|
+
|
80
|
+
def _nt_header
|
81
|
+
start_index = index
|
82
|
+
if node_cache[:header].has_key?(index)
|
83
|
+
cached = node_cache[:header][index]
|
84
|
+
@index = cached.interval.end if cached
|
85
|
+
return cached
|
86
|
+
end
|
87
|
+
|
88
|
+
s0, i0 = [], index
|
89
|
+
loop do
|
90
|
+
i1, s1 = index, []
|
91
|
+
i2 = index
|
92
|
+
i3 = index
|
93
|
+
r4 = _nt_scenario_keyword
|
94
|
+
if r4
|
95
|
+
r3 = r4
|
96
|
+
else
|
97
|
+
r5 = _nt_comment_to_eol
|
98
|
+
if r5
|
99
|
+
r3 = r5
|
100
|
+
else
|
101
|
+
self.index = i3
|
102
|
+
r3 = nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
if r3
|
106
|
+
r2 = nil
|
107
|
+
else
|
108
|
+
self.index = i2
|
109
|
+
r2 = SyntaxNode.new(input, index...index)
|
110
|
+
end
|
111
|
+
s1 << r2
|
112
|
+
if r2
|
113
|
+
if index < input_length
|
114
|
+
r6 = (SyntaxNode).new(input, index...(index + 1))
|
115
|
+
@index += 1
|
116
|
+
else
|
117
|
+
terminal_parse_failure("any character")
|
118
|
+
r6 = nil
|
119
|
+
end
|
120
|
+
s1 << r6
|
121
|
+
end
|
122
|
+
if s1.last
|
123
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
124
|
+
r1.extend(Header0)
|
125
|
+
else
|
126
|
+
self.index = i1
|
127
|
+
r1 = nil
|
128
|
+
end
|
129
|
+
if r1
|
130
|
+
s0 << r1
|
131
|
+
else
|
132
|
+
break
|
133
|
+
end
|
134
|
+
end
|
135
|
+
if s0.empty?
|
136
|
+
self.index = i0
|
137
|
+
r0 = nil
|
138
|
+
else
|
139
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
140
|
+
end
|
141
|
+
|
142
|
+
node_cache[:header][start_index] = r0
|
143
|
+
|
144
|
+
return r0
|
145
|
+
end
|
146
|
+
|
147
|
+
module ScenarioSequence0
|
148
|
+
def space
|
149
|
+
elements[0]
|
150
|
+
end
|
151
|
+
|
152
|
+
def scenario_or_table
|
153
|
+
elements[1]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
module ScenarioSequence1
|
158
|
+
def head
|
159
|
+
elements[0]
|
160
|
+
end
|
161
|
+
|
162
|
+
def tail
|
163
|
+
elements[1]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
module ScenarioSequence2
|
168
|
+
def compile(feature)
|
169
|
+
([head] + tail).each do |scenario_or_table|
|
170
|
+
scenario_or_table.compile(feature) if scenario_or_table.respond_to?(:compile)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def tail
|
175
|
+
super.elements.map { |elt| elt.scenario_or_table }
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def _nt_scenario_sequence
|
180
|
+
start_index = index
|
181
|
+
if node_cache[:scenario_sequence].has_key?(index)
|
182
|
+
cached = node_cache[:scenario_sequence][index]
|
183
|
+
@index = cached.interval.end if cached
|
184
|
+
return cached
|
185
|
+
end
|
186
|
+
|
187
|
+
i0, s0 = index, []
|
188
|
+
r2 = _nt_scenario
|
189
|
+
if r2
|
190
|
+
r1 = r2
|
191
|
+
else
|
192
|
+
r1 = SyntaxNode.new(input, index...index)
|
193
|
+
end
|
194
|
+
s0 << r1
|
195
|
+
if r1
|
196
|
+
s3, i3 = [], index
|
197
|
+
loop do
|
198
|
+
i4, s4 = index, []
|
199
|
+
r5 = _nt_space
|
200
|
+
s4 << r5
|
201
|
+
if r5
|
202
|
+
r6 = _nt_scenario_or_table
|
203
|
+
s4 << r6
|
204
|
+
end
|
205
|
+
if s4.last
|
206
|
+
r4 = (SyntaxNode).new(input, i4...index, s4)
|
207
|
+
r4.extend(ScenarioSequence0)
|
208
|
+
else
|
209
|
+
self.index = i4
|
210
|
+
r4 = nil
|
211
|
+
end
|
212
|
+
if r4
|
213
|
+
s3 << r4
|
214
|
+
else
|
215
|
+
break
|
216
|
+
end
|
217
|
+
end
|
218
|
+
r3 = SyntaxNode.new(input, i3...index, s3)
|
219
|
+
s0 << r3
|
220
|
+
end
|
221
|
+
if s0.last
|
222
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
223
|
+
r0.extend(ScenarioSequence1)
|
224
|
+
r0.extend(ScenarioSequence2)
|
225
|
+
else
|
226
|
+
self.index = i0
|
227
|
+
r0 = nil
|
228
|
+
end
|
229
|
+
|
230
|
+
node_cache[:scenario_sequence][start_index] = r0
|
231
|
+
|
232
|
+
return r0
|
233
|
+
end
|
234
|
+
|
235
|
+
module Scenario0
|
236
|
+
def space
|
237
|
+
elements[0]
|
238
|
+
end
|
239
|
+
|
240
|
+
def step_sequence
|
241
|
+
elements[1]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
module Scenario1
|
246
|
+
def scenario_keyword
|
247
|
+
elements[0]
|
248
|
+
end
|
249
|
+
|
250
|
+
def name
|
251
|
+
elements[2]
|
252
|
+
end
|
253
|
+
|
254
|
+
def steps
|
255
|
+
elements[3]
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
module Scenario2
|
260
|
+
def compile(feature)
|
261
|
+
line = input.line_of(interval.first)
|
262
|
+
scenario = feature.add_scenario(name.text_value.strip, line)
|
263
|
+
steps.step_sequence.compile(scenario) if steps.respond_to?(:step_sequence)
|
264
|
+
# TODO - GET RID OF THIS last_scenario NASTINESS
|
265
|
+
# Use a better datastructure, like a linked list...
|
266
|
+
Feature.last_scenario = scenario
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def _nt_scenario
|
271
|
+
start_index = index
|
272
|
+
if node_cache[:scenario].has_key?(index)
|
273
|
+
cached = node_cache[:scenario][index]
|
274
|
+
@index = cached.interval.end if cached
|
275
|
+
return cached
|
276
|
+
end
|
277
|
+
|
278
|
+
i0, s0 = index, []
|
279
|
+
r1 = _nt_scenario_keyword
|
280
|
+
s0 << r1
|
281
|
+
if r1
|
282
|
+
r3 = _nt_space
|
283
|
+
if r3
|
284
|
+
r2 = r3
|
285
|
+
else
|
286
|
+
r2 = SyntaxNode.new(input, index...index)
|
287
|
+
end
|
288
|
+
s0 << r2
|
289
|
+
if r2
|
290
|
+
r4 = _nt_line_to_eol
|
291
|
+
s0 << r4
|
292
|
+
if r4
|
293
|
+
i6, s6 = index, []
|
294
|
+
r7 = _nt_space
|
295
|
+
s6 << r7
|
296
|
+
if r7
|
297
|
+
r8 = _nt_step_sequence
|
298
|
+
s6 << r8
|
299
|
+
end
|
300
|
+
if s6.last
|
301
|
+
r6 = (SyntaxNode).new(input, i6...index, s6)
|
302
|
+
r6.extend(Scenario0)
|
303
|
+
else
|
304
|
+
self.index = i6
|
305
|
+
r6 = nil
|
306
|
+
end
|
307
|
+
if r6
|
308
|
+
r5 = r6
|
309
|
+
else
|
310
|
+
r5 = SyntaxNode.new(input, index...index)
|
311
|
+
end
|
312
|
+
s0 << r5
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
if s0.last
|
317
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
318
|
+
r0.extend(Scenario1)
|
319
|
+
r0.extend(Scenario2)
|
320
|
+
else
|
321
|
+
self.index = i0
|
322
|
+
r0 = nil
|
323
|
+
end
|
324
|
+
|
325
|
+
node_cache[:scenario][start_index] = r0
|
326
|
+
|
327
|
+
return r0
|
328
|
+
end
|
329
|
+
|
330
|
+
def _nt_scenario_or_table
|
331
|
+
start_index = index
|
332
|
+
if node_cache[:scenario_or_table].has_key?(index)
|
333
|
+
cached = node_cache[:scenario_or_table][index]
|
334
|
+
@index = cached.interval.end if cached
|
335
|
+
return cached
|
336
|
+
end
|
337
|
+
|
338
|
+
i0 = index
|
339
|
+
r1 = _nt_scenario
|
340
|
+
if r1
|
341
|
+
r0 = r1
|
342
|
+
else
|
343
|
+
r2 = _nt_more_examples
|
344
|
+
if r2
|
345
|
+
r0 = r2
|
346
|
+
else
|
347
|
+
self.index = i0
|
348
|
+
r0 = nil
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
node_cache[:scenario_or_table][start_index] = r0
|
353
|
+
|
354
|
+
return r0
|
355
|
+
end
|
356
|
+
|
357
|
+
module MoreExamples0
|
358
|
+
def more_examples_keyword
|
359
|
+
elements[0]
|
360
|
+
end
|
361
|
+
|
362
|
+
def table
|
363
|
+
elements[1]
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
module MoreExamples1
|
368
|
+
def compile(f)
|
369
|
+
table.compile(f)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
def _nt_more_examples
|
374
|
+
start_index = index
|
375
|
+
if node_cache[:more_examples].has_key?(index)
|
376
|
+
cached = node_cache[:more_examples][index]
|
377
|
+
@index = cached.interval.end if cached
|
378
|
+
return cached
|
379
|
+
end
|
380
|
+
|
381
|
+
i0, s0 = index, []
|
382
|
+
r1 = _nt_more_examples_keyword
|
383
|
+
s0 << r1
|
384
|
+
if r1
|
385
|
+
r2 = _nt_table
|
386
|
+
s0 << r2
|
387
|
+
end
|
388
|
+
if s0.last
|
389
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
390
|
+
r0.extend(MoreExamples0)
|
391
|
+
r0.extend(MoreExamples1)
|
392
|
+
else
|
393
|
+
self.index = i0
|
394
|
+
r0 = nil
|
395
|
+
end
|
396
|
+
|
397
|
+
node_cache[:more_examples][start_index] = r0
|
398
|
+
|
399
|
+
return r0
|
400
|
+
end
|
401
|
+
|
402
|
+
module Table0
|
403
|
+
def eol
|
404
|
+
elements[1]
|
405
|
+
end
|
406
|
+
|
407
|
+
def table_line
|
408
|
+
elements[3]
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
module Table1
|
413
|
+
def space
|
414
|
+
elements[0]
|
415
|
+
end
|
416
|
+
|
417
|
+
def head
|
418
|
+
elements[1]
|
419
|
+
end
|
420
|
+
|
421
|
+
def body
|
422
|
+
elements[2]
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
module Table2
|
427
|
+
def compile(feature)
|
428
|
+
Feature.last_scenario.table_header = head.cell_values
|
429
|
+
body.each do |table_line|
|
430
|
+
feature.add_row_scenario(Feature.last_scenario, table_line.cell_values, table_line.line)
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def matrix
|
435
|
+
([head] + body).map do |table_line|
|
436
|
+
table_line.cell_values # We're losing the line - we'll get it back when we make our own class
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
def to_arg
|
441
|
+
Model::Table.new(matrix)
|
442
|
+
end
|
443
|
+
|
444
|
+
def body
|
445
|
+
super.elements.map { |elt| elt.table_line }
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
def _nt_table
|
450
|
+
start_index = index
|
451
|
+
if node_cache[:table].has_key?(index)
|
452
|
+
cached = node_cache[:table][index]
|
453
|
+
@index = cached.interval.end if cached
|
454
|
+
return cached
|
455
|
+
end
|
456
|
+
|
457
|
+
i0, s0 = index, []
|
458
|
+
r1 = _nt_space
|
459
|
+
s0 << r1
|
460
|
+
if r1
|
461
|
+
r2 = _nt_table_line
|
462
|
+
s0 << r2
|
463
|
+
if r2
|
464
|
+
s3, i3 = [], index
|
465
|
+
loop do
|
466
|
+
i4, s4 = index, []
|
467
|
+
s5, i5 = [], index
|
468
|
+
loop do
|
469
|
+
r6 = _nt_blank
|
470
|
+
if r6
|
471
|
+
s5 << r6
|
472
|
+
else
|
473
|
+
break
|
474
|
+
end
|
475
|
+
end
|
476
|
+
r5 = SyntaxNode.new(input, i5...index, s5)
|
477
|
+
s4 << r5
|
478
|
+
if r5
|
479
|
+
r7 = _nt_eol
|
480
|
+
s4 << r7
|
481
|
+
if r7
|
482
|
+
r9 = _nt_space
|
483
|
+
if r9
|
484
|
+
r8 = r9
|
485
|
+
else
|
486
|
+
r8 = SyntaxNode.new(input, index...index)
|
487
|
+
end
|
488
|
+
s4 << r8
|
489
|
+
if r8
|
490
|
+
r10 = _nt_table_line
|
491
|
+
s4 << r10
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
495
|
+
if s4.last
|
496
|
+
r4 = (SyntaxNode).new(input, i4...index, s4)
|
497
|
+
r4.extend(Table0)
|
498
|
+
else
|
499
|
+
self.index = i4
|
500
|
+
r4 = nil
|
501
|
+
end
|
502
|
+
if r4
|
503
|
+
s3 << r4
|
504
|
+
else
|
505
|
+
break
|
506
|
+
end
|
507
|
+
end
|
508
|
+
r3 = SyntaxNode.new(input, i3...index, s3)
|
509
|
+
s0 << r3
|
510
|
+
end
|
511
|
+
end
|
512
|
+
if s0.last
|
513
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
514
|
+
r0.extend(Table1)
|
515
|
+
r0.extend(Table2)
|
516
|
+
else
|
517
|
+
self.index = i0
|
518
|
+
r0 = nil
|
519
|
+
end
|
520
|
+
|
521
|
+
node_cache[:table][start_index] = r0
|
522
|
+
|
523
|
+
return r0
|
524
|
+
end
|
525
|
+
|
526
|
+
module TableLine0
|
527
|
+
def cell_value
|
528
|
+
elements[1]
|
529
|
+
end
|
530
|
+
|
531
|
+
def separator
|
532
|
+
elements[3]
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
module TableLine1
|
537
|
+
def separator
|
538
|
+
elements[0]
|
539
|
+
end
|
540
|
+
|
541
|
+
def cells
|
542
|
+
elements[1]
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
module TableLine2
|
547
|
+
def cell_values
|
548
|
+
cells.elements.map { |elt| elt.cell_value.text_value.strip }
|
549
|
+
end
|
550
|
+
|
551
|
+
def line
|
552
|
+
input.line_of(interval.first)
|
553
|
+
end
|
554
|
+
end
|
555
|
+
|
556
|
+
def _nt_table_line
|
557
|
+
start_index = index
|
558
|
+
if node_cache[:table_line].has_key?(index)
|
559
|
+
cached = node_cache[:table_line][index]
|
560
|
+
@index = cached.interval.end if cached
|
561
|
+
return cached
|
562
|
+
end
|
563
|
+
|
564
|
+
i0, s0 = index, []
|
565
|
+
r1 = _nt_separator
|
566
|
+
s0 << r1
|
567
|
+
if r1
|
568
|
+
s2, i2 = [], index
|
569
|
+
loop do
|
570
|
+
i3, s3 = index, []
|
571
|
+
s4, i4 = [], index
|
572
|
+
loop do
|
573
|
+
r5 = _nt_blank
|
574
|
+
if r5
|
575
|
+
s4 << r5
|
576
|
+
else
|
577
|
+
break
|
578
|
+
end
|
579
|
+
end
|
580
|
+
r4 = SyntaxNode.new(input, i4...index, s4)
|
581
|
+
s3 << r4
|
582
|
+
if r4
|
583
|
+
r6 = _nt_cell_value
|
584
|
+
s3 << r6
|
585
|
+
if r6
|
586
|
+
s7, i7 = [], index
|
587
|
+
loop do
|
588
|
+
r8 = _nt_blank
|
589
|
+
if r8
|
590
|
+
s7 << r8
|
591
|
+
else
|
592
|
+
break
|
593
|
+
end
|
594
|
+
end
|
595
|
+
r7 = SyntaxNode.new(input, i7...index, s7)
|
596
|
+
s3 << r7
|
597
|
+
if r7
|
598
|
+
r9 = _nt_separator
|
599
|
+
s3 << r9
|
600
|
+
end
|
601
|
+
end
|
602
|
+
end
|
603
|
+
if s3.last
|
604
|
+
r3 = (SyntaxNode).new(input, i3...index, s3)
|
605
|
+
r3.extend(TableLine0)
|
606
|
+
else
|
607
|
+
self.index = i3
|
608
|
+
r3 = nil
|
609
|
+
end
|
610
|
+
if r3
|
611
|
+
s2 << r3
|
612
|
+
else
|
613
|
+
break
|
614
|
+
end
|
615
|
+
end
|
616
|
+
if s2.empty?
|
617
|
+
self.index = i2
|
618
|
+
r2 = nil
|
619
|
+
else
|
620
|
+
r2 = SyntaxNode.new(input, i2...index, s2)
|
621
|
+
end
|
622
|
+
s0 << r2
|
623
|
+
end
|
624
|
+
if s0.last
|
625
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
626
|
+
r0.extend(TableLine1)
|
627
|
+
r0.extend(TableLine2)
|
628
|
+
else
|
629
|
+
self.index = i0
|
630
|
+
r0 = nil
|
631
|
+
end
|
632
|
+
|
633
|
+
node_cache[:table_line][start_index] = r0
|
634
|
+
|
635
|
+
return r0
|
636
|
+
end
|
637
|
+
|
638
|
+
module CellValue0
|
639
|
+
end
|
640
|
+
|
641
|
+
def _nt_cell_value
|
642
|
+
start_index = index
|
643
|
+
if node_cache[:cell_value].has_key?(index)
|
644
|
+
cached = node_cache[:cell_value][index]
|
645
|
+
@index = cached.interval.end if cached
|
646
|
+
return cached
|
647
|
+
end
|
648
|
+
|
649
|
+
s0, i0 = [], index
|
650
|
+
loop do
|
651
|
+
i1, s1 = index, []
|
652
|
+
i2 = index
|
653
|
+
i3 = index
|
654
|
+
r4 = _nt_separator
|
655
|
+
if r4
|
656
|
+
r3 = r4
|
657
|
+
else
|
658
|
+
r5 = _nt_eol
|
659
|
+
if r5
|
660
|
+
r3 = r5
|
661
|
+
else
|
662
|
+
self.index = i3
|
663
|
+
r3 = nil
|
664
|
+
end
|
665
|
+
end
|
666
|
+
if r3
|
667
|
+
r2 = nil
|
668
|
+
else
|
669
|
+
self.index = i2
|
670
|
+
r2 = SyntaxNode.new(input, index...index)
|
671
|
+
end
|
672
|
+
s1 << r2
|
673
|
+
if r2
|
674
|
+
if index < input_length
|
675
|
+
r6 = (SyntaxNode).new(input, index...(index + 1))
|
676
|
+
@index += 1
|
677
|
+
else
|
678
|
+
terminal_parse_failure("any character")
|
679
|
+
r6 = nil
|
680
|
+
end
|
681
|
+
s1 << r6
|
682
|
+
end
|
683
|
+
if s1.last
|
684
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
685
|
+
r1.extend(CellValue0)
|
686
|
+
else
|
687
|
+
self.index = i1
|
688
|
+
r1 = nil
|
689
|
+
end
|
690
|
+
if r1
|
691
|
+
s0 << r1
|
692
|
+
else
|
693
|
+
break
|
694
|
+
end
|
695
|
+
end
|
696
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
697
|
+
|
698
|
+
node_cache[:cell_value][start_index] = r0
|
699
|
+
|
700
|
+
return r0
|
701
|
+
end
|
702
|
+
|
703
|
+
module StepSequence0
|
704
|
+
def space
|
705
|
+
elements[0]
|
706
|
+
end
|
707
|
+
|
708
|
+
def step
|
709
|
+
elements[1]
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
module StepSequence1
|
714
|
+
def head
|
715
|
+
elements[0]
|
716
|
+
end
|
717
|
+
|
718
|
+
def tail
|
719
|
+
elements[1]
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
module StepSequence2
|
724
|
+
def compile(scenario)
|
725
|
+
([head] + tail).each do |step|
|
726
|
+
step.compile(scenario)
|
727
|
+
end
|
728
|
+
end
|
729
|
+
|
730
|
+
def tail
|
731
|
+
super.elements.map { |elt| elt.step }
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
735
|
+
def _nt_step_sequence
|
736
|
+
start_index = index
|
737
|
+
if node_cache[:step_sequence].has_key?(index)
|
738
|
+
cached = node_cache[:step_sequence][index]
|
739
|
+
@index = cached.interval.end if cached
|
740
|
+
return cached
|
741
|
+
end
|
742
|
+
|
743
|
+
i0, s0 = index, []
|
744
|
+
r1 = _nt_step
|
745
|
+
s0 << r1
|
746
|
+
if r1
|
747
|
+
s2, i2 = [], index
|
748
|
+
loop do
|
749
|
+
i3, s3 = index, []
|
750
|
+
r4 = _nt_space
|
751
|
+
s3 << r4
|
752
|
+
if r4
|
753
|
+
r5 = _nt_step
|
754
|
+
s3 << r5
|
755
|
+
end
|
756
|
+
if s3.last
|
757
|
+
r3 = (SyntaxNode).new(input, i3...index, s3)
|
758
|
+
r3.extend(StepSequence0)
|
759
|
+
else
|
760
|
+
self.index = i3
|
761
|
+
r3 = nil
|
762
|
+
end
|
763
|
+
if r3
|
764
|
+
s2 << r3
|
765
|
+
else
|
766
|
+
break
|
767
|
+
end
|
768
|
+
end
|
769
|
+
r2 = SyntaxNode.new(input, i2...index, s2)
|
770
|
+
s0 << r2
|
771
|
+
end
|
772
|
+
if s0.last
|
773
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
774
|
+
r0.extend(StepSequence1)
|
775
|
+
r0.extend(StepSequence2)
|
776
|
+
else
|
777
|
+
self.index = i0
|
778
|
+
r0 = nil
|
779
|
+
end
|
780
|
+
|
781
|
+
node_cache[:step_sequence][start_index] = r0
|
782
|
+
|
783
|
+
return r0
|
784
|
+
end
|
785
|
+
|
786
|
+
def _nt_step
|
787
|
+
start_index = index
|
788
|
+
if node_cache[:step].has_key?(index)
|
789
|
+
cached = node_cache[:step][index]
|
790
|
+
@index = cached.interval.end if cached
|
791
|
+
return cached
|
792
|
+
end
|
793
|
+
|
794
|
+
i0 = index
|
795
|
+
r1 = _nt_given_scenario
|
796
|
+
if r1
|
797
|
+
r0 = r1
|
798
|
+
else
|
799
|
+
r2 = _nt_plain_step
|
800
|
+
if r2
|
801
|
+
r0 = r2
|
802
|
+
else
|
803
|
+
self.index = i0
|
804
|
+
r0 = nil
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
node_cache[:step][start_index] = r0
|
809
|
+
|
810
|
+
return r0
|
811
|
+
end
|
812
|
+
|
813
|
+
module GivenScenario0
|
814
|
+
def given_scenario_keyword
|
815
|
+
elements[0]
|
816
|
+
end
|
817
|
+
|
818
|
+
def name
|
819
|
+
elements[2]
|
820
|
+
end
|
821
|
+
end
|
822
|
+
|
823
|
+
module GivenScenario1
|
824
|
+
def compile(scenario)
|
825
|
+
line = input.line_of(interval.first)
|
826
|
+
scenario.create_given_scenario(name.text_value.strip, line)
|
827
|
+
end
|
828
|
+
end
|
829
|
+
|
830
|
+
def _nt_given_scenario
|
831
|
+
start_index = index
|
832
|
+
if node_cache[:given_scenario].has_key?(index)
|
833
|
+
cached = node_cache[:given_scenario][index]
|
834
|
+
@index = cached.interval.end if cached
|
835
|
+
return cached
|
836
|
+
end
|
837
|
+
|
838
|
+
i0, s0 = index, []
|
839
|
+
r1 = _nt_given_scenario_keyword
|
840
|
+
s0 << r1
|
841
|
+
if r1
|
842
|
+
r3 = _nt_space
|
843
|
+
if r3
|
844
|
+
r2 = r3
|
845
|
+
else
|
846
|
+
r2 = SyntaxNode.new(input, index...index)
|
847
|
+
end
|
848
|
+
s0 << r2
|
849
|
+
if r2
|
850
|
+
r4 = _nt_line_to_eol
|
851
|
+
s0 << r4
|
852
|
+
end
|
853
|
+
end
|
854
|
+
if s0.last
|
855
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
856
|
+
r0.extend(GivenScenario0)
|
857
|
+
r0.extend(GivenScenario1)
|
858
|
+
else
|
859
|
+
self.index = i0
|
860
|
+
r0 = nil
|
861
|
+
end
|
862
|
+
|
863
|
+
node_cache[:given_scenario][start_index] = r0
|
864
|
+
|
865
|
+
return r0
|
866
|
+
end
|
867
|
+
|
868
|
+
module PlainStep0
|
869
|
+
def step_keyword
|
870
|
+
elements[0]
|
871
|
+
end
|
872
|
+
|
873
|
+
def name
|
874
|
+
elements[2]
|
875
|
+
end
|
876
|
+
|
877
|
+
def multi
|
878
|
+
elements[3]
|
879
|
+
end
|
880
|
+
end
|
881
|
+
|
882
|
+
module PlainStep1
|
883
|
+
def compile(scenario)
|
884
|
+
line = input.line_of(interval.first)
|
885
|
+
step = scenario.create_step(step_keyword.text_value, name.text_value.strip, line)
|
886
|
+
|
887
|
+
if multi.respond_to?(:to_arg)
|
888
|
+
step.extra_args << multi.to_arg
|
889
|
+
end
|
890
|
+
end
|
891
|
+
end
|
892
|
+
|
893
|
+
def _nt_plain_step
|
894
|
+
start_index = index
|
895
|
+
if node_cache[:plain_step].has_key?(index)
|
896
|
+
cached = node_cache[:plain_step][index]
|
897
|
+
@index = cached.interval.end if cached
|
898
|
+
return cached
|
899
|
+
end
|
900
|
+
|
901
|
+
i0, s0 = index, []
|
902
|
+
r1 = _nt_step_keyword
|
903
|
+
s0 << r1
|
904
|
+
if r1
|
905
|
+
r3 = _nt_space
|
906
|
+
if r3
|
907
|
+
r2 = r3
|
908
|
+
else
|
909
|
+
r2 = SyntaxNode.new(input, index...index)
|
910
|
+
end
|
911
|
+
s0 << r2
|
912
|
+
if r2
|
913
|
+
r4 = _nt_line_to_eol
|
914
|
+
s0 << r4
|
915
|
+
if r4
|
916
|
+
r6 = _nt_multiline_arg
|
917
|
+
if r6
|
918
|
+
r5 = r6
|
919
|
+
else
|
920
|
+
r5 = SyntaxNode.new(input, index...index)
|
921
|
+
end
|
922
|
+
s0 << r5
|
923
|
+
end
|
924
|
+
end
|
925
|
+
end
|
926
|
+
if s0.last
|
927
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
928
|
+
r0.extend(PlainStep0)
|
929
|
+
r0.extend(PlainStep1)
|
930
|
+
else
|
931
|
+
self.index = i0
|
932
|
+
r0 = nil
|
933
|
+
end
|
934
|
+
|
935
|
+
node_cache[:plain_step][start_index] = r0
|
936
|
+
|
937
|
+
return r0
|
938
|
+
end
|
939
|
+
|
940
|
+
def _nt_multiline_arg
|
941
|
+
start_index = index
|
942
|
+
if node_cache[:multiline_arg].has_key?(index)
|
943
|
+
cached = node_cache[:multiline_arg][index]
|
944
|
+
@index = cached.interval.end if cached
|
945
|
+
return cached
|
946
|
+
end
|
947
|
+
|
948
|
+
i0 = index
|
949
|
+
r1 = _nt_table
|
950
|
+
if r1
|
951
|
+
r0 = r1
|
952
|
+
else
|
953
|
+
r2 = _nt_multiline_string
|
954
|
+
if r2
|
955
|
+
r0 = r2
|
956
|
+
else
|
957
|
+
self.index = i0
|
958
|
+
r0 = nil
|
959
|
+
end
|
960
|
+
end
|
961
|
+
|
962
|
+
node_cache[:multiline_arg][start_index] = r0
|
963
|
+
|
964
|
+
return r0
|
965
|
+
end
|
966
|
+
|
967
|
+
module MultilineString0
|
968
|
+
end
|
969
|
+
|
970
|
+
module MultilineString1
|
971
|
+
def eol
|
972
|
+
elements[0]
|
973
|
+
end
|
974
|
+
|
975
|
+
def indent
|
976
|
+
elements[1]
|
977
|
+
end
|
978
|
+
|
979
|
+
def triple_quote
|
980
|
+
elements[2]
|
981
|
+
end
|
982
|
+
|
983
|
+
def string
|
984
|
+
elements[3]
|
985
|
+
end
|
986
|
+
|
987
|
+
def triple_quote
|
988
|
+
elements[4]
|
989
|
+
end
|
990
|
+
end
|
991
|
+
|
992
|
+
module MultilineString2
|
993
|
+
def to_arg
|
994
|
+
indent_length = indent.text_value.length
|
995
|
+
significant_lines = string.text_value.split("\n")[1..-2]
|
996
|
+
significant_lines.map do |l|
|
997
|
+
l[indent_length..-1]
|
998
|
+
end.join("\n")
|
999
|
+
end
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
def _nt_multiline_string
|
1003
|
+
start_index = index
|
1004
|
+
if node_cache[:multiline_string].has_key?(index)
|
1005
|
+
cached = node_cache[:multiline_string][index]
|
1006
|
+
@index = cached.interval.end if cached
|
1007
|
+
return cached
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
i0, s0 = index, []
|
1011
|
+
r1 = _nt_eol
|
1012
|
+
s0 << r1
|
1013
|
+
if r1
|
1014
|
+
r2 = _nt_space
|
1015
|
+
s0 << r2
|
1016
|
+
if r2
|
1017
|
+
r3 = _nt_triple_quote
|
1018
|
+
s0 << r3
|
1019
|
+
if r3
|
1020
|
+
s4, i4 = [], index
|
1021
|
+
loop do
|
1022
|
+
i5, s5 = index, []
|
1023
|
+
i6 = index
|
1024
|
+
r7 = _nt_triple_quote
|
1025
|
+
if r7
|
1026
|
+
r6 = nil
|
1027
|
+
else
|
1028
|
+
self.index = i6
|
1029
|
+
r6 = SyntaxNode.new(input, index...index)
|
1030
|
+
end
|
1031
|
+
s5 << r6
|
1032
|
+
if r6
|
1033
|
+
if index < input_length
|
1034
|
+
r8 = (SyntaxNode).new(input, index...(index + 1))
|
1035
|
+
@index += 1
|
1036
|
+
else
|
1037
|
+
terminal_parse_failure("any character")
|
1038
|
+
r8 = nil
|
1039
|
+
end
|
1040
|
+
s5 << r8
|
1041
|
+
end
|
1042
|
+
if s5.last
|
1043
|
+
r5 = (SyntaxNode).new(input, i5...index, s5)
|
1044
|
+
r5.extend(MultilineString0)
|
1045
|
+
else
|
1046
|
+
self.index = i5
|
1047
|
+
r5 = nil
|
1048
|
+
end
|
1049
|
+
if r5
|
1050
|
+
s4 << r5
|
1051
|
+
else
|
1052
|
+
break
|
1053
|
+
end
|
1054
|
+
end
|
1055
|
+
r4 = SyntaxNode.new(input, i4...index, s4)
|
1056
|
+
s0 << r4
|
1057
|
+
if r4
|
1058
|
+
r9 = _nt_triple_quote
|
1059
|
+
s0 << r9
|
1060
|
+
end
|
1061
|
+
end
|
1062
|
+
end
|
1063
|
+
end
|
1064
|
+
if s0.last
|
1065
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
1066
|
+
r0.extend(MultilineString1)
|
1067
|
+
r0.extend(MultilineString2)
|
1068
|
+
else
|
1069
|
+
self.index = i0
|
1070
|
+
r0 = nil
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
node_cache[:multiline_string][start_index] = r0
|
1074
|
+
|
1075
|
+
return r0
|
1076
|
+
end
|
1077
|
+
|
1078
|
+
def _nt_triple_quote
|
1079
|
+
start_index = index
|
1080
|
+
if node_cache[:triple_quote].has_key?(index)
|
1081
|
+
cached = node_cache[:triple_quote][index]
|
1082
|
+
@index = cached.interval.end if cached
|
1083
|
+
return cached
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
if input.index('"""', index) == index
|
1087
|
+
r0 = (SyntaxNode).new(input, index...(index + 3))
|
1088
|
+
@index += 3
|
1089
|
+
else
|
1090
|
+
terminal_parse_failure('"""')
|
1091
|
+
r0 = nil
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
node_cache[:triple_quote][start_index] = r0
|
1095
|
+
|
1096
|
+
return r0
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
def _nt_separator
|
1100
|
+
start_index = index
|
1101
|
+
if node_cache[:separator].has_key?(index)
|
1102
|
+
cached = node_cache[:separator][index]
|
1103
|
+
@index = cached.interval.end if cached
|
1104
|
+
return cached
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
if input.index('|', index) == index
|
1108
|
+
r0 = (SyntaxNode).new(input, index...(index + 1))
|
1109
|
+
@index += 1
|
1110
|
+
else
|
1111
|
+
terminal_parse_failure('|')
|
1112
|
+
r0 = nil
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
node_cache[:separator][start_index] = r0
|
1116
|
+
|
1117
|
+
return r0
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
def _nt_space
|
1121
|
+
start_index = index
|
1122
|
+
if node_cache[:space].has_key?(index)
|
1123
|
+
cached = node_cache[:space][index]
|
1124
|
+
@index = cached.interval.end if cached
|
1125
|
+
return cached
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
s0, i0 = [], index
|
1129
|
+
loop do
|
1130
|
+
i1 = index
|
1131
|
+
r2 = _nt_white
|
1132
|
+
if r2
|
1133
|
+
r1 = r2
|
1134
|
+
else
|
1135
|
+
r3 = _nt_comment_to_eol
|
1136
|
+
if r3
|
1137
|
+
r1 = r3
|
1138
|
+
else
|
1139
|
+
self.index = i1
|
1140
|
+
r1 = nil
|
1141
|
+
end
|
1142
|
+
end
|
1143
|
+
if r1
|
1144
|
+
s0 << r1
|
1145
|
+
else
|
1146
|
+
break
|
1147
|
+
end
|
1148
|
+
end
|
1149
|
+
if s0.empty?
|
1150
|
+
self.index = i0
|
1151
|
+
r0 = nil
|
1152
|
+
else
|
1153
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
node_cache[:space][start_index] = r0
|
1157
|
+
|
1158
|
+
return r0
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
module LineToEol0
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
def _nt_line_to_eol
|
1165
|
+
start_index = index
|
1166
|
+
if node_cache[:line_to_eol].has_key?(index)
|
1167
|
+
cached = node_cache[:line_to_eol][index]
|
1168
|
+
@index = cached.interval.end if cached
|
1169
|
+
return cached
|
1170
|
+
end
|
1171
|
+
|
1172
|
+
s0, i0 = [], index
|
1173
|
+
loop do
|
1174
|
+
i1, s1 = index, []
|
1175
|
+
i2 = index
|
1176
|
+
r3 = _nt_eol
|
1177
|
+
if r3
|
1178
|
+
r2 = nil
|
1179
|
+
else
|
1180
|
+
self.index = i2
|
1181
|
+
r2 = SyntaxNode.new(input, index...index)
|
1182
|
+
end
|
1183
|
+
s1 << r2
|
1184
|
+
if r2
|
1185
|
+
if index < input_length
|
1186
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
1187
|
+
@index += 1
|
1188
|
+
else
|
1189
|
+
terminal_parse_failure("any character")
|
1190
|
+
r4 = nil
|
1191
|
+
end
|
1192
|
+
s1 << r4
|
1193
|
+
end
|
1194
|
+
if s1.last
|
1195
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
1196
|
+
r1.extend(LineToEol0)
|
1197
|
+
else
|
1198
|
+
self.index = i1
|
1199
|
+
r1 = nil
|
1200
|
+
end
|
1201
|
+
if r1
|
1202
|
+
s0 << r1
|
1203
|
+
else
|
1204
|
+
break
|
1205
|
+
end
|
1206
|
+
end
|
1207
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
1208
|
+
|
1209
|
+
node_cache[:line_to_eol][start_index] = r0
|
1210
|
+
|
1211
|
+
return r0
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
module CommentToEol0
|
1215
|
+
def line_to_eol
|
1216
|
+
elements[1]
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
def _nt_comment_to_eol
|
1221
|
+
start_index = index
|
1222
|
+
if node_cache[:comment_to_eol].has_key?(index)
|
1223
|
+
cached = node_cache[:comment_to_eol][index]
|
1224
|
+
@index = cached.interval.end if cached
|
1225
|
+
return cached
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
i0, s0 = index, []
|
1229
|
+
if input.index('#', index) == index
|
1230
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
1231
|
+
@index += 1
|
1232
|
+
else
|
1233
|
+
terminal_parse_failure('#')
|
1234
|
+
r1 = nil
|
1235
|
+
end
|
1236
|
+
s0 << r1
|
1237
|
+
if r1
|
1238
|
+
r2 = _nt_line_to_eol
|
1239
|
+
s0 << r2
|
1240
|
+
end
|
1241
|
+
if s0.last
|
1242
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
1243
|
+
r0.extend(CommentToEol0)
|
1244
|
+
else
|
1245
|
+
self.index = i0
|
1246
|
+
r0 = nil
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
node_cache[:comment_to_eol][start_index] = r0
|
1250
|
+
|
1251
|
+
return r0
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
def _nt_white
|
1255
|
+
start_index = index
|
1256
|
+
if node_cache[:white].has_key?(index)
|
1257
|
+
cached = node_cache[:white][index]
|
1258
|
+
@index = cached.interval.end if cached
|
1259
|
+
return cached
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
i0 = index
|
1263
|
+
r1 = _nt_blank
|
1264
|
+
if r1
|
1265
|
+
r0 = r1
|
1266
|
+
else
|
1267
|
+
r2 = _nt_eol
|
1268
|
+
if r2
|
1269
|
+
r0 = r2
|
1270
|
+
else
|
1271
|
+
self.index = i0
|
1272
|
+
r0 = nil
|
1273
|
+
end
|
1274
|
+
end
|
1275
|
+
|
1276
|
+
node_cache[:white][start_index] = r0
|
1277
|
+
|
1278
|
+
return r0
|
1279
|
+
end
|
1280
|
+
|
1281
|
+
def _nt_blank
|
1282
|
+
start_index = index
|
1283
|
+
if node_cache[:blank].has_key?(index)
|
1284
|
+
cached = node_cache[:blank][index]
|
1285
|
+
@index = cached.interval.end if cached
|
1286
|
+
return cached
|
1287
|
+
end
|
1288
|
+
|
1289
|
+
if input.index(Regexp.new('[ \\t]'), index) == index
|
1290
|
+
r0 = (SyntaxNode).new(input, index...(index + 1))
|
1291
|
+
@index += 1
|
1292
|
+
else
|
1293
|
+
r0 = nil
|
1294
|
+
end
|
1295
|
+
|
1296
|
+
node_cache[:blank][start_index] = r0
|
1297
|
+
|
1298
|
+
return r0
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
module Eol0
|
1302
|
+
end
|
1303
|
+
|
1304
|
+
def _nt_eol
|
1305
|
+
start_index = index
|
1306
|
+
if node_cache[:eol].has_key?(index)
|
1307
|
+
cached = node_cache[:eol][index]
|
1308
|
+
@index = cached.interval.end if cached
|
1309
|
+
return cached
|
1310
|
+
end
|
1311
|
+
|
1312
|
+
i0 = index
|
1313
|
+
i1, s1 = index, []
|
1314
|
+
if input.index("\r", index) == index
|
1315
|
+
r2 = (SyntaxNode).new(input, index...(index + 1))
|
1316
|
+
@index += 1
|
1317
|
+
else
|
1318
|
+
terminal_parse_failure("\r")
|
1319
|
+
r2 = nil
|
1320
|
+
end
|
1321
|
+
s1 << r2
|
1322
|
+
if r2
|
1323
|
+
if input.index("\n", index) == index
|
1324
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
1325
|
+
@index += 1
|
1326
|
+
else
|
1327
|
+
terminal_parse_failure("\n")
|
1328
|
+
r4 = nil
|
1329
|
+
end
|
1330
|
+
if r4
|
1331
|
+
r3 = r4
|
1332
|
+
else
|
1333
|
+
r3 = SyntaxNode.new(input, index...index)
|
1334
|
+
end
|
1335
|
+
s1 << r3
|
1336
|
+
end
|
1337
|
+
if s1.last
|
1338
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
1339
|
+
r1.extend(Eol0)
|
1340
|
+
else
|
1341
|
+
self.index = i1
|
1342
|
+
r1 = nil
|
1343
|
+
end
|
1344
|
+
if r1
|
1345
|
+
r0 = r1
|
1346
|
+
else
|
1347
|
+
if input.index("\n", index) == index
|
1348
|
+
r5 = (SyntaxNode).new(input, index...(index + 1))
|
1349
|
+
@index += 1
|
1350
|
+
else
|
1351
|
+
terminal_parse_failure("\n")
|
1352
|
+
r5 = nil
|
1353
|
+
end
|
1354
|
+
if r5
|
1355
|
+
r0 = r5
|
1356
|
+
else
|
1357
|
+
self.index = i0
|
1358
|
+
r0 = nil
|
1359
|
+
end
|
1360
|
+
end
|
1361
|
+
|
1362
|
+
node_cache[:eol][start_index] = r0
|
1363
|
+
|
1364
|
+
return r0
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
def _nt_step_keyword
|
1368
|
+
start_index = index
|
1369
|
+
if node_cache[:step_keyword].has_key?(index)
|
1370
|
+
cached = node_cache[:step_keyword][index]
|
1371
|
+
@index = cached.interval.end if cached
|
1372
|
+
return cached
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
i0 = index
|
1376
|
+
if input.index("GIVN", index) == index
|
1377
|
+
r1 = (SyntaxNode).new(input, index...(index + 4))
|
1378
|
+
@index += 4
|
1379
|
+
else
|
1380
|
+
terminal_parse_failure("GIVN")
|
1381
|
+
r1 = nil
|
1382
|
+
end
|
1383
|
+
if r1
|
1384
|
+
r0 = r1
|
1385
|
+
else
|
1386
|
+
if input.index("WEN", index) == index
|
1387
|
+
r2 = (SyntaxNode).new(input, index...(index + 3))
|
1388
|
+
@index += 3
|
1389
|
+
else
|
1390
|
+
terminal_parse_failure("WEN")
|
1391
|
+
r2 = nil
|
1392
|
+
end
|
1393
|
+
if r2
|
1394
|
+
r0 = r2
|
1395
|
+
else
|
1396
|
+
if input.index("DEN", index) == index
|
1397
|
+
r3 = (SyntaxNode).new(input, index...(index + 3))
|
1398
|
+
@index += 3
|
1399
|
+
else
|
1400
|
+
terminal_parse_failure("DEN")
|
1401
|
+
r3 = nil
|
1402
|
+
end
|
1403
|
+
if r3
|
1404
|
+
r0 = r3
|
1405
|
+
else
|
1406
|
+
if input.index("AN", index) == index
|
1407
|
+
r4 = (SyntaxNode).new(input, index...(index + 2))
|
1408
|
+
@index += 2
|
1409
|
+
else
|
1410
|
+
terminal_parse_failure("AN")
|
1411
|
+
r4 = nil
|
1412
|
+
end
|
1413
|
+
if r4
|
1414
|
+
r0 = r4
|
1415
|
+
else
|
1416
|
+
if input.index("BUT", index) == index
|
1417
|
+
r5 = (SyntaxNode).new(input, index...(index + 3))
|
1418
|
+
@index += 3
|
1419
|
+
else
|
1420
|
+
terminal_parse_failure("BUT")
|
1421
|
+
r5 = nil
|
1422
|
+
end
|
1423
|
+
if r5
|
1424
|
+
r0 = r5
|
1425
|
+
else
|
1426
|
+
self.index = i0
|
1427
|
+
r0 = nil
|
1428
|
+
end
|
1429
|
+
end
|
1430
|
+
end
|
1431
|
+
end
|
1432
|
+
end
|
1433
|
+
|
1434
|
+
node_cache[:step_keyword][start_index] = r0
|
1435
|
+
|
1436
|
+
return r0
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
module ScenarioKeyword0
|
1440
|
+
end
|
1441
|
+
|
1442
|
+
def _nt_scenario_keyword
|
1443
|
+
start_index = index
|
1444
|
+
if node_cache[:scenario_keyword].has_key?(index)
|
1445
|
+
cached = node_cache[:scenario_keyword][index]
|
1446
|
+
@index = cached.interval.end if cached
|
1447
|
+
return cached
|
1448
|
+
end
|
1449
|
+
|
1450
|
+
i0, s0 = index, []
|
1451
|
+
if input.index("MISHUN", index) == index
|
1452
|
+
r1 = (SyntaxNode).new(input, index...(index + 6))
|
1453
|
+
@index += 6
|
1454
|
+
else
|
1455
|
+
terminal_parse_failure("MISHUN")
|
1456
|
+
r1 = nil
|
1457
|
+
end
|
1458
|
+
s0 << r1
|
1459
|
+
if r1
|
1460
|
+
if input.index(":", index) == index
|
1461
|
+
r3 = (SyntaxNode).new(input, index...(index + 1))
|
1462
|
+
@index += 1
|
1463
|
+
else
|
1464
|
+
terminal_parse_failure(":")
|
1465
|
+
r3 = nil
|
1466
|
+
end
|
1467
|
+
if r3
|
1468
|
+
r2 = r3
|
1469
|
+
else
|
1470
|
+
r2 = SyntaxNode.new(input, index...index)
|
1471
|
+
end
|
1472
|
+
s0 << r2
|
1473
|
+
end
|
1474
|
+
if s0.last
|
1475
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
1476
|
+
r0.extend(ScenarioKeyword0)
|
1477
|
+
else
|
1478
|
+
self.index = i0
|
1479
|
+
r0 = nil
|
1480
|
+
end
|
1481
|
+
|
1482
|
+
node_cache[:scenario_keyword][start_index] = r0
|
1483
|
+
|
1484
|
+
return r0
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
module MoreExamplesKeyword0
|
1488
|
+
end
|
1489
|
+
|
1490
|
+
def _nt_more_examples_keyword
|
1491
|
+
start_index = index
|
1492
|
+
if node_cache[:more_examples_keyword].has_key?(index)
|
1493
|
+
cached = node_cache[:more_examples_keyword][index]
|
1494
|
+
@index = cached.interval.end if cached
|
1495
|
+
return cached
|
1496
|
+
end
|
1497
|
+
|
1498
|
+
i0, s0 = index, []
|
1499
|
+
if input.index("MOAR EXAMPLZ", index) == index
|
1500
|
+
r1 = (SyntaxNode).new(input, index...(index + 12))
|
1501
|
+
@index += 12
|
1502
|
+
else
|
1503
|
+
terminal_parse_failure("MOAR EXAMPLZ")
|
1504
|
+
r1 = nil
|
1505
|
+
end
|
1506
|
+
s0 << r1
|
1507
|
+
if r1
|
1508
|
+
if input.index(":", index) == index
|
1509
|
+
r3 = (SyntaxNode).new(input, index...(index + 1))
|
1510
|
+
@index += 1
|
1511
|
+
else
|
1512
|
+
terminal_parse_failure(":")
|
1513
|
+
r3 = nil
|
1514
|
+
end
|
1515
|
+
if r3
|
1516
|
+
r2 = r3
|
1517
|
+
else
|
1518
|
+
r2 = SyntaxNode.new(input, index...index)
|
1519
|
+
end
|
1520
|
+
s0 << r2
|
1521
|
+
end
|
1522
|
+
if s0.last
|
1523
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
1524
|
+
r0.extend(MoreExamplesKeyword0)
|
1525
|
+
else
|
1526
|
+
self.index = i0
|
1527
|
+
r0 = nil
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
node_cache[:more_examples_keyword][start_index] = r0
|
1531
|
+
|
1532
|
+
return r0
|
1533
|
+
end
|
1534
|
+
|
1535
|
+
module GivenScenarioKeyword0
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
def _nt_given_scenario_keyword
|
1539
|
+
start_index = index
|
1540
|
+
if node_cache[:given_scenario_keyword].has_key?(index)
|
1541
|
+
cached = node_cache[:given_scenario_keyword][index]
|
1542
|
+
@index = cached.interval.end if cached
|
1543
|
+
return cached
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
i0, s0 = index, []
|
1547
|
+
if input.index("SRSLY", index) == index
|
1548
|
+
r1 = (SyntaxNode).new(input, index...(index + 5))
|
1549
|
+
@index += 5
|
1550
|
+
else
|
1551
|
+
terminal_parse_failure("SRSLY")
|
1552
|
+
r1 = nil
|
1553
|
+
end
|
1554
|
+
s0 << r1
|
1555
|
+
if r1
|
1556
|
+
if input.index(":", index) == index
|
1557
|
+
r3 = (SyntaxNode).new(input, index...(index + 1))
|
1558
|
+
@index += 1
|
1559
|
+
else
|
1560
|
+
terminal_parse_failure(":")
|
1561
|
+
r3 = nil
|
1562
|
+
end
|
1563
|
+
if r3
|
1564
|
+
r2 = r3
|
1565
|
+
else
|
1566
|
+
r2 = SyntaxNode.new(input, index...index)
|
1567
|
+
end
|
1568
|
+
s0 << r2
|
1569
|
+
end
|
1570
|
+
if s0.last
|
1571
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
1572
|
+
r0.extend(GivenScenarioKeyword0)
|
1573
|
+
else
|
1574
|
+
self.index = i0
|
1575
|
+
r0 = nil
|
1576
|
+
end
|
1577
|
+
|
1578
|
+
node_cache[:given_scenario_keyword][start_index] = r0
|
1579
|
+
|
1580
|
+
return r0
|
1581
|
+
end
|
1582
|
+
|
1583
|
+
end
|
1584
|
+
|
1585
|
+
class FeatureParser < Treetop::Runtime::CompiledParser
|
1586
|
+
include Feature
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
|
1590
|
+
end
|
1591
|
+
end
|