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.
(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]]
]]]
# 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)))"
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.
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]
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 ())"
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
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: Aaron Gough Contributors: Shane Hanna
Copyright © 2022 Aaron Gough, released under the MIT license