SexpPath
June 22, 2009
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.
Entry Filed under: ruby, ruby_diff. Tags: ruby, sexp, sexp_path.
4 Comments Add your own
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed
1. Luca Guidi | June 22, 2009 at 11:36 pm
Really interesting, Erlang style. Thanks for sharing!
2. SexpPath: A Ruby DSL for Pattern Matching S-Expressions | July 14, 2009 at 8:48 am
[...] vs. Data", it only makes sense that you should be able process over code as you would a string. Sexp Path is a code processing tool that allows you to search over and process Ruby code in the form of [...]
3. SexpPath: A Ruby DSL for Pattern Matching S-Expressions | Webs Developer | July 14, 2009 at 9:04 am
[...] Data”, it only makes sense that you should be able process over code as you would a string. Sexp Path is a code processing tool that allows you to search over and process Ruby code in the form of [...]
4. SexpPath - Uma DSL Ruby para pattern matching de S-Expressions | August 13, 2009 at 5:04 am
[...] a fazer sentido sermos capazes de processar código da mesma maneira que processamos uma string. Sexp Path é uma ferramenta de processamento de código que nos permite procurar e processar código Ruby na [...]