SexpPath

SexpPath is a ruby DSL for pattern matching S-Expressions. Think of it as XPath or Regular Expressions for Ruby code, and you’re most of the way there.

Here is an example of an S-Expression in Ruby:

pets = s(:pets, 
  s(:cat, :fluffy, s(:color, :white)),
  s(:cat, :snuggles, s(:color, :grey)),
  s(:fish, :bubbles, s(:drinks, :water)
)

This query extracts all the cats from our example:

pattern = Q?{ s(:cat, atom, _ ) }
cats = pets.search pattern

The SexpPath query above looks for expressions that start with the symbol :cat. The atom part says that we will match any symbol, so in the example above it would match both :fluffy and :snuggles. The underscore at the end will match anything at all, in this case, the S-Expression for color.

You can also match nested expressions with SexpPath:

pattern = Q?{ s(:cat, atom, s(:color, grey) ) }
grey_cats = pets.search pattern

SexpPath also has a notion of named matches. This query will place each cat’s name in the query result:

pattern = Q?{ s(:cat, atom % 'name', _ ) }
cat_matches = pets.search pattern
cat_names = cat_matches.map{|match| match['name']}

The % operator tells SexpPath where to stash a matching value.

Here is an example of using SexpPath with Ryan Davis’ excellent ParseTree library to extract all the methods in a given file:

# read in a ruby file
code = File.read('pony_factory.rb')
# parse the file with ParseTree
sexp = Sexp.from_array(ParseTree.new.parse_tree_for_string(code))
# create a SexpPath to find all the methods
pattern = Q?{ s(:defn, atom % 'name', _ ) }
# print all the methods in the ruby file
sexp.search(pattern).each do |match|
  puts match['name']
end

Now you’re doing static analysis on Ruby code! To learn more take a look at the Readme on GitHub, or skim over some of the examples.

If you have any suggestions or critiques of the code, API, etc. I would love to hear from you so comment, fork, or open an issue on GitHub.

About these ads

4 Comments

Filed under ruby, ruby_diff, Uncategorized

4 responses to “SexpPath

  1. Really interesting, Erlang style. Thanks for sharing!

  2. Pingback: SexpPath: A Ruby DSL for Pattern Matching S-Expressions

  3. Pingback: SexpPath: A Ruby DSL for Pattern Matching S-Expressions | Webs Developer

  4. Pingback: SexpPath - Uma DSL Ruby para pattern matching de S-Expressions

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s