Class Tap::Parser
In: lib/tap/parser.rb
Parent: Object

A parser for workflows defined on the command line.

Methods

build_to   new   parse   parse!  

Constants

BREAK = /\A-(?!-?\w)/   Regexp to match any dash-nonword break
OPTION = /\A--?\w/   Matches a traditional dash-letter or double-dash-word option
SET = '-'   Delmits and sets the next object
ENQUE = '--'   Sets and enques the next object
EXECUTE = '-!'   Sets and executes the next object
SIGENQ = '-@'   Break to enque an existing object
JOIN = /\A-:(.+)?\z/   Matches a sequence break. After the match:
  $1:: The modifier string, or nil
       (ex: ':' => nil, ':i' => 'i')
MODIFIER = /\A([A-z]*)(?:\.(.*))?\z/   Matches a join modifier. After the match:
  $1:: The modifier flag string.
       (ex: 'is.sync' => 'is')
  $2:: The class string.
       (ex: 'is.sync' => 'sync')
SIGNAL = /\A-(-)?\/(.*)\z/   Matches a signal break. After the match:
  $1:: The object string, or nil
       (ex: 'obj/sig' => 'obj')
  $2:: The signal string
       (ex: 'obj/sig' => 'sig')
ESCAPE_BEGIN = "-."   The escape begin argument
ESCAPE_END = ".-"   The escape end argument
END_FLAG = "---"   The parser end flag

Attributes

specs  [R] 

Public Class methods

[Source]

    # File lib/tap/parser.rb, line 63
63:     def initialize
64:       @specs = []
65:     end

Public Instance methods

[Source]

     # File lib/tap/parser.rb, line 132
132:     def build_to(app)
133:       blocks = Hash.new do |hash, type|
134:         hash[type] = block(type, app)
135:       end
136:       
137:       app.scope do
138:         specs.each do |(spec, type)|
139:           app.call(spec, &blocks[type])
140:         end
141:       end
142:       
143:       self
144:     end

[Source]

    # File lib/tap/parser.rb, line 67
67:     def parse(argv)
68:       parse!(argv.dup)
69:     end

Same as parse, but removes parsed args from argv.

[Source]

     # File lib/tap/parser.rb, line 72
 72:     def parse!(argv)
 73:       return argv if argv.empty?
 74:       
 75:       @current_index = -1
 76:       current = argv[0] =~ BREAK ? nil : spec(:enq)
 77:       escape = false
 78:       
 79:       while !argv.empty?
 80:         arg = argv.shift
 81: 
 82:         # collect escaped arguments until an escape-end
 83:         if escape
 84:           if arg == ESCAPE_END
 85:             escape = false
 86:           else
 87:             current << arg
 88:           end
 89:           next
 90:         end
 91:         
 92:         # collect non-option/break arguments
 93:         unless arg[0] == ?-
 94:           current << arg
 95:           next
 96:         end
 97:         
 98:         begin
 99:           
100:           # parse option/break arguments
101:           case arg
102:           when SET
103:             current = spec(:set)
104:           when ENQUE
105:             current = spec(:enq)
106:           when EXECUTE
107:             current = spec(:exe)
108:           when OPTION
109:             current << arg
110:           when JOIN
111:             current = parse_join($1)
112:           when SIGENQ
113:             current = parse_signal(nil, 'enq')
114:           when SIGNAL
115:             current = parse_signal($1, $2)
116:           when ESCAPE_BEGIN
117:             escape = true
118:           when END_FLAG
119:             break
120:           else
121:             raise "unknown"
122:           end
123:           
124:         rescue
125:           raise "invalid break: #{arg} (#{$!.message})"
126:         end
127:       end
128:       
129:       argv
130:     end

[Validate]