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 = .("(string (to (parse)))") #=> [:string, [:to, [:parse]]] # Change the representation ast = :is ast = :parsed #=> [:string, [:is, [:parsed]]] # Turn the array structure back into an S-Expression .(ast) #=> "(string (is (parsed)))"
.(string, parse_ruby_keyword_literals: false) # Parse an s-expression given as a string. Optionally convert # ruby keyword literals to their native Ruby equivalents. .(structure, scheme_compatability: false) # Output a nested set of arrays as an s-expression. Optionally # output `true, false, nil` as their Scheme literal equivalents. .convert_ruby_keyword_literals(data) # Recursively maps over a nested array structure and converts # any instances of :nil, :true, :false to their native Ruby equivalents. .convert_scheme_literals(data) # Converts Ruby literals to their equivalent Scheme literals .recursive_map(data, &block) # Recursively map over a nested set of arrays, applying the block # to each item and returning the result.
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") ->
- Symbols (symbol symbol? + - a+ e$, etc...) ->
[:symbol, :symbol?, :+, :-, :a+, :'e$', :'etc...']
Sexpistol also supports mapping the Ruby keyword literals (
false) to their native Ruby types, although this is disabled by default for compatibility. To enable it use
parse_ruby_keyword_literals: true, eg:
.("(nil false true)") #=> [:nil, :false, :true] .("(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:
.([true, false, nil]) #=> "(true false nil)" .([true, false, nil], scheme_compatability: true) #=> "(#t #f ())"
Add Sexpistol to your gemfile:
gem 'sexpistol', '~>0.10.0'
And then execute:
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 & Credits:
Copyright © 2022 Aaron Gough, released under the MIT license