Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dryruby/sxp.rb

A universal S-expression parser for Ruby.
https://github.com/dryruby/sxp.rb

parser ruby rubygems sxp

Last synced: 3 months ago
JSON representation

A universal S-expression parser for Ruby.

Awesome Lists containing this project

README

        

# SXP.rb: S-Expressions for Ruby

This is a Ruby implementation of a universal [S-expression][] parser.

[![Gem Version](https://badge.fury.io/rb/sxp.svg)](https:/badge.fury.io/rb/sxp)
[![Build Status](https://github.com/dryruby/sxp.rb/workflows/CI/badge.svg?branch=develop)](https://github.com/dryruby/sxp.rb/actions?query=workflow%3ACI)
[![Coverage Status](https://coveralls.io/repos/dryruby/sxp.rb/badge.svg?branch=develop)](https://coveralls.io/r/dryruby/sxp.rb?branch=develop)

## Features

* Parses S-expressions in universal, [Scheme][], [Common Lisp][], or
[SPARQL][] syntax.
* Adds a `#to_sxp` method to Ruby objects.
* Compatible with Ruby >= 3.0, Rubinius >= 3.0, and JRuby 9+.

## Basic syntax

S-Expressions derive from LISP, and include some basic datatypes common to all variants:


Pairs

Of the form (2 . 3)

Lists

Of the form (1 (2 3))

Symbols

Of the form with-hyphen ?@!$ a\ symbol\ with\ spaces

Strings

Of the form "Hello, world!" or 'Hello, world!'

Strings may include the following special characters:


  • \b — Backspace


  • \f — Form Feed


  • \n — New Line


  • \r — Carriage Return


  • \t — Horizontal Tab


  • \uxxxx — 2-byte Unicode character escape


  • \Uxxxxxxxx — 4-byte Unicode character escape


  • \" — Double-quote character


  • \' — Single-quote character


  • \\ — Backspace


Additionally, any other character may follow \, representing the character itself.

Characters

Of the form ...

Integers

Of the form -9876543210

Floating-point numbers

Of the form -0.0 6.28318 6.022e23

Rationals

Of the form 1/3

Additionally, variation-specific formats support additional datatypes:

### Scheme

In addition to the standard datatypes, the Scheme dialect supports the following:


Lists

In addition to ( ... ), a square bracket pair may be used for reading lists of the form [ ... ].

Comments

A comment starts with ; and continues to the end of the line.

Sharp character sequences

Such as #t, #n, and #xXXX.



  • #n — Null


  • #f — False


  • #t — True


  • #bBBB — Binary number


  • #oOOO — Octal number


  • #dDDD — Decimal number


  • #xXXX — Hexadecimal number


  • #\C — A single Unicode character


  • #\space — A space character


  • #\newline — A newline character


  • #; — Skipped character


  • #! — Skipped to end of line



### Common Lisp

In addition to the standard datatypes, the Common Lisp dialect supports the following:


Comments

A comment starts with ; and continues to the end of the line.

Symbols

In addition to base symbols, any character sequence delimited by | is treated as a symbol.

Sharp character sequences

Such as #t, #n, and #xXXX.



  • #bBBB — Binary number


  • #oOOO — Octal number


  • #xXXX — Hexadecimal number


  • #C — A single Unicode character


  • #\newline — A newline character


  • #\space — A space character


  • #\backspace — A backspace character


  • #\tab — A tab character


  • #\linefeed — A linefeed character


  • #\page — A page feed character


  • #\return — A carriage return character


  • #\rubout — A rubout character


  • #'function — A function definition



### SPARQL/RDF

In addition to the standard datatypes, the SPARQL dialect supports the following:


Lists

In addition to ( ... ), a square bracket pair may be used for reading lists of the form [ ... ].

Comments

A comment starts with # or ; and continues to the end of the line.

Literals

Strings are interpreted as an RDF Literal with datatype xsd:string. It can be followed by @lang to create a language-tagged string, or ^^IRI to create a datatyped-literal. Examples:

  • "a plain literal"

  • 'another plain literal'

  • "a literal with a language"@en

  • "a typed literal"^^<http://example/>

  • "a typed literal with a PNAME"^^xsd:string



IRIs

An IRI is formed as in SPARQL, either enclosed by <...>, or having the form of a PNAME. If a base iri is defined in a containing base expression, IRIs using the <...> are resolved against that base iri. If the PNAME form is used, the prefix must be defined in a containing prefix expression. Examples:

  • <http://example/foo>

  • (base &lthttp://example.com> <foo>)

  • (prefix ((foo: <http://example.com/>)) foo:bar)


  • a # synonym for rdf:type



Blank Nodes

An blank node is formed as in SPARQL. Examples:

  • _:

  • _:id



Variables

A SPARQL variable is defined using either ? or $ prefixes, as in SPARQL. Examples:

  • ?var

  • $var



Numbers and booleans

As with SPARQL. Examples:

  • true, false

  • 123, -18

  • 123.0, 456.

  • 1.0e0, 1.0E+6



## Examples

require 'sxp'

### Parsing basic S-expressions

SXP.read "(* 6 7)" #=> [:*, 6, 7]

SXP.read <<-EOF
(define (fact n)
(if (= n 0)
1
(* n (fact (- n 1)))))
EOF

#=> [:define, [:fact, :n],
[:if, [:"=", :n, 0],
1,
[:*, :n, [:fact, [:-, :n, 1]]]]]

### Parsing Scheme S-expressions

SXP::Reader::Scheme.read %q((and #t #f)) #=> [:and, true, false]

### Parsing Common Lisp S-expressions

SXP::Reader::CommonLisp.read %q((or t nil)) #=> [:or, true, nil]

### Parsing SPARQL S-expressions

require 'rdf'

SXP::Reader::SPARQL.read %q((base )) #=> [:base, RDF::URI('https://ar.to/')]

### Writing an SXP with formatting

SXP::Generator.print([:and, true, false]) #=> (and #t #f)

## Documentation

* Full documentation available on [RubyDoc](https://dryruby.github.io/sxp)

* {SXP}

### Parsing SXP
* {SXP::Reader}
* {SXP::Reader::Basic}
* {SXP::Reader::CommonLisp}
* {SXP::Reader::Extended}
* {SXP::Reader::Scheme}
* {SXP::Reader::SPARQL}

### Manipulating SXP
* {SXP::Pair}
* {SXP::List}

### Generating SXP
* {SXP::Generator}

# Dependencies

* [Ruby](https:/ruby-lang.org/) (>= 3.0)
* [RDF.rb](https:/rubygems.org/gems/rdf) (~> 3.3), only needed for SPARQL
S-expressions

# Installation

The recommended installation method is via [RubyGems](https:/rubygems.org/).
To install the latest official release of the SXP.rb gem, do:

% [sudo] gem install sxp

## Download

To get a local working copy of the development repository, do:

% git clone git://github.com/dryruby/sxp.rb.git

Alternatively, you can download the latest development version as a tarball
as follows:

% wget https:/github.com/dryruby/sxp.rb/tarball/master

## Resources

*
*
*

## Change Log

See [Release Notes on GitHub](https://github.com/dryruby/sxp.rb/releases)

## Authors

* [Arto Bendiken](https://github.com/artob) -
* [Gregg Kellogg](https://github.com/gkellogg) -

## Contributors

* [Ben Lavender](https://github.com/bhuga) -

## Contributing

This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange development and release activity. All submissions _must_ be on a feature branch based on the _develop_ branch to ease staging and integration.

* Do your best to adhere to the existing coding conventions and idioms.
* Don't use hard tabs, and don't leave trailing whitespace on any line.
* Do document every method you add using [YARD][] annotations. Read the
[tutorial][YARD-GS] or just look at the existing code for examples.
* Don't touch the `.gemspec`, `VERSION` or `AUTHORS` files. If you need to
change them, do so on your private branch only.
* Do feel free to add yourself to the `CREDITS` file and the corresponding
list in the the `README`. Alphabetical order applies.
* Do note that in order for us to merge any non-trivial changes (as a rule
of thumb, additions larger than about 15 lines of code), we need an
explicit [public domain dedication][PDD] on record from you,
which you will be asked to agree to on the first commit to a repo within the organization.

## License

SXP.rb is free and unencumbered public domain software. For more
information, see or the accompanying UNLICENSE file.

[S-expression]: https://en.wikipedia.org/wiki/S-expression
[Scheme]: https://scheme.info/
[Common Lisp]: https://en.wikipedia.org/wiki/Common_Lisp
[SPARQL]: https://jena.apache.org/documentation/notes/sse.html
[YARD]: https://yardoc.org/
[YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
[PDD]: https://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html