0.02
No release in over 3 years
Low commit activity in last 3 years
Sexpistol is an easy-to-use S-Expression parser for Ruby. It is fast and has no dependencies.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

Ruby Style Guide Actions Status Maintainability Test Coverage Gem Version

Sexpistol

Sexpistol is a very fast and easy-to-use library for parsing S-Expressions in Ruby. Sexpistol takes an S-Expression in string form and turns it into a native Ruby data structure made up of nested sets of arrays.

Example:

(define test (lambda () (
  (print "Hello world!\n")
  (print 1)
  (print 9.01)
  (print 2.0e10)
  (print (+ 10 12 13))
)))

would be parsed by Sexpistol like so:

[:define, :test, [:lambda, [], [
  [:print, "Hello world!\n"],
  [:print, 1],
  [:print, 9.01],
  [:print, 2.0e10],
  [:print, [:+, 10, 12, 13]]
]]]

Usage:

# Parse an s-expression
ast = Sexpistol.parse("(string (to (parse)))")
#=> [:string, [:to, [:parse]]]

# Change the representation
ast[1][0] = :is
ast[1][1][0] = :parsed
#=> [:string, [:is, [:parsed]]]

# Turn the array structure back into an S-Expression
Sexpistol.to_sexp(ast)
#=> "(string (is (parsed)))"

API:

Sexpistol.parse(string, parse_ruby_keyword_literals: false)
# Parse an s-expression given as a string. Optionally convert 
# ruby keyword literals to their native Ruby equivalents.

Sexpistol.to_sexp(structure, scheme_compatability: false)
# Output a nested set of arrays as an s-expression. Optionally 
# output `true, false, nil` as their Scheme literal equivalents.

Type mappings:

Sexpistol supports all of the standard datatypes and converts them directly to their Ruby equivalents:

  • Lists (a b c) -> [:a, :b, :c]
  • Integers (1 2 3) -> [1, 2, 3]
  • Floats (1.0 42.9 3e6 1.2e2) -> [1.0, 42.9, 3e6, 1.2e2]
  • Strings ("\t"Hello world!"\n") -> ["\t\"Hello world!\"\n"]
  • Symbols (symbol symbol? + - a+ e$, etc...) -> [:symbol, :symbol?, :+, :-, :a+, :'e$', :'etc...']

Sexpistol also supports mapping the Ruby keyword literals (nil, true, false) to their native Ruby types, although this is disabled by default for compatibility. To enable it use parse_ruby_keyword_literals: true, eg:

Sexpistol.parse("(nil false true)")
#=> [:nil, :false, :true]

Sexpistol.parse("(nil false true)", parse_ruby_keyword_literals: true)
#=> [nil, false, true]

Scheme compatibility:

Sexpistol strives to be compatible with Scheme-style S-Expressions. Sexpistol can generate Scheme compatible external representations when the 'scheme_compatability' option is set to true:

Sexpistol.to_sexp([true, false, nil])
#=> "(true false nil)"

Sexpistol.to_sexp([true, false, nil], scheme_compatability: true)
#=> "(#t #f ())"

Installation:

Add Sexpistol to your gemfile:

gem 'sexpistol', '~>0.1.2'

And then execute:

bundle install

Or install it manually by entering the following at your command line:

gem install sexpistol

Contributing:

Contributions are always welcome! Please create a pull request that clearly outlines the work you've done. Make sure your changes include updating or adding relevant tests, and use Rubocop to make sure your additions adhere to the same style as the rest of the project!

Author & Credits:

Author: Aaron Gough Contributors: Shane Hanna

Copyright © 2022 Aaron Gough, released under the MIT license