worked 0.1.0 → 0.2.0

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.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,8 @@
1
+ == 0.2.0 2009-06-12
2
+
3
+ * 1 major enhancement:
4
+ * Create Gruff Graphs
5
+
1
6
  == 0.1.0 2009-02-19
2
7
 
3
8
  * 1 major enhancement:
@@ -7,18 +7,24 @@ bin/worked
7
7
  config/website.yml
8
8
  lib/worked.rb
9
9
  lib/worked/cli.rb
10
+ lib/worked/graph.rb
11
+ lib/worked/inputgrammar.rb
10
12
  lib/worked/inputgrammar.treetop
11
13
  lib/worked/inputparser.rb
14
+ lib/worked/reader.rb
12
15
  lib/worked/recorder.rb
13
16
  script/console
14
17
  script/destroy
15
18
  script/generate
16
19
  script/txt2html
20
+ tasks/parser_generate.rake
17
21
  tasks/website.rake
18
22
  test/test_grammar.rb
19
23
  test/test_helper.rb
24
+ test/test_reader.rb
20
25
  test/test_worked.rb
21
26
  test/test_worked_cli.rb
27
+ website/index.html
22
28
  website/javascripts/rounded_corners_lite.inc.js
23
29
  website/stylesheets/screen.css
24
30
  website/template.rhtml
@@ -1,9 +1,9 @@
1
1
  = Worked
2
2
 
3
- The easiest time recording application imagineable.
4
-
5
3
  * http://worked.rubyforge.org/
6
4
 
5
+ The easiest time recording application imagineable.
6
+
7
7
  == DESCRIPTION:
8
8
 
