Class: Tap::Support::Parser

Inherits:
Object show all
Includes:
Utils
Defined in:
lib/tap/support/parser.rb

Overview

Syntax

Round Assignment

Tasks can be defined and set to a round using the following:

break           assigns task(s)         to round
--              next                    0
--+             next                    1
--++            next                    2
--+2            next                    2
--+2[1,2,3]     1,2,3                   2

Here all task (except c) are parsed into round 0, then the final argument reassigns e to round 3.

schema = Parser.new("a -- b --+ c -- d -- e --+3[4]").schema
schema.rounds(true)             # => [[0,1,3],[2], nil, [4]]

Workflow Assignment

All simple workflow patterns except switch can be specified within the parse syntax (switch is the exception because there is no good way to define the switch block).

break      pattern       source(s)      target(s)
--:        sequence      last           next
--[]       fork          last           next
--{}       merge         next           last
--()       sync_merge    next           last

example       meaning
--1:2         1.sequence(2)
--1:2:3       1.sequence(2,3)
--:2:         last.sequence(2,next)
--[]          last.fork(next)
--1{2,3,4}    1.merge(2,3,4)
--(2,3,4)     last.sync_merge(2,3,4)

Note how all of the bracketed styles behave similarly; they are parsed with essentially the same code, but reverse the source and target in the case of merges.

Here a and b are sequenced inline. Task c is assigned to no workflow until the final argument which sequenced b and c.

schema = Parser.new("a --: b -- c --1:2i").schema
schema.argvs                    # => [["a"], ["b"], ["c"], []]
schema.joins(true)              # => [[:sequence,0,[1],{}], [:sequence,1,[2],{:iterate => true}]]

Globals

Global instances of task (used, for example, by dependencies) may be assigned in the parse syntax as well. The break for a global is ‘–*’.

schema = Parser.new("a -- b --* global_name --config for --global").schema
schema.globals(true)            # => [2]

Escapes and End Flags

Breaks can be escaped by enclosing them in ‘-.’ and ‘.-’ delimiters; any number of arguments may be enclosed within the escape. After the end delimiter, breaks are active once again.

schema = Parser.new("a -- b -- c").schema
schema.argvs                    # => [["a"], ["b"], ["c"]]

schema = Parser.new("a -. -- b .- -- c").schema
schema.argvs                    # => [["a", "--", "b"], ["c"]]

Parsing continues until the end of argv, or a an end flag ‘—’ is reached. The end flag may also be escaped.

schema = Parser.new("a -- b --- c").schema
schema.argvs                    # => [["a"], ["b"]]

Defined Under Namespace

Modules: Utils

Constant Summary

Constants included from Utils

Utils::BREAK, Utils::END_FLAG, Utils::ESCAPE_BEGIN, Utils::ESCAPE_END, Utils::FORK, Utils::INSTANCE, Utils::MERGE, Utils::ROUND, Utils::SEQUENCE, Utils::SYNC_MERGE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

bracket_regexp, parse_argh, parse_bracket, parse_indicies, parse_instance, parse_options, parse_round, parse_sequence

Constructor Details

#initialize(argv = []) ⇒ Parser

Returns a new instance of Parser.



307
308
309
310
311
# File 'lib/tap/support/parser.rb', line 307

def initialize(argv=[])
  @current_index = 0
  @schema = Schema.new
  parse(argv)
end

Instance Attribute Details

#schemaObject (readonly)

The schema into which nodes are parsed



305
306
307
# File 'lib/tap/support/parser.rb', line 305

def schema
  @schema
end

Instance Method Details

#load(argv) ⇒ Object



389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/tap/support/parser.rb', line 389

def load(argv)
   argv.each do |arg|
    case arg
    when Array
      schema.nodes << arg
      self.current_index += 1
    else
      parse_break(arg)
    end
  end
  
  schema
end

#parse(argv) ⇒ Object

Iterates through the argv splitting out task and workflow definitions. Task definitions are split out (with configurations) along round and/or workflow break lines. Rounds and workflows are dynamically parsed; tasks may be reassigned to different rounds or workflows by later arguments.

Parse is non-destructive to argv. If a string argv is provided, parse splits it into an array using Shellwords; if a hash argv is provided, parse converts it to an array using Parser::Utils#parse_argh.



323
324
325
# File 'lib/tap/support/parser.rb', line 323

def parse(argv)
  parse!(argv.kind_of?(String) ? argv : argv.dup)
end

#parse!(argv) ⇒ Object

Same as parse, but removes parsed args from argv.



328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/tap/support/parser.rb', line 328

def parse!(argv)
  argv = case argv
  when Array then argv
  when String then Shellwords.shellwords(argv) 
  when Hash then parse_argh(argv)
  else argv
  end
  argv.unshift('--')
  
  escape = false
  current_argv = schema[current_index].argv        
  
  while !argv.empty?
    arg = argv.shift

    # if escaping, add escaped arguments 
    # until an escape-end argument
    if escape
      if arg == ESCAPE_END
        escape = false
      else
        current_argv << arg
      end

      next
    end
    
    case arg
    when ESCAPE_BEGIN
      # begin escaping if indicated
      escape = true
      
    when END_FLAG
      # break on an end-flag
      break
    
    when BREAK
      # a breaking argument was reached:
      # unless the current argv is empty,
      # append and start a new definition
      unless current_argv.empty?
        self.current_index += 1
        current_argv = schema[current_index].argv
      end
      
      # parse the break string for any
      # schema modifications
      parse_break($1)
      
    else
      # add all other non-breaking args to
      # the current argv; this includes
      # both inputs and configurations
      current_argv << arg
      
    end
  end

  schema
end