# class MCollective::Matcher::Parser

### Attributes

execution_stack[R]
scanner[R]

### Public Class Methods

new(args) click to toggle source

    # 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

### Public Instance Methods

exit_with_paren_errors() click to toggle source

    # 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_errors() click to toggle source

    # 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_errors() click to toggle source

Exit and highlight any malformed tokens

    # 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

parse() click to toggle source

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

    # 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