9
9
  Worked is really the simplest time recording (or tracking, whatever term you
@@ -19,6 +19,7 @@ Right now, the times are just recorded, no report generation yet.
19
19
  == FEATURES:
20
20
 
21
21
  * Appends a time range and an activity to a file.
22
+ * Create a graph from the collected data, showing hours/week.
22
23
 
23
24
  == SYNOPSIS:
24
25
 
@@ -57,6 +58,9 @@ write:
57
58
  Specifying dates is not supported right now, but you can of course edit the file
58
59
  directly if necessary.
59
60
 
61
+ Since version 0.2, worked also has the ability to generate a graph from the
62
+ collected data, using the -g argument. [TODO: Add image here.]
63
+
60
64
  == STORY:
61
65
 
62
66
  The week before my new semester started, I promised to myself to do better (or,
data/Rakefile CHANGED
@@ -9,6 +9,7 @@ $hoe = Hoe.new('worked', Worked::VERSION) do |p|
9
9
  p.rubyforge_name = p.name
10
10
  p.extra_deps = [
11
11
  ['treetop','>= 1.2.4'],
12
+ ['gruff','>= 0.3.1'],
12
13
  ]
13
14
  p.extra_dev_deps = [
14
15
  ['newgem', ">= #{::Newgem::VERSION}"]
data/bin/worked CHANGED
@@ -9,6 +9,6 @@ require "worked/cli"
9
9
 
10
10
  CONFIG = File.join(Dir.getwd, ".worked")
11
11
 
12
- File.open(CONFIG, "a") do |file|
13
- Worked::CLI.execute(STDOUT, ARGV.join(" "), file)
12
+ File.open(CONFIG, "a+") do |file|
13
+ Worked::CLI.execute(STDOUT, ARGV, file)
14
14
  end
@@ -4,5 +4,5 @@ $:.unshift(File.dirname(__FILE__)) unless
4
4
  require 'worked/inputparser'
5
5
 
6
6
  module Worked
7
- VERSION = '0.1.0'
7
+ VERSION = '0.2.0'
8
8
  end
@@ -1,37 +1,68 @@
1
1
  require 'optparse'
2
2
  require 'worked/recorder'
3
+ require 'worked/graph'
3
4
 
4
5
  module Worked
5
6
  class CLI
6
7
  def self.execute(stdout, arguments, file)
7
8
 
8
- Recorder.new(file).record(arguments)
9
+ if arguments.empty?
10
+ parse_options(stdout, ["--help"], file)
11
+ end
9
12
 
10
- #options = {
11
- # :path => '~'
12
- #}
13
+ begin
13
14
 
14
- #parser = OptionParser.new do |opts|
15
- # opts.banner = <<-BANNER.gsub(/^ /,'')
16
- # This application is wonderful because...
15
+ try_to_parse(file, arguments.join(" "))
17
16
 
18
- # Usage: #{File.basename($0)} [options]
17
+ rescue CannotParse
19
18
 
20
- # Options are:
21
- # BANNER
22
- # opts.separator ""
23
- # opts.on("-p", "--path=PATH", String,
24
- # "This is a sample message.",
25
- # "For multiple lines, add more strings.",
26
- # "Default: ~") { |arg| options[:path] = arg }
27
- # opts.on("-h", "--help",
28
- # "Show this help message.") { stdout.puts opts; exit }
19
+ options = parse_options(stdout, arguments, file)
29
20
 
30
- # opts.parse!(arguments)
31
- #end
21
+ if options[:graph_path]
32
22
 
33
- #path = options[:path]
23
+ graph(stdout, file, options[:graph_path])
34
24
 
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.try_to_parse file, string
30
+
31
+ Recorder.new(file).record(string)
32
+ end
33
+
34
+ def self.graph stdout, file, path
35
+
36
+ Graph::create_weekly(Reader::by_week(file.readlines), path)
37
+
38
+ stdout.puts "Graph saved to #{path}."
39
+ end
40
+
41
+ def self.parse_options(stdout, arguments, file)
42
+
43
+ options = {}
44
+
45
+ parser = OptionParser.new do |opts|
46
+ opts.banner = <<-BANNER.gsub(/^ /,'')
47
+ This application is wonderful!
48
+
49
+ Usage: #{File.basename($0)} [options]
50
+ #{File.basename($0)} work time specification
51
+
52
+ Options are:
53
+ BANNER
54
+ opts.separator ""
55
+ opts.on("-g", "--graph=PATH", String,
56
+ "Prints a graph to the specified file.") { |arg|
57
+ options[:graph_path] = arg
58
+ }
59
+ opts.on("-h", "--help",
60
+ "Show this help message.") { stdout.puts opts; exit }
61
+
62
+ opts.parse!(arguments)
63
+ end
64
+
65
+ options
35
66
  end
36
67
  end
37
68
  end
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'gruff'
3
+
4
+ require 'worked/reader'
5
+
6
+ module Worked
7
+
8
+ class Graph
9
+
10
+ def self.create_weekly entries, output_file
11
+ create(entries, output_file)
12
+ end
13
+
14
+ def self.create_daily entries, output_file
15
+ create(entries, output_file)
16
+ end
17
+
18
+ private
19
+
20
+ def self.create entries, output_file
21
+
22
+ g = Gruff::Bar.new
23
+ g.title = "My Work Hours"
24
+ g.y_axis_increment = 2
25
+ g.y_axis_label = "Hours"
26
+ g.x_axis_label = "Week of the Year"
27
+
28
+ g.data("Total: #{entries.sum{|e| e.hours.to_f}.to_i.to_s} Hours", entries.collect {|e| e.hours.to_f})
29
+
30
+ g.minimum_value = 0
31
+
32
+ g.labels = entries.inject({}) {|h, e| h.merge( { h.size => e.date.to_s }) }
33
+
34
+ g.write output_file
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,741 @@
1
+
2
+ module InputGrammar
3
+ include Treetop::Runtime
4
+
5
+ def root
6
+ @root || :root
7
+ end
8
+
9
+ module Root0
10
+ def time
11
+ elements[0]
12
+ end
13
+
14
+ def activity
15
+ elements[2]
16
+ end
17
+ end
18
+
19
+ def _nt_root
20
+ start_index = index
21
+ if node_cache[:root].has_key?(index)
22
+ cached = node_cache[:root][index]
23
+ @index = cached.interval.end if cached
24
+ return cached
25
+ end
26
+
27
+ i0, s0 = index, []
28
+ r1 = _nt_time
29
+ s0 << r1
30
+ if r1
31
+ if input.index(" on ", index) == index
32
+ r2 = instantiate_node(SyntaxNode,input, index...(index + 4))
33
+ @index += 4
34
+ else
35
+ terminal_parse_failure(" on ")
36
+ r2 = nil
37
+ end
38
+ s0 << r2
39
+ if r2
40
+ r3 = _nt_activity
41
+ s0 << r3
42
+ end
43
+ end
44
+ if s0.last
45
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
46
+ r0.extend(Root0)
47
+ else
48
+ self.index = i0
49
+ r0 = nil
50
+ end
51
+
52
+ node_cache[:root][start_index] = r0
53
+
54
+ return r0
55
+ end
56
+
57
+ def _nt_activity
58
+ start_index = index
59
+ if node_cache[:activity].has_key?(index)
60
+ cached = node_cache[:activity][index]
61
+ @index = cached.interval.end if cached
62
+ return cached
63
+ end
64
+
65
+ s0, i0 = [], index
66
+ loop do
67
+ if index < input_length
68
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
69
+ @index += 1
70
+ else
71
+ terminal_parse_failure("any character")
72
+ r1 = nil
73
+ end
74
+ if r1
75
+ s0 << r1
76
+ else
77
+ break
78
+ end
79
+ end
80
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
81
+
82
+ node_cache[:activity][start_index] = r0
83
+
84
+ return r0
85
+ end
86
+
87
+ def _nt_time
88
+ start_index = index
89
+ if node_cache[:time].has_key?(index)
90
+ cached = node_cache[:time][index]
91
+ @index = cached.interval.end if cached
92
+ return cached
93
+ end
94
+
95
+ i0 = index
96
+ r1 = _nt_time_from
97
+ if r1
98
+ r0 = r1
99
+ else
100
+ r2 = _nt_time_in_words
101
+ if r2
102
+ r0 = r2
103
+ else
104
+ r3 = _nt_time_range
105
+ if r3
106
+ r0 = r3
107
+ else
108
+ r4 = _nt_time_in_digits
109
+ if r4
110
+ r0 = r4
111
+ else
112
+ self.index = i0
113
+ r0 = nil
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ node_cache[:time][start_index] = r0
120
+
121
+ return r0
122
+ end
123
+
124
+ module TimeFrom0
125
+ def am_pm_time
126
+ elements[1]
127
+ end
128
+ end
129
+
130
+ module TimeFrom1
131
+ def from
132
+ am_pm_time.to_24h
133
+ end
134
+ end
135
+
136
+ def _nt_time_from
137
+ start_index = index
138
+ if node_cache[:time_from].has_key?(index)
139
+ cached = node_cache[:time_from][index]
140
+ @index = cached.interval.end if cached
141
+ return cached
142
+ end
143
+
144
+ i0, s0 = index, []
145
+ if input.index("from ", index) == index
146
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 5))
147
+ @index += 5
148
+ else
149
+ terminal_parse_failure("from ")
150
+ r1 = nil
151
+ end
152
+ s0 << r1
153
+ if r1
154
+ r2 = _nt_am_pm_time
155
+ s0 << r2
156
+ end
157
+ if s0.last
158
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
159
+ r0.extend(TimeFrom0)
160
+ r0.extend(TimeFrom1)
161
+ else
162
+ self.index = i0
163
+ r0 = nil
164
+ end
165
+
166
+ node_cache[:time_from][start_index] = r0
167
+
168
+ return r0
169
+ end
170
+
171
+ module TimeRange0
172
+ def f
173
+ elements[0]
174
+ end
175
+
176
+ def t
177
+ elements[2]
178
+ end
179
+ end
180
+
181
+ module TimeRange1
182
+ def from
183
+ f.to_24h
184
+ end
185
+
186
+ def to
187
+ t.to_24h
188
+ end
189
+ end
190
+
191
+ def _nt_time_range
192
+ start_index = index
193
+ if node_cache[:time_range].has_key?(index)
194
+ cached = node_cache[:time_range][index]
195
+ @index = cached.interval.end if cached
196
+ return cached
197
+ end
198
+
199
+ i0, s0 = index, []
200
+ r1 = _nt_am_pm_time
201
+ s0 << r1
202
+ if r1
203
+ if input.index(" to ", index) == index
204
+ r2 = instantiate_node(SyntaxNode,input, index...(index + 4))
205
+ @index += 4
206
+ else
207
+ terminal_parse_failure(" to ")
208
+ r2 = nil
209
+ end
210
+ s0 << r2
211
+ if r2
212
+ r3 = _nt_am_pm_time
213
+ s0 << r3
214
+ end
215
+ end
216
+ if s0.last
217
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
218
+ r0.extend(TimeRange0)
219
+ r0.extend(TimeRange1)
220
+ else
221
+ self.index = i0
222
+ r0 = nil
223
+ end
224
+
225
+ node_cache[:time_range][start_index] = r0
226
+
227
+ return r0
228
+ end
229
+
230
+ module AmPmTime0
231
+ def time_in_digits
232
+ elements[0]
233
+ end
234
+
235
+ def am_pm
236
+ elements[1]
237
+ end
238
+ end
239
+
240
+ module AmPmTime1
241
+ def to_24h
242
+
243
+ if methods.include?("am_pm") && am_pm.text_value =~ /pm/
244
+ return time_in_digits.total + 12.hours
245
+ end
246
+
247
+ time_in_digits.total
248
+ end
249
+ end
250
+
251
+ def _nt_am_pm_time
252
+ start_index = index
253
+ if node_cache[:am_pm_time].has_key?(index)
254
+ cached = node_cache[:am_pm_time][index]
255
+ @index = cached.interval.end if cached
256
+ return cached
257
+ end
258
+
259
+ i0, s0 = index, []
260
+ r1 = _nt_time_in_digits
261
+ s0 << r1
262
+ if r1
263
+ i3 = index
264
+ if input.index(" am", index) == index
265
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 3))
266
+ @index += 3
267
+ else
268
+ terminal_parse_failure(" am")
269
+ r4 = nil
270
+ end
271
+ if r4
272
+ r3 = r4
273
+ else
274
+ if input.index(" pm", index) == index
275
+ r5 = instantiate_node(SyntaxNode,input, index...(index + 3))
276
+ @index += 3
277
+ else
278
+ terminal_parse_failure(" pm")
279
+ r5 = nil
280
+ end
281
+ if r5
282
+ r3 = r5
283
+ else
284
+ if input.index("am", index) == index
285
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 2))
286
+ @index += 2
287
+ else
288
+ terminal_parse_failure("am")
289
+ r6 = nil
290
+ end
291
+ if r6
292
+ r3 = r6
293
+ else
294
+ if input.index("pm", index) == index
295
+ r7 = instantiate_node(SyntaxNode,input, index...(index + 2))
296
+ @index += 2
297
+ else
298
+ terminal_parse_failure("pm")
299
+ r7 = nil
300
+ end
301
+ if r7
302
+ r3 = r7
303
+ else
304
+ self.index = i3
305
+ r3 = nil
306
+ end
307
+ end
308
+ end
309
+ end
310
+ if r3
311
+ r2 = r3
312
+ else
313
+ r2 = instantiate_node(SyntaxNode,input, index...index)
314
+ end
315
+ s0 << r2
316
+ end
317
+ if s0.last
318
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
319
+ r0.extend(AmPmTime0)
320
+ r0.extend(AmPmTime1)
321
+ else
322
+ self.index = i0
323
+ r0 = nil
324
+ end
325
+
326
+ node_cache[:am_pm_time][start_index] = r0
327
+
328
+ return r0
329
+ end
330
+
331
+ module TimeInWords0
332
+ def minutes
333
+ elements[1]
334
+ end
335
+ end
336
+
337
+ module TimeInWords1
338
+ def hours
339
+ elements[0]
340
+ end
341
+
342
+ def m
343
+ elements[1]
344
+ end
345
+ end
346
+
347
+ module TimeInWords2
348
+ def total
349
+ minutes.to_i.minutes + hours.to_i.hours + m.to_i.minutes
350
+ end
351
+ end
352
+
353
+ def _nt_time_in_words
354
+ start_index = index
355
+ if node_cache[:time_in_words].has_key?(index)
356
+ cached = node_cache[:time_in_words][index]
357
+ @index = cached.interval.end if cached
358
+ return cached
359
+ end
360
+
361
+ i0 = index
362
+ r1 = _nt_minutes
363
+ if r1
364
+ r0 = r1
365
+ else
366
+ i2, s2 = index, []
367
+ r3 = _nt_hours
368
+ s2 << r3
369
+ if r3
370
+ i5, s5 = index, []
371
+ if input.index(" ", index) == index
372
+ r7 = instantiate_node(SyntaxNode,input, index...(index + 1))
373
+ @index += 1
374
+ else
375
+ terminal_parse_failure(" ")
376
+ r7 = nil
377
+ end
378
+ if r7
379
+ r6 = r7
380
+ else
381
+ r6 = instantiate_node(SyntaxNode,input, index...index)
382
+ end
383
+ s5 << r6
384
+ if r6
385
+ r8 = _nt_minutes
386
+ s5 << r8
387
+ end
388
+ if s5.last
389
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
390
+ r5.extend(TimeInWords0)
391
+ else
392
+ self.index = i5
393
+ r5 = nil
394
+ end
395
+ if r5
396
+ r4 = r5
397
+ else
398
+ r4 = instantiate_node(SyntaxNode,input, index...index)
399
+ end
400
+ s2 << r4
401
+ end
402
+ if s2.last
403
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
404
+ r2.extend(TimeInWords1)
405
+ r2.extend(TimeInWords2)
406
+ else
407
+ self.index = i2
408
+ r2 = nil
409
+ end
410
+ if r2
411
+ r0 = r2
412
+ else
413
+ self.index = i0
414
+ r0 = nil
415
+ end
416
+ end
417
+
418
+ node_cache[:time_in_words][start_index] = r0
419
+
420
+ return r0
421
+ end
422
+
423
+ module TimeInDigits0
424
+ def integer
425
+ elements[1]
426
+ end
427
+ end
428
+
429
+ module TimeInDigits1
430
+ def integer
431
+ elements[0]
432
+ end
433
+
434
+ def m
435
+ elements[1]
436
+ end
437
+ end
438
+
439
+ module TimeInDigits2
440
+ def total
441
+ integer.to_i.hours + m.to_i.minutes
442
+ end
443
+ end
444
+
445
+ def _nt_time_in_digits
446
+ start_index = index
447
+ if node_cache[:time_in_digits].has_key?(index)
448
+ cached = node_cache[:time_in_digits][index]
449
+ @index = cached.interval.end if cached
450
+ return cached
451
+ end
452
+
453
+ i0, s0 = index, []
454
+ r1 = _nt_integer
455
+ s0 << r1
456
+ if r1
457
+ i3, s3 = index, []
458
+ if input.index(":", index) == index
459
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
460
+ @index += 1
461
+ else
462
+ terminal_parse_failure(":")
463
+ r4 = nil
464
+ end
465
+ s3 << r4
466
+ if r4
467
+ r5 = _nt_integer
468
+ s3 << r5
469
+ end
470
+ if s3.last
471
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
472
+ r3.extend(TimeInDigits0)
473
+ else
474
+ self.index = i3
475
+ r3 = nil
476
+ end
477
+ if r3
478
+ r2 = r3
479
+ else
480
+ r2 = instantiate_node(SyntaxNode,input, index...index)
481
+ end
482
+ s0 << r2
483
+ end
484
+ if s0.last
485
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
486
+ r0.extend(TimeInDigits1)
487
+ r0.extend(TimeInDigits2)
488
+ else
489
+ self.index = i0
490
+ r0 = nil
491
+ end
492
+
493
+ node_cache[:time_in_digits][start_index] = r0
494
+
495
+ return r0
496
+ end
497
+
498
+ module Hours0
499
+ end
500
+
501
+ module Hours1
502
+ def integer
503
+ elements[0]
504
+ end
505
+
506
+ end
507
+
508
+ def _nt_hours
509
+ start_index = index
510
+ if node_cache[:hours].has_key?(index)
511
+ cached = node_cache[:hours][index]
512
+ @index = cached.interval.end if cached
513
+ return cached
514
+ end
515
+
516
+ i0, s0 = index, []
517
+ r1 = _nt_integer
518
+ s0 << r1
519
+ if r1
520
+ if input.index(" ", index) == index
521
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
522
+ @index += 1
523
+ else
524
+ terminal_parse_failure(" ")
525
+ r3 = nil
526
+ end
527
+ if r3
528
+ r2 = r3
529
+ else
530
+ r2 = instantiate_node(SyntaxNode,input, index...index)
531
+ end
532
+ s0 << r2
533
+ if r2
534
+ i4 = index
535
+ i5, s5 = index, []
536
+ if input.index("hour", index) == index
537
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 4))
538
+ @index += 4
539
+ else
540
+ terminal_parse_failure("hour")
541
+ r6 = nil
542
+ end
543
+ s5 << r6
544
+ if r6
545
+ if input.index("s", index) == index
546
+ r8 = instantiate_node(SyntaxNode,input, index...(index + 1))
547
+ @index += 1
548
+ else
549
+ terminal_parse_failure("s")
550
+ r8 = nil
551
+ end
552
+ if r8
553
+ r7 = r8
554
+ else
555
+ r7 = instantiate_node(SyntaxNode,input, index...index)
556
+ end
557
+ s5 << r7
558
+ end
559
+ if s5.last
560
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
561
+ r5.extend(Hours0)
562
+ else
563
+ self.index = i5
564
+ r5 = nil
565
+ end
566
+ if r5
567
+ r4 = r5
568
+ else
569
+ if input.index("h", index) == index
570
+ r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
571
+ @index += 1
572
+ else
573
+ terminal_parse_failure("h")
574
+ r9 = nil
575
+ end
576
+ if r9
577
+ r4 = r9
578
+ else
579
+ self.index = i4
580
+ r4 = nil
581
+ end
582
+ end
583
+ s0 << r4
584
+ end
585
+ end
586
+ if s0.last
587
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
588
+ r0.extend(Hours1)
589
+ else
590
+ self.index = i0
591
+ r0 = nil
592
+ end
593
+
594
+ node_cache[:hours][start_index] = r0
595
+
596
+ return r0
597
+ end
598
+
599
+ module Minutes0
600
+ end
601
+
602
+ module Minutes1
603
+ def integer
604
+ elements[0]
605
+ end
606
+
607
+ end
608
+
609
+ module Minutes2
610
+ def total
611
+ integer.to_i.minutes
612
+ end
613
+ end
614
+
615
+ def _nt_minutes
616
+ start_index = index
617
+ if node_cache[:minutes].has_key?(index)
618
+ cached = node_cache[:minutes][index]
619
+ @index = cached.interval.end if cached
620
+ return cached
621
+ end
622
+
623
+ i0, s0 = index, []
624
+ r1 = _nt_integer
625
+ s0 << r1
626
+ if r1
627
+ if input.index(" ", index) == index
628
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
629
+ @index += 1
630
+ else
631
+ terminal_parse_failure(" ")
632
+ r3 = nil
633
+ end
634
+ if r3
635
+ r2 = r3
636
+ else
637
+ r2 = instantiate_node(SyntaxNode,input, index...index)
638
+ end
639
+ s0 << r2
640
+ if r2
641
+ i4 = index
642
+ i5, s5 = index, []
643
+ if input.index("minute", index) == index
644
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 6))
645
+ @index += 6
646
+ else
647
+ terminal_parse_failure("minute")
648
+ r6 = nil
649
+ end
650
+ s5 << r6
651
+ if r6
652
+ if input.index("s", index) == index
653
+ r8 = instantiate_node(SyntaxNode,input, index...(index + 1))
654
+ @index += 1
655
+ else
656
+ terminal_parse_failure("s")
657
+ r8 = nil
658
+ end
659
+ if r8
660
+ r7 = r8
661
+ else
662
+ r7 = instantiate_node(SyntaxNode,input, index...index)
663
+ end
664
+ s5 << r7
665
+ end
666
+ if s5.last
667
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
668
+ r5.extend(Minutes0)
669
+ else
670
+ self.index = i5
671
+ r5 = nil
672
+ end
673
+ if r5
674
+ r4 = r5
675
+ else
676
+ if input.index("m", index) == index
677
+ r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
678
+ @index += 1
679
+ else
680
+ terminal_parse_failure("m")
681
+ r9 = nil
682
+ end
683
+ if r9
684
+ r4 = r9
685
+ else
686
+ self.index = i4
687
+ r4 = nil
688
+ end
689
+ end
690
+ s0 << r4
691
+ end
692
+ end
693
+ if s0.last
694
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
695
+ r0.extend(Minutes1)
696
+ r0.extend(Minutes2)
697
+ else
698
+ self.index = i0
699
+ r0 = nil
700
+ end
701
+
702
+ node_cache[:minutes][start_index] = r0
703
+
704
+ return r0
705
+ end
706
+
707
+ def _nt_integer
708
+ start_index = index
709
+ if node_cache[:integer].has_key?(index)
710
+ cached = node_cache[:integer][index]
711
+ @index = cached.interval.end if cached
712
+ return cached
713
+ end
714
+
715
+ s0, i0 = [], index
716
+ loop do
717
+ if input.index(Regexp.new('[0-9]'), index) == index
718
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
719
+ @index += 1
720
+ else
721
+ r1 = nil
722
+ end
723
+ if r1
724
+ s0 << r1
725
+ else
726
+ break
727
+ end
728
+ end
729
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
730
+
731
+ node_cache[:integer][start_index] = r0
732
+
733
+ return r0
734
+ end
735
+
736
+ end
737
+
738
+ class InputGrammarParser < Treetop::Runtime::CompiledParser
739
+ include InputGrammar
740
+ end
741
+