lib/tap/support/parser.rb in bahuvrihi-tap-0.10.7 vs lib/tap/support/parser.rb in bahuvrihi-tap-0.10.8

- old
+ new

@@ -2,10 +2,12 @@ autoload(:Shellwords, 'shellwords') module Tap module Support + # == Syntax + # # ==== Round Assignment # Tasks can be defined and set to a round using the following: # # break assigns task(s) to round # -- next 0 @@ -21,11 +23,11 @@ # 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 a block from an array). + # way to define the switch block). # # break pattern source(s) target(s) # --: sequence last next # --[] fork last next # --{} merge next last @@ -38,11 +40,11 @@ # --[] 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, only reversing the source + # 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. # @@ -244,10 +246,59 @@ options[Join::FLAGS[index]] = true end options end + + # Parses an arg hash into a schema argv. An arg hash is a hash + # using numeric keys to specify the [row][col] in a two-dimensional + # array where a set of values should go. Breaks are added between + # rows (if necessary) and the array is collapsed to yield the + # argv: + # + # argh = { + # 0 => { + # 0 => 'a', + # 1 => ['b', 'c']}, + # 1 => 'z' + # } + # parse_argh(argh) # => ['--', 'a', 'b', 'c', '--', 'z'] + # + # Non-numeric keys are converted to integers using to_i and + # existing breaks (such as workflow breaks) occuring at the + # start of a row are preseved. + # + # argh = { + # '0' => { + # '0' => 'a', + # '1' => ['b', 'c']}, + # '1' => ['--:', 'z'] + # } + # parse_argh(argh) # => ['--', 'a', 'b', 'c', '--:', 'z'] + # + def parse_argh(argh) + rows = [] + argh.each_pair do |row, values| + if values.kind_of?(Hash) + arry = [] + values.each_pair {|col, value| arry[col.to_i] = value } + values = arry + end + + rows[row.to_i] = values + end + + argv = [] + rows.each do |row| + row = [row].flatten.compact + if row.empty? || row[0] !~ BREAK + argv << '--' + end + argv.concat row + end + argv + end end include Utils # The schema into which nodes are parsed @@ -264,19 +315,25 @@ # 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. + # splits it into an array using Shellwords; if a hash argv is provided, + # parse converts it to an array using Parser::Utils#parse_argh. # def parse(argv) parse!(argv.kind_of?(String) ? argv : argv.dup) end # Same as parse, but removes parsed args from argv. def parse!(argv) - argv = Shellwords.shellwords(argv) if argv.kind_of?(String) + 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 @@ -344,13 +401,13 @@ end protected # The index of the node currently being parsed. - attr_accessor :current_index + attr_accessor :current_index # :nodoc: # Returns current_index-1, or raises an error if current_index < 1. - def previous_index + def previous_index # :nodoc: raise ArgumentError, 'there is no previous index' if current_index < 1 current_index - 1 end # determines the type of break and modifies self appropriately \ No newline at end of file