sxp 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -1,38 +1,27 @@
1
- SXP.rb: SXP for Ruby
2
- ====================
1
+ SXP.rb: S-Expressions for Ruby
2
+ ==============================
3
3
 
4
- This is the Ruby reference implementation of the SXP data interchange
5
- format.
4
+ This is a Ruby implementation of a universal [S-expression][] parser.
6
5
 
7
6
  * <http://sxp.rubyforge.org/>
8
7
  * <http://github.com/bendiken/sxp-ruby>
9
8
 
10
- ### About SXP
11
-
12
- SXP is a data interchange format based on S-expressions, the simplest and
13
- most versatile known means of representing complex data structures such as
14
- lists, trees and graphs.
15
-
16
- * <http://sxp.cc/>
17
- * <http://en.wikipedia.org/wiki/S-expression>
18
-
19
9
  Features
20
10
  --------
21
11
 
22
- * Parses S-expressions in SXP format.
12
+ * Parses S-expressions in universal, [Scheme][], [Common Lisp][], or
13
+ [SPARQL][] syntax.
23
14
  * Adds a `#to_sxp` method to Ruby objects.
15
+ * Compatible with Ruby 1.8.7+, Ruby 1.9.x, and JRuby 1.4/1.5.
24
16
 
25
17
  Examples
26
18
  --------
27
19
 
28
20
  require 'sxp'
29
21
 
30
- ### Parsing S-expressions
31
-
32
- SXP.read "(+ 1 2)"
33
-
34
- => [:+, 1, 2]
22
+ ### Parsing S-expressions using universal syntax
35
23
 
24
+ SXP.read "(* 6 7)" #=> [:*, 6, 7]
36
25
 
37
26
  SXP.read <<-EOF
38
27
  (define (fact n)
@@ -41,16 +30,43 @@ Examples
41
30
  (* n (fact (- n 1)))))
42
31
  EOF
43
32
 
44
- => [:define, [:fact, :n],
45
- [:if, [:"=", :n, 0],
46
- 1,
47
- [:*, :n, [:fact, [:-, :n, 1]]]]]
33
+ #=> [:define, [:fact, :n],
34
+ [:if, [:"=", :n, 0],
35
+ 1,
36
+ [:*, :n, [:fact, [:-, :n, 1]]]]]
37
+
38
+ ### Parsing S-expressions using Scheme syntax
39
+
40
+ SXP::Reader::Scheme.read %q((and #t #f)) #=> [:and, true, false]
41
+
42
+ ### Parsing S-expressions using Common Lisp syntax
43
+
44
+ SXP::Reader::CommonLisp.read %q((or t nil)) #=> [:or, true, nil]
45
+
46
+ ### Parsing S-expressions using SPARQL syntax
47
+
48
+ SXP::Reader::SPARQL.read %q((base <http://ar.to/>)) #=> [:base, RDF::URI('http://ar.to/')]
48
49
 
49
50
  Documentation
50
51
  -------------
51
52
 
52
53
  * <http://sxp.rubyforge.org/>
53
54
 
55
+ Dependencies
56
+ ------------
57
+
58
+ * [Ruby](http://ruby-lang.org/) (>= 1.8.7) or (>= 1.8.1 with [Backports][])
59
+ * [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.2.0), only needed for SPARQL
60
+ S-expressions
61
+
62
+ Installation
63
+ ------------
64
+
65
+ The recommended installation method is via [RubyGems](http://rubygems.org/).
66
+ To install the latest official release of the SXP.rb gem, do:
67
+
68
+ % [sudo] gem install sxp
69
+
54
70
  Download
55
71
  --------
56
72
 
@@ -63,21 +79,13 @@ as follows:
63
79
 
64
80
  % wget http://github.com/bendiken/sxp-ruby/tarball/master
65
81
 
66
- Installation
67
- ------------
68
-
69
- The recommended installation method is via RubyGems. To install the latest
70
- official release from Gemcutter, do:
71
-
72
- % [sudo] gem install sxp
73
-
74
82
  Resources
75
83
  ---------
76
84
 
77
85
  * <http://sxp.rubyforge.org/>
78
86
  * <http://github.com/bendiken/sxp>
79
87
  * <http://github.com/bendiken/sxp-ruby>
80
- * <http://gemcutter.org/gems/sxp>
88
+ * <http://rubygems.org/gems/sxp>
81
89
  * <http://rubyforge.org/projects/sxp/>
82
90
  * <http://raa.ruby-lang.org/project/sxp>
83
91
 
@@ -91,3 +99,9 @@ License
91
99
 
92
100
  SXP.rb is free and unencumbered public domain software. For more
93
101
  information, see <http://unlicense.org/> or the accompanying UNLICENSE file.
102
+
103
+ [S-expression]: http://en.wikipedia.org/wiki/S-expression
104
+ [Scheme]: http://scheme.info/
105
+ [Common Lisp]: http://en.wikipedia.org/wiki/Common_Lisp
106
+ [SPARQL]: http://openjena.org/wiki/SSE
107
+ [Backports]: http://rubygems.org/gems/backports
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.6
@@ -14,7 +14,7 @@ module SXP; class Reader
14
14
  def read_token
15
15
  case peek_char
16
16
  when ?(, ?) then [:list, read_char]
17
- when ?" then [:atom, read_string]
17
+ when ?" then [:atom, read_string] #"
18
18
  else super
19
19
  end
20
20
  end
@@ -36,7 +36,7 @@ module SXP; class Reader
36
36
  def read_string
37
37
  buffer = String.new
38
38
  skip_char # '"'
39
- until peek_char == ?"
39
+ until peek_char == ?" #"
40
40
  buffer <<
41
41
  case char = read_char
42
42
  when ?\\ then read_character
@@ -58,7 +58,7 @@ module SXP; class Reader
58
58
  when ?t then ?\t
59
59
  when ?u then read_chars(4).to_i(16).chr
60
60
  when ?U then read_chars(8).to_i(16).chr
61
- when ?" then char
61
+ when ?" then char #"
62
62
  when ?\\ then char
63
63
  else char
64
64
  end
@@ -72,5 +72,5 @@ module SXP; class Reader
72
72
  buffer << read_char while !eof? && peek_char.chr =~ grammar
73
73
  buffer
74
74
  end
75
- end # class Reader
75
+ end # class Basic
76
76
  end; end # class SXP::Reader
@@ -0,0 +1,127 @@
1
+ module SXP; class Reader
2
+ ##
3
+ # A Common Lisp S-expressions parser.
4
+ #
5
+ # @see http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node14.html
6
+ class CommonLisp < Basic
7
+ OPTIONS = {:nil => nil, :t => true, :quote => :quote, :function => :function}
8
+
9
+ DECIMAL = /^[+-]?(\d*)?\.\d*$/
10
+ INTEGER_BASE_2 = /^[+-]?[01]+$/
11
+ INTEGER_BASE_8 = /^[+-]?[0-7]+$/
12
+ INTEGER_BASE_10 = /^[+-]?\d+$/
13
+ INTEGER_BASE_16 = /^[+-]?[\da-z]+$/i
14
+ RATIONAL = /^([+-]?\d+)\/(\d+)$/
15
+
16
+ # @see http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node22.html
17
+ CHARACTERS = {
18
+ 'newline' => "\n",
19
+ 'space' => " ",
20
+ 'backspace' => "\b", # \010 BS
21
+ 'tab' => "\t", # \011 HT
22
+ 'linefeed' => "\n", # \012 LF
23
+ 'page' => "\f", # \014 FF
24
+ 'return' => "\r", # \015 CR
25
+ 'rubout' => "\x7F", # \177 DEL
26
+ }
27
+
28
+ ##
29
+ # Initializes the reader.
30
+ #
31
+ # @param [IO, StringIO, String] input
32
+ # @param [Hash{Symbol => Object}] options
33
+ # @option options [Object] :nil (nil)
34
+ # @option options [Object] :t (true)
35
+ # @option options [Object] :quote (:quote)
36
+ # @option options [Object] :function (:function)
37
+ def initialize(input, options = {}, &block)
38
+ super(input, OPTIONS.merge(options), &block)
39
+ end
40
+
41
+ ##
42
+ # @return [Object]
43
+ def read_token
44
+ case peek_char
45
+ when ?# then [:atom, read_sharp]
46
+ when ?| then [:atom, read_symbol(?|)]
47
+ when ?' then [:atom, read_quote]
48
+ else super
49
+ end
50
+ end
51
+
52
+ ##
53
+ # @return [Object]
54
+ def read_sharp
55
+ skip_char # '#'
56
+ case char = read_char
57
+ when ?b, ?B then read_integer(2)
58
+ when ?o, ?O then read_integer(8)
59
+ when ?x, ?X then read_integer(16)
60
+ when ?\\ then read_character
61
+ when ?( then read_vector
62
+ when ?' then read_function
63
+ else raise Error, "invalid sharp-sign read syntax: ##{char.chr}"
64
+ end
65
+ end
66
+
67
+ ##
68
+ # @return [Symbol]
69
+ def read_symbol(delimiter = nil)
70
+ buffer = String.new
71
+ skip_char # '|'
72
+ until delimiter === peek_char
73
+ buffer <<
74
+ case char = read_char
75
+ when ?\\ then read_character
76
+ else char
77
+ end
78
+ end
79
+ skip_char # '|'
80
+ buffer.to_sym
81
+ end
82
+
83
+ ##
84
+ # Reads `#(1 2 3)` forms.
85
+ #
86
+ # @return [Array]
87
+ def read_vector
88
+ raise NotImplementedError, "#{self.class}#read_vector" # TODO
89
+ end
90
+
91
+ ##
92
+ # Reads `'foobar` forms.
93
+ #
94
+ # @return [Array]
95
+ def read_quote
96
+ skip_char # "'"
97
+ [options[:quote] || :quote, read]
98
+ end
99
+
100
+ ##
101
+ # Reads `#'mapcar` forms.
102
+ #
103
+ # @return [Array]
104
+ def read_function
105
+ [options[:function] || :function, read]
106
+ end
107
+
108
+ ##
109
+ # @return [String]
110
+ # @see http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node22.html
111
+ def read_character
112
+ super
113
+ end
114
+
115
+ ##
116
+ # @return [void]
117
+ def skip_comments
118
+ until eof?
119
+ case (char = peek_char).chr
120
+ when /\s+/ then skip_char
121
+ when /;/ then skip_line
122
+ else break
123
+ end
124
+ end
125
+ end
126
+ end # class CommonLisp
127
+ end; end # class SXP::Reader
@@ -26,5 +26,5 @@ module SXP; class Reader
26
26
  end
27
27
  end
28
28
  end
29
- end # class Reader
29
+ end # class Extended
30
30
  end; end # class SXP::Reader
@@ -1,6 +1,8 @@
1
1
  module SXP; class Reader
2
2
  ##
3
- # A Scheme-like S-expression parser.
3
+ # A Scheme R4RS S-expressions parser.
4
+ #
5
+ # @see http://people.csail.mit.edu/jaffer/r4rs_9.html#SEC65
4
6
  class Scheme < Extended
5
7
  DECIMAL = /^[+-]?(\d*)?\.\d*$/.freeze
6
8
  INTEGER_BASE_2 = /^[+-]?[01]+$/.freeze
@@ -9,6 +11,16 @@ module SXP; class Reader
9
11
  INTEGER_BASE_16 = /^[+-]?[\da-z]+$/i.freeze
10
12
  RATIONAL = /^([+-]?\d+)\/(\d+)$/.freeze
11
13
 
14
+ ##
15
+ # Initializes the reader.
16
+ #
17
+ # @param [IO, StringIO, String] input
18
+ # @param [Hash{Symbol => Object}] options
19
+ # @option options [Symbol] :version (:r4rs)
20
+ def initialize(input, options = {}, &block)
21
+ super(input, {:version => :r4rs}.merge(options), &block)
22
+ end
23
+
12
24
  ##
13
25
  # @return [Object]
14
26
  def read_token
@@ -35,18 +47,18 @@ module SXP; class Reader
35
47
  def read_sharp
36
48
  skip_char # '#'
37
49
  case char = read_char
38
- when ?n then nil # not in Scheme
39
- when ?f then false
40
- when ?t then true
41
- when ?b then read_integer(2)
42
- when ?o then read_integer(8)
43
- when ?d then read_integer(10)
44
- when ?x then read_integer(16)
45
- when ?\\ then read_character
46
- when ?; then skip; read
47
- when ?! then skip_line; read # shebang
50
+ when ?n, ?N then nil # not in Scheme per se
51
+ when ?f, ?F then false
52
+ when ?t, ?T then true
53
+ when ?b, ?B then read_integer(2)
54
+ when ?o, ?O then read_integer(8)
55
+ when ?d, ?D then read_integer(10)
56
+ when ?x, ?X then read_integer(16)
57
+ when ?\\ then read_character
58
+ when ?; then skip; read
59
+ when ?! then skip_line; read # shebang
48
60
  else raise Error, "invalid sharp-sign read syntax: ##{char.chr}"
49
61
  end
50
62
  end
51
- end # class Reader
63
+ end # class Scheme
52
64
  end; end # class SXP::Reader
@@ -0,0 +1,80 @@
1
+ require 'rdf' # @see http://rubygems.org/gems/rdf
2
+
3
+ module SXP; class Reader
4
+ ##
5
+ # A SPARQL Syntax Expressions (SSE) parser.
6
+ #
7
+ # Requires [RDF.rb](http://rdf.rubyforge.org/).
8
+ #
9
+ # @see http://openjena.org/wiki/SSE
10
+ class SPARQL < Extended
11
+ BNODE_ID = /^_:([A-Za-z][A-Za-z0-9]*)/.freeze # FIXME
12
+ BNODE_NEW = /^_:$/.freeze
13
+ VARIABLE = /^\?([A-Za-z][A-Za-z0-9]*)/.freeze # FIXME
14
+ URIREF = /^<([^>]+)>/.freeze
15
+
16
+ ##
17
+ # @return [Object]
18
+ def read_token
19
+ case peek_char
20
+ when ?" then [:atom, read_rdf_literal] # "
21
+ when ?< then [:atom, read_rdf_uri]
22
+ else super
23
+ end
24
+ end
25
+
26
+ ##
27
+ # @return [RDF::Literal]
28
+ def read_rdf_literal
29
+ value = read_string
30
+ options = case peek_char
31
+ when ?@
32
+ skip_char # '@'
33
+ {:language => read_atom}
34
+ when ?^
35
+ 2.times { skip_char } # '^^'
36
+ {:datatype => read_rdf_uri} # TODO: support prefixed names
37
+ else {}
38
+ end
39
+ RDF::Literal.new(value, options)
40
+ end
41
+
42
+ ##
43
+ # @return [RDF::URI]
44
+ def read_rdf_uri
45
+ buffer = String.new
46
+ skip_char # '<'
47
+ until peek_char == ?>
48
+ buffer << read_char # TODO: unescaping
49
+ end
50
+ skip_char # '>'
51
+ RDF::URI.new(buffer)
52
+ end
53
+
54
+ ##
55
+ # @return [Object]
56
+ def read_atom
57
+ case buffer = read_literal
58
+ when '.' then buffer.to_sym
59
+ when INTEGER then RDF::Literal.new(Integer(buffer))
60
+ when BNODE_ID then RDF::Node.new($1)
61
+ when BNODE_NEW then RDF::Node.new
62
+ when VARIABLE then RDF::Query::Variable.new($1)
63
+ else buffer.to_sym
64
+ end
65
+ end
66
+
67
+ ##
68
+ # @return [void]
69
+ def skip_comments
70
+ until eof?
71
+ case (char = peek_char).chr
72
+ when /\s+/ then skip_char
73
+ when /;/ then skip_line
74
+ when /#/ then skip_line
75
+ else break
76
+ end
77
+ end
78
+ end
79
+ end # class SPARQL
80
+ end; end # class SXP::Reader
data/lib/sxp/reader.rb CHANGED
@@ -2,22 +2,73 @@ module SXP
2
2
  ##
3
3
  # The base class for S-expression parsers.
4
4
  class Reader
5
- autoload :Basic, 'sxp/reader/basic'
6
- autoload :Extended, 'sxp/reader/extended'
7
- autoload :Scheme, 'sxp/reader/scheme'
5
+ autoload :Basic, 'sxp/reader/basic'
6
+ autoload :Extended, 'sxp/reader/extended'
7
+ autoload :Scheme, 'sxp/reader/scheme'
8
+ autoload :CommonLisp, 'sxp/reader/common_lisp'
9
+ autoload :SPARQL, 'sxp/reader/sparql'
8
10
 
9
11
  class Error < StandardError; end
10
12
  class EOF < Error; end
11
13
 
12
14
  include Enumerable
13
15
 
14
- # @return [Object]
15
- attr_reader :input
16
+ ##
17
+ # Reads all S-expressions from a given input URL using the HTTP or FTP
18
+ # protocols.
19
+ #
20
+ # @param [String, #to_s] url
21
+ # @param [Hash{Symbol => Object}] options
22
+ # @return [Enumerable<Object>]
23
+ def self.read_url(url, options = {})
24
+ require 'open-uri'
25
+ open(url.to_s, 'rb', nil, options) { |io| read_all(io, options) }
26
+ end
16
27
 
17
- # @return [Hash{Symbol => Object}]
18
- attr_reader :options
28
+ ##
29
+ # Reads all S-expressions from the given input files.
30
+ #
31
+ # @param [Enumerable<String>] filenames
32
+ # @param [Hash{Symbol => Object}] options
33
+ # @return [Enumerable<Object>]
34
+ def self.read_files(*filenames)
35
+ options = filenames.last.is_a?(Hash) ? filenames.pop : {}
36
+ filenames.map { |filename| read_file(filename, options) }.inject { |sxps, sxp| sxps + sxp }
37
+ end
38
+
39
+ ##
40
+ # Reads all S-expressions from a given input file.
41
+ #
42
+ # @param [String, #to_s] filename
43
+ # @param [Hash{Symbol => Object}] options
44
+ # @return [Enumerable<Object>]
45
+ def self.read_file(filename, options = {})
46
+ File.open(filename.to_s, 'rb') { |io| read_all(io, options) }
47
+ end
48
+
49
+ ##
50
+ # Reads all S-expressions from the given input stream.
51
+ #
52
+ # @param [IO, StringIO, String] input
53
+ # @param [Hash{Symbol => Object}] options
54
+ # @return [Enumerable<Object>]
55
+ def self.read_all(input, options = {})
56
+ self.new(input, options).read_all
57
+ end
19
58
 
20
59
  ##
60
+ # Reads one S-expression from the given input stream.
61
+ #
62
+ # @param [IO, StringIO, String] input
63
+ # @param [Hash{Symbol => Object}] options
64
+ # @return [Object]
65
+ def self.read(input, options = {})
66
+ self.new(input, options).read
67
+ end
68
+
69
+ ##
70
+ # Initializes the reader.
71
+ #
21
72
  # @param [IO, StringIO, String] input
22
73
  # @param [Hash{Symbol => Object}] options
23
74
  def initialize(input, options = {}, &block)
@@ -28,7 +79,8 @@ module SXP
28
79
  @input = input
29
80
  when input.respond_to?(:to_str)
30
81
  require 'stringio' unless defined?(StringIO)
31
- @input = StringIO.new(input.to_str)
82
+ # NOTE: StringIO#ungetc mutates the string, so we use #dup to take a copy.
83
+ @input = StringIO.new(input.to_str.dup)
32
84
  else
33
85
  raise ArgumentError, "expected an IO or String input stream, but got #{input.inspect}"
34
86
  end
@@ -41,16 +93,22 @@ module SXP
41
93
  end
42
94
  end
43
95
 
96
+ # @return [Object]
97
+ attr_reader :input
98
+
99
+ # @return [Hash]
100
+ attr_reader :options
101
+
44
102
  ##
45
103
  # @yield [object]
46
104
  # @yieldparam [Object] object
47
105
  # @return [Enumerator]
48
106
  def each(&block)
49
- #block_given? ?
50
- # to_enum
51
- #else
52
- # block.call(read)
53
- #end
107
+ unless block_given?
108
+ to_enum
109
+ else
110
+ read_all.each(&block) # TODO: lazy reading
111
+ end
54
112
  end
55
113
 
56
114
  ##
data/lib/sxp/version.rb CHANGED
@@ -2,7 +2,7 @@ module SXP
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- TINY = 5
5
+ TINY = 6
6
6
  EXTRA = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
data/lib/sxp.rb CHANGED
@@ -26,15 +26,14 @@ module SXP
26
26
  autoload :Reader, 'sxp/reader'
27
27
 
28
28
  ##
29
- # Reads all S-expressions from a given input URI using the HTTP or FTP
29
+ # Reads all S-expressions from a given input URL using the HTTP or FTP
30
30
  # protocols.
31
31
  #
32
32
  # @param [String, #to_s] url
33
33
  # @param [Hash{Symbol => Object}] options
34
34
  # @return [Enumerable<Object>]
35
35
  def self.read_url(url, options = {})
36
- require 'open-uri'
37
- open(url.to_s, 'rb', nil, options) { |io| read_all(io, options) }
36
+ Reader::Scheme.read_url(url, options)
38
37
  end
39
38
 
40
39
  ##
@@ -44,8 +43,7 @@ module SXP
44
43
  # @param [Hash{Symbol => Object}] options
45
44
  # @return [Enumerable<Object>]
46
45
  def self.read_files(*filenames)
47
- options = filenames.last.is_a?(Hash) ? filenames.pop : {}
48
- filenames.map { |filename| read_file(filename, options) }.inject { |sxps, sxp| sxps + sxp }
46
+ Reader::Scheme.read_files(*filenames)
49
47
  end
50
48
 
51
49
  ##
@@ -55,7 +53,7 @@ module SXP
55
53
  # @param [Hash{Symbol => Object}] options
56
54
  # @return [Enumerable<Object>]
57
55
  def self.read_file(filename, options = {})
58
- File.open(filename.to_s, 'rb') { |io| read_all(io, options) }
56
+ Reader::Scheme.read_file(filename, options)
59
57
  end
60
58
 
61
59
  ##
@@ -65,7 +63,7 @@ module SXP
65
63
  # @param [Hash{Symbol => Object}] options
66
64
  # @return [Enumerable<Object>]
67
65
  def self.read_all(input, options = {})
68
- Reader::Scheme.new(input, options).read_all
66
+ Reader::Scheme.read_all(input, options)
69
67
  end
70
68
 
71
69
  ##
@@ -75,7 +73,7 @@ module SXP
75
73
  # @param [Hash{Symbol => Object}] options
76
74
  # @return [Object]
77
75
  def self.read(input, options = {})
78
- Reader::Scheme.new(input, options).read
76
+ Reader::Scheme.read(input, options)
79
77
  end
80
78
 
81
79
  class << self
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 5
9
- version: 0.0.5
8
+ - 6
9
+ version: 0.0.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Arto Bendiken
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-23 00:00:00 +02:00
17
+ date: 2010-08-25 00:00:00 +02:00
18
18
  default_executable: sxp2rdf
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -45,7 +45,7 @@ dependencies:
45
45
  version: 1.3.0
46
46
  type: :development
47
47
  version_requirements: *id002
48
- description: " SXP is a data interchange format based on S-expressions, the simplest and\n most versatile known means of representing complex data structures such as\n lists, trees and graphs.\n"
48
+ description: A pure-Ruby implementation of a universal S-expression parser.
49
49
  email: arto.bendiken@gmail.com
50
50
  executables:
51
51
  - sxp2rdf
@@ -66,8 +66,10 @@ files:
66
66
  - lib/sxp/list.rb
67
67
  - lib/sxp/pair.rb
68
68
  - lib/sxp/reader/basic.rb
69
+ - lib/sxp/reader/common_lisp.rb
69
70
  - lib/sxp/reader/extended.rb
70
71
  - lib/sxp/reader/scheme.rb
72
+ - lib/sxp/reader/sparql.rb
71
73
  - lib/sxp/reader.rb
72
74
  - lib/sxp/version.rb
73
75
  - lib/sxp/writer.rb
@@ -103,6 +105,6 @@ rubyforge_project: sxp
103
105
  rubygems_version: 1.3.6
104
106
  signing_key:
105
107
  specification_version: 3
106
- summary: A pure-Ruby implementation of the SXP data interchange format.
108
+ summary: A pure-Ruby implementation of a universal S-expression parser.
107
109
  test_files: []
108
110