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

BREAK =

Regexp to match any dash-nonword break

/\A-(?!-?\w)/
OPTION =

Matches a traditional dash-letter or double-dash-word option

/\A--?\w/
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 =

Matches a sequence break. After the match:

$1:: The modifier string, or nil
     (ex: ':' => nil, ':i' => 'i')
/\A-:(.+)?\z/
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/
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/
ESCAPE_BEGIN =

The escape begin argument

"-."
ESCAPE_END =

The escape end argument

".-"
END_FLAG =

The parser end flag

"---"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



63
64
65
# File 'lib/tap/parser.rb', line 63

def initialize
  @specs = []
end

Instance Attribute Details

#specsObject (readonly)

Returns the value of attribute specs.



61
62
63
# File 'lib/tap/parser.rb', line 61

def specs
  @specs
end

Instance Method Details

#build_to(app) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/tap/parser.rb', line 132

def build_to(app)
  blocks = Hash.new do |hash, type|
    hash[type] = block(type, app)
  end
  
  app.scope do
    specs.each do |(spec, type)|
      app.call(spec, &blocks[type])
    end
  end
  
  self
end

#parse(argv) ⇒ Object



67
68
69
# File 'lib/tap/parser.rb', line 67

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

#parse!(argv) ⇒ Object

Same as parse, but removes parsed args from argv.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/tap/parser.rb', line 72

def parse!(argv)
  return argv if argv.empty?
  
  @current_index = -1
  current = argv[0] =~ BREAK ? nil : spec(:enq)
  escape = false
  
  while !argv.empty?
    arg = argv.shift

    # collect escaped arguments until an escape-end
    if escape
      if arg == ESCAPE_END
        escape = false
      else
        current << arg
      end
      next
    end
    
    # collect non-option/break arguments
    unless arg[0] == ?-
      current << arg
      next
    end
    
    begin
      
      # parse option/break arguments
      case arg
      when SET
        current = spec(:set)
      when ENQUE
        current = spec(:enq)
      when EXECUTE
        current = spec(:exe)
      when OPTION
        current << arg
      when JOIN
        current = parse_join($1)
      when SIGENQ
        current = parse_signal(nil, 'enq')
      when SIGNAL
        current = parse_signal($1, $2)
      when ESCAPE_BEGIN
        escape = true
      when END_FLAG
        break
      else
        raise "unknown"
      end
      
    rescue
      raise "invalid break: #{arg} (#{$!.message})"
    end
  end
  
  argv
end