class Travis::Conditions::V0::Parser

Constants

FUNCS
PRESENCE

Public Instance Methods

parse(str) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 10
def parse(str)
  parser.parse(str)
end

Private Instance Methods

define_parser(keywords) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 20
  def define_parser(keywords)
    Class.new(Parslet::Parser) do
      root :expr_or

      rule :expr_or  do
        spaced(expr_and.as(:lft), op_or, expr_or.as(:rgt)).as(:or) | expr_and
      end

      rule :expr_and do
        spaced(expr_inner.as(:lft), op_and, expr_and.as(:rgt)).as(:and) | expr_inner
      end

      rule :expr_inner do
        lnot(parens(expr_or) | expr_incl | expr_is | expr_regex | expr_cmp)
      end

      rule :expr_cmp do
        spaced(lhs.as(:lft), op_cmp.as(:op), value.as(:rgt)).as(:cmp)
      end

      rule :expr_regex do
        spaced(lhs.as(:lft), op_regex.as(:op), regex.as(:rgt)).as(:cmp)
      end

      rule :expr_incl do
        spaced(lhs.as(:lft), op_incl, parens(list).as(:rgt)).as(:incl)
      end

      rule :expr_is do
        spaced(lhs.as(:lft), op_is, presence.as(:rgt)).as(:is)
      end

      def lnot(node)
        (stri('not').maybe >> space >> node.as(:rgt)).as(:not) | node
      end

      rule :list do
        (value >> (ts(str(',')) >> value).repeat)
      end

      rule :lhs do
        func | keyword
      end

      rule :keyword do
        stris(*keywords)
      end

      rule :func do
        (stris(*FUNCS).as(:name) >> parens(word)).as(:func)
      end

      rule :word do
        match('[\w_\-]').repeat(1).as(:str)
      end

      rule :regex do
        quoted('/') | match('[\S]').repeat(1).as(:str)
      end

      rule :value do
        unquoted | quoted('"') | quoted("'")
      end

      rule :unquoted do
        match('[^\s\"\'\(\),]').repeat(1).as(:str)
      end

      def quoted(chr)
        str(chr) >> match("[^#{chr}]").repeat.as(:str) >> str(chr)
      end

      rule :presence do
        (stris(*PRESENCE)).as(:str)
      end

      rule :op_is do
        stri('is')
      end

      rule :op_cmp do
        str('=') | str('!=')
      end

      rule :op_regex do
        str('=~') | str('!~')
      end

      rule :op_incl do
        stri('in')
      end

      rule :op_or do
        stri('or')
      end

      rule :op_and do
        stri('and')
      end

      rule :space do
        match('\s').repeat(1)
      end

      rule :space? do
        space.maybe
      end

      def stris(*strs)
        strs.inject(stri(strs.shift)) { |node, str| node | stri(str) }
      end

      def stri(str)
        str(str.to_s) | str(str.to_s.upcase)
      end

      def parens?(node)
        spaced?(str('(').maybe, node, str(')').maybe)
      end

      def parens(node)
        spaced?(str('('), node, str(')'))
      end

      def spaced?(*nodes)
        nodes.zip([space?] * nodes.size).flatten[0..-2].inject(&:>>)
      end

      def spaced(*nodes)
        # nodes.zip([space] * nodes.size).flatten[0..-2].inject(&:>>)
        nodes.zip([space?] * nodes.size).flatten[0..-2].inject(&:>>)
      end

      def ls(node)
        space? >> node
      end

      def ts(node)
        node >> space?
      end
    end
end
lnot(node) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 52
def lnot(node)
  (stri('not').maybe >> space >> node.as(:rgt)).as(:not) | node
end
ls(node) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 153
def ls(node)
  space? >> node
end
parens(node) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 140
def parens(node)
  spaced?(str('('), node, str(')'))
end
parens?(node) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 136
def parens?(node)
  spaced?(str('(').maybe, node, str(')').maybe)
end
parser() click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 16
def parser
  @parser ||= define_parser(opts[:keys]).new
end
quoted(chr) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 88
def quoted(chr)
  str(chr) >> match("[^#{chr}]").repeat.as(:str) >> str(chr)
end
spaced(*nodes) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 148
def spaced(*nodes)
  # nodes.zip([space] * nodes.size).flatten[0..-2].inject(&:>>)
  nodes.zip([space?] * nodes.size).flatten[0..-2].inject(&:>>)
end
spaced?(*nodes) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 144
def spaced?(*nodes)
  nodes.zip([space?] * nodes.size).flatten[0..-2].inject(&:>>)
end
stri(str) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 132
def stri(str)
  str(str.to_s) | str(str.to_s.upcase)
end
stris(*strs) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 128
def stris(*strs)
  strs.inject(stri(strs.shift)) { |node, str| node | stri(str) }
end
ts(node) click to toggle source
# File lib/travis/conditions/v0/parser.rb, line 157
def ts(node)
  node >> space?
end