Class: SexpPath::SexpQueryBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/sexp_path/sexp_query_builder.rb

Overview

The SexpQueryBuilder is the simplest way to build SexpPath queries.

Typically, one access the SexpQueryBuilder through the helper method Q? which accepts a block, and will return a SexpPath matcher.

For example here is a SexpPath query that looks for s(:a):

query = Q?{ s(:a) }

A more interesting query might look for classes with names starting in Test:

query = Q?{ s(:class, m(/^Test\w+/ % 'name', _, _)) }

This makes use of a SexpPath::Matcher::Pattern, two SexpPath::Matcher::Wild matchers and SexpPath::Traverse#capture_as for capturing the name to a variable ‘name’.

For more examples, see the various SexpQueryBuilder class methods, the examples, and the tests supplied with SexpPath.

Direct Known Subclasses

RubyQueryBuilder

Class Method Summary collapse

Class Method Details

.all(*args) ⇒ Object

Matches only when all sub expressions match

example:

s(:a) / Q?{ all(s(:a), s(:b)) } #=> []
s(:a,:b) / Q?{ t(:a), include(:b)) } #=> [s(:a,:b)]


115
116
117
# File 'lib/sexp_path/sexp_query_builder.rb', line 115

def all(*args)
  SexpPath::Matcher::All.new(*args)
end

.any(*args) ⇒ Object

Matches when any of the sub expressions match.

example:

s(:a) / Q?{ any(s(:a), s(:b)) } #=> [s(:a)]
s(:a) / Q?{ any(s(:b), s(:c)) } #=> []


105
106
107
# File 'lib/sexp_path/sexp_query_builder.rb', line 105

def any(*args)
  SexpPath::Matcher::Any.new(*args)
end

.atomObject

Matches any atom.

example:

s(:a) / Q?{ s(atom) }        #=> [s(:a)]
s(:a, s(:b)) / Q?{ s(atom) } #=> [s(:b)]


95
96
97
# File 'lib/sexp_path/sexp_query_builder.rb', line 95

def atom
  SexpPath::Matcher::Atom.new
end

.child(child) ⇒ Object

Matches anything that has a child matching the sub expression

example:

s(s(s(s(s(:a))))) / Q?{ child(s(:a)) } #=> [s(s(s(s(s(:a)))))]


134
135
136
# File 'lib/sexp_path/sexp_query_builder.rb', line 134

def child(child)
  SexpPath::Matcher::Child.new(child)
end

.do(&block) ⇒ Object

This is the longhand method for create a SexpPath query, normally one would use Q?{ … }, however it is also possible to do:

SexpPath::SexpQueryBuilder.do{ s() }


32
33
34
# File 'lib/sexp_path/sexp_query_builder.rb', line 32

def do(&block)
  instance_eval(&block)
end

.include(child) ⇒ Object

Matches an expression or any expression that includes the child.

example:

s(:a, :b)   / Q?{ include(:b) }
s(s(s(:a))) / Q?{ include(:a) }


85
86
87
# File 'lib/sexp_path/sexp_query_builder.rb', line 85

def include(child)
  SexpPath::Matcher::Include.new(child)
end

.is_not(arg) ⇒ Object

Matches when sub expression does not match, see SexpPath::Matcher::Base#-@

example:

s(:a) / Q?{ is_not(s(:b)) } #=> [s(:a)]
s(:a) / Q?{ s(is_not :a) } #=> []


125
126
127
# File 'lib/sexp_path/sexp_query_builder.rb', line 125

def is_not(arg)
  SexpPath::Matcher::Not.new(arg)
end

.m(*patterns) ⇒ Object

Matches any atom who’s string representation matches the patterns passed in.

example:

s(:a) / Q?{ m('a') } #=> [s(:a)]
s(:a) / Q?{ m(/\w/,/\d/) } #=> [s(:a)]
s(:tests, s(s(:test_a), s(:test_b))) / Q?{ m(/test_\w/) } #=> [s(:test_a), s(:test_b)]


154
155
156
157
158
# File 'lib/sexp_path/sexp_query_builder.rb', line 154

def m(* patterns)
  patterns = patterns.map{|p| p.is_a?(Regexp) ? p : Regexp.new("\\A"+Regexp.escape(p.to_s)+"\\Z")}
  regexp = Regexp.union(*patterns)
  SexpPath::Matcher::Pattern.new(regexp)
end

.remainingObject Also known as: ___

Matches all remaining input. This is a special case pattern and has a few odd characteristics.

  • You cannot capture with remaining

  • If remaining comes before any other matchers, they will be ignored.

example:

s(:a) / Q?{ s(:a, ___ ) }    #=> [s(:a)]
s(:a, :b, :c) / Q?{ s(:a, ___ ) } #=> [s(:a, :b, :c)]

Can also be called with remaining

s(:a) / Q?{ s(:a, remaining) } #=> [s(:a)]


74
75
76
# File 'lib/sexp_path/sexp_query_builder.rb', line 74

def remaining()
  SexpPath::Matcher::Remaining.new
end

.s(*args) ⇒ Object

Matches an S-Expression.

example

s(:a) / Q?{ s(:a) }       #=> [s(:a)]
s(:a) / Q?{ s() }         #=> []
s(:a, s(:b) / Q?{ s(:b) } #=> [s(:b)]


43
44
45
# File 'lib/sexp_path/sexp_query_builder.rb', line 43

def s(*args)
  SexpPath::Matcher::Base.new(*args)
end

.t(name) ⇒ Object

Matches anything having the same sexp_type, which is the first value in a Sexp.

example:

s(:a, :b) / Q?{ t(:a) } #=> [s(:a, :b)]
s(:a, :b) / Q?{ t(:b) } #=> []
s(:a, s(:b, :c)) / Q?{ t(:b) } #=> [s(:b, :c)]


144
145
146
# File 'lib/sexp_path/sexp_query_builder.rb', line 144

def t(name)
  SexpPath::Matcher::Type.new(name)
end

.wildObject Also known as: _

Matches any single item.

example:

s(:a) / Q?{ _ }        #=> [s(:a)]
s(:a, s(s(:b))) / Q?{ s(_) } #=> [s(s(:b))]

Can also be called with wild

s(:a) / Q?{ wild }     #=> [s(:a)]


56
57
58
# File 'lib/sexp_path/sexp_query_builder.rb', line 56

def wild()
  SexpPath::Matcher::Wild.new
end