Class: MCollective::Matcher::Parser

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Parser

Returns a new instance of Parser.



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/mcollective/matcher/parser.rb', line 6

def initialize(args)
  @scanner = Scanner.new(args)
  @execution_stack = []
  @parse_errors = []
  @token_errors = []
  @paren_errors = []
  parse
  exit_with_token_errors if @token_errors.size > 0
  exit_with_parse_errors if @parse_errors.size > 0
  exit_with_paren_errors if @paren_errors.size > 0
end

Instance Attribute Details

#execution_stackObject (readonly)

Returns the value of attribute execution_stack.



4
5
6
# File 'lib/mcollective/matcher/parser.rb', line 4

def execution_stack
  @execution_stack
end

#scannerObject (readonly)

Returns the value of attribute scanner.



4
5
6
# File 'lib/mcollective/matcher/parser.rb', line 4

def scanner
  @scanner
end

Instance Method Details

#exit_with_paren_errorsObject



37
38
39
40
41
42
# File 'lib/mcollective/matcher/parser.rb', line 37

def exit_with_paren_errors
  @paren_errors.each do |i|
    @scanner.arguments[i] = Util.colorize(:red, @scanner.arguments[i])
  end
  raise "Missing parenthesis found while parsing -S input #{@scanner.arguments.join}"
end

#exit_with_parse_errorsObject



28
29
30
31
32
33
34
35
# File 'lib/mcollective/matcher/parser.rb', line 28

def exit_with_parse_errors
  @parse_errors.each do |error_range|
    (error_range[0]..error_range[1]).each do |i|
      @scanner.arguments[i] = Util.colorize(:red, @scanner.arguments[i])
    end
  end
  raise "Parse errors found while parsing -S input #{ @scanner.arguments.join}"
end

#exit_with_token_errorsObject

Exit and highlight any malformed tokens



19
20
21
22
23
24
25
26
# File 'lib/mcollective/matcher/parser.rb', line 19

def exit_with_token_errors
  @token_errors.each do |error_range|
    (error_range[0]..error_range[1]).each do |i|
      @scanner.arguments[i] = Util.colorize(:red, @scanner.arguments[i])
    end
  end
  raise "Malformed token(s) found while parsing -S input #{@scanner.arguments.join}"
end

#parseObject

Parse the input string, one token at a time a contruct the call stack



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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
# File 'lib/mcollective/matcher/parser.rb', line 45

def parse
  pre_index = @scanner.token_index
  p_token,p_token_value = nil
  c_token,c_token_value = @scanner.get_token
  parenth = 0

  while (c_token != nil)
    @scanner.token_index += 1
    n_token, n_token_value = @scanner.get_token

    unless n_token == " "
      case c_token
      when "bad_token"
        @token_errors << c_token_value

      when "and"
        unless (n_token =~ /not|fstatement|statement|\(/) || (scanner.token_index == scanner.arguments.size) && !(n_token == nil)
          @parse_errors << [pre_index, scanner.token_index]
        end

        if p_token == nil
          @parse_errors << [pre_index - c_token.size, scanner.token_index]
        elsif (p_token == "and" || p_token == "or")
          @parse_errors << [pre_index - 1 - p_token.size, pre_index - 1]
        end

      when "or"
        unless (n_token =~ /not|fstatement|statement|\(/) || (scanner.token_index == scanner.arguments.size) && !(n_token == nil)
          @parse_errors << [pre_index, scanner.token_index]
        end

        if p_token == nil
          @parse_errors << [pre_index - c_token.size, scanner.token_index]
        elsif (p_token == "and" || p_token == "or")
          @parse_errors << [pre_index - 1 - p_token.size, pre_index - 1]
        end

      when "not"
        unless n_token =~ /fstatement|statement|\(|not/ && !(n_token == nil)
          @parse_errors << [pre_index, scanner.token_index]
        end

      when "statement","fstatement"
        unless n_token =~ /and|or|\)/
          unless scanner.token_index == scanner.arguments.size
            @parse_errors << [pre_index, scanner.token_index]
          end
        end

      when ")"
        unless (n_token =~ /|and|or|not|\(/)
          unless(scanner.token_index == scanner.arguments.size)
            @parse_errors << [pre_index, scanner.token_index]
          end
        end
        unless @paren_errors.empty?
          @paren_errors.pop
        else
          @paren_errors.push((n_token.nil?) ? scanner.token_index - 1: scanner.token_index - n_token_value.size)
        end

      when "("
        unless n_token =~ /fstatement|statement|not|\(/
          @parse_errors << [pre_index, scanner.token_index]
        end
        @paren_errors.push((n_token.nil?) ? scanner.token_index - 1: scanner.token_index - n_token_value.size)

      else
        @parse_errors << [pre_index, scanner.token_index]
      end

      unless n_token == " " ||c_token == "bad_token"
        @execution_stack << {c_token => c_token_value}
      end

      p_token, p_token_value = c_token, c_token_value
      c_token, c_token_value = n_token, n_token_value
    end
    pre_index = @scanner.token_index
  end
end