Class: Tap::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/tap/parser.rb

Overview

A parser for workflows defined on the command line.

Constant Summary collapse

ESCAPE_BEGIN =

The escape begin argument

"-."
ESCAPE_END =

The escape end argument

".-"
END_FLAG =

The parser end flag

"---"
BREAK =

Matches any breaking arg. Examples:

--
--:
--[1,2][3]
--@
--/var
--.

After the match:

$1:: The string after the break, or nil
     (ex: '--' => nil, '--:' => ':', '--[1,2][3,4]' => '[1,2][3,4]')
/\A--(?:\z|([\:\[\/\.@].*?)\z)/
NODE_BREAK =

The node modifier.

nil
JOIN_BREAK =

The join modifier.

"."
SEQUENCE =

Matches a sequence break. After the match:

$1:: The modifier string, or nil
     (ex: ':' => nil, ':i' => 'i')
/\A:(.+)?\z/
JOIN =

Matches a generic join break. After the match:

$1:: The inputs string.
     (ex: '[1,2,3][4,5,6]' => '1,2,3')
$2:: The outputs string.
     (ex: '[1,2,3][4,5,6]' => '4,5,6')
$3:: The modifier string, or nil
     (ex: '[][]is' => 'is')
/\A\[(.*?)\]\[(.*?)\](.+)?\z/
JOIN_MODIFIER =

Matches a join modifier. After the match:

$1:: The modifier flag string.
     (ex: 'is.sync' => 'is')
$2:: The class string.
     (ex: 'is.sync' => 'sync')
/\A([A-z]*)(?:\.(.*))?\z/
ENQUE =

Matches an enque modifier. After the match:

$1:: The modifier string, or nil
     (ex: '@var' => 'var')
/\A@(.+)?\z/
SIGNAL =

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')
/\A\/(?:(.*)\/)?(.*)\z/
OBJECT =

Splits a signal into an object string and a signal string. If OBJECT doesn’t match, then the string can be considered a signal, and the object is nil. After a match:

$1:: The object string
     (ex: 'obj/sig' => 'obj')
$2:: The signal string
     (ex: 'obj/sig' => 'sig')
/\A(.*)\/(.*)\z/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(specs = []) ⇒ Parser

Returns a new instance of Parser.



111
112
113
# File 'lib/tap/parser.rb', line 111

def initialize(specs=[])
  @specs = specs
end

Instance Attribute Details

#specsObject (readonly)

Returns the value of attribute specs.



109
110
111
# File 'lib/tap/parser.rb', line 109

def specs
  @specs
end

Class Method Details

.parse(argv = ARGV) ⇒ Object



8
9
10
# File 'lib/tap/parser.rb', line 8

def parse(argv=ARGV)
  parse!(argv.dup)
end

.parse!(argv = ARGV) ⇒ Object



12
13
14
15
16
17
18
19
20
21
# File 'lib/tap/parser.rb', line 12

def parse!(argv=ARGV)
  argv = Shellwords.shellwords(argv) if argv.kind_of?(String)
  sig, obj = argv.shift, nil
  
  if sig =~ OBJECT
    obj, sig = $1, $2
  end
  
  [obj, sig, argv]
end

Instance Method Details

#parse(argv) ⇒ Object



115
116
117
118
# File 'lib/tap/parser.rb', line 115

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

#parse!(argv) ⇒ Object

Same as parse, but removes parsed args from argv.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/tap/parser.rb', line 121

def parse!(argv)
  argv = Shellwords.shellwords(argv) if argv.kind_of?(String)
  return argv if argv.empty?
  
  unless argv[0] =~ BREAK
    argv.unshift("--") 
  end
  
  @current_type = nil
  @current_index = -1
  @current = nil
  escape = false
  
  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 << arg
      end
      next
    end
  
    # handle breaks and parser flags
    case arg
    when BREAK
      begin
        @current_type = nil
        @current_index += 1
        @current = parse_break($1)
      rescue
        raise "invalid break: #{arg} (#{$!.message})"
      end
      next

    when ESCAPE_BEGIN
      escape = true
      next

    when END_FLAG
      break
    
    end if arg[0] == ?-
  
    # add all remaining args to the current argv
    current << arg
  end
  
  @current_type = nil
  @current_index = nil
  @current = nil
  
  argv
end