sxp 1.0.1 → 1.2.1

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.
@@ -1,13 +1,13 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require 'rdf' # @see http://rubygems.org/gems/rdf
2
+ require 'rdf' # @see https:/rubygems.org/gems/rdf
3
3
 
4
4
  module SXP; class Reader
5
5
  ##
6
6
  # A SPARQL Syntax Expressions (SSE) parser.
7
7
  #
8
- # Requires [RDF.rb](http://rdf.rubyforge.org/).
8
+ # Requires [RDF.rb](https:/rubygems.org/gems/rdf/).
9
9
  #
10
- # @see http://openjena.org/wiki/SSE
10
+ # @see https:/openjena.org/wiki/SSE
11
11
  class SPARQL < Extended
12
12
  # Alias for rdf:type
13
13
  A = /^a$/
@@ -29,7 +29,11 @@ module SXP; class Reader
29
29
  # Distinguished variable
30
30
  VAR_ID = /^\?(.*)/
31
31
  # Non-distinguished variable
32
- ND_VAR = /^\?(:?\?([0-9]+)?|(\.[0-9]+))/
32
+ ND_VAR = /^\?(?:[\?\.])(.*)/
33
+ # Distinguished existential variable
34
+ EVAR_ID = /^\$(.*)/
35
+ # Non-distinguished existential variable
36
+ ND_EVAR = /^\$(?:[\$\.])(.*)/
33
37
  # A QName, subject to expansion to URIs using {PREFIX}
34
38
  PNAME = /([^:]*):(.*)/
35
39
 
@@ -67,7 +71,7 @@ module SXP; class Reader
67
71
  #
68
72
  # @param [IO, StringIO, String] input
69
73
  # @param [Hash{Symbol => Object}] options
70
- def initialize(input, options = {}, &block)
74
+ def initialize(input, **options, &block)
71
75
  super { @prefixes = {}; @bnodes = {}; @list_depth = 0 }
72
76
 
73
77
  if block_given?
@@ -79,12 +83,12 @@ module SXP; class Reader
79
83
  end
80
84
 
81
85
  ##
82
- # Reads SSE Tokens, including {RDF::Literal}, {RDF::URI} and RDF::Node.
86
+ # Reads SSE Tokens, including `RDF::Literal`, `RDF::URI` and `RDF::Node`.
83
87
  #
84
88
  # Performs forward reference for prefix and base URI representations and saves in
85
89
  # {#base_uri} and {#prefixes} accessors.
86
90
  #
87
- # Transforms tokens matching a {PNAME} pattern into {RDF::URI} instances if a match is
91
+ # Transforms tokens matching a {PNAME} pattern into `RDF::URI` instances if a match is
88
92
  # found with a previously identified {PREFIX}.
89
93
  # @return [Object]
90
94
  def read_token
@@ -125,8 +129,6 @@ module SXP; class Reader
125
129
  uri = RDF::URI(base.to_s + suffix)
126
130
  #STDERR.puts "read_tok lexical uri: #{uri.inspect}"
127
131
 
128
- # Cause URI to be serialized as a lexical
129
- uri.lexical = value
130
132
  [:atom, uri]
131
133
  else
132
134
  tok
@@ -158,7 +160,7 @@ module SXP; class Reader
158
160
  {datatype: read_token.last}
159
161
  else {}
160
162
  end
161
- RDF::Literal(value, options)
163
+ RDF::Literal(value, **options)
162
164
  end
163
165
 
164
166
  ##
@@ -169,7 +171,7 @@ module SXP; class Reader
169
171
  #
170
172
  # @return [RDF::URI]
171
173
  def read_rdf_uri
172
- buffer = String.new
174
+ buffer = ""
173
175
  skip_char # '<'
174
176
  return :< if (char = peek_char).nil? || char.chr !~ ATOM # FIXME: nasty special case for the '< symbol
175
177
  return :<= if peek_char.chr.eql?(?=.chr) && read_char # FIXME: nasty special case for the '<= symbol
@@ -180,9 +182,7 @@ module SXP; class Reader
180
182
 
181
183
  # If we have a base URI, use that when constructing a new URI
182
184
  uri = if self.base_uri && RDF::URI(buffer).relative?
183
- u = self.base_uri.join(buffer)
184
- u.lexical = "<#{buffer}>" unless u.to_s == buffer # So that it can be re-serialized properly
185
- u
185
+ self.base_uri.join(buffer)
186
186
  else
187
187
  RDF::URI(buffer)
188
188
  end
@@ -207,7 +207,7 @@ module SXP; class Reader
207
207
  #
208
208
  # Atoms parsed including `base`, `prefix`, `true`, `false`, numeric, BNodes and variables.
209
209
  #
210
- # Creates {RDF::Literal}, RDF::Node, or {RDF::Query::Variable} instances where appropriate.
210
+ # Creates `RDF::Literal`, `RDF::Node`, or `RDF::Query::Variable` instances where appropriate.
211
211
  #
212
212
  # @return [Object]
213
213
  def read_atom
@@ -223,8 +223,10 @@ module SXP; class Reader
223
223
  when INTEGER then RDF::Literal::Integer.new(buffer)
224
224
  when BNODE_ID then @bnodes[$1] ||= RDF::Node($1)
225
225
  when BNODE_NEW then RDF::Node.new
226
- when ND_VAR then variable($1, false)
227
- when VAR_ID then variable($1, true)
226
+ when ND_VAR then variable($1, distinguished: false)
227
+ when VAR_ID then variable($1, distinguished: true)
228
+ when ND_EVAR then variable($1, existential: true, distinguished: false)
229
+ when EVAR_ID then variable($1, existential: true, distinguished: true)
228
230
  else buffer.to_sym
229
231
  end
230
232
  end
@@ -251,20 +253,16 @@ module SXP; class Reader
251
253
  # is a disinguished or non-distinguished variable. Non-distinguished
252
254
  # variables are effectively the same as BNodes.
253
255
  # @return [RDF::Query::Variable]
254
- def variable(id, distinguished = true)
256
+ def variable(id, distinguished: true, existential: false)
255
257
  id = nil if id.to_s.empty?
256
258
 
257
259
  if id
258
260
  @vars ||= {}
259
261
  @vars[id] ||= begin
260
- v = RDF::Query::Variable.new(id)
261
- v.distinguished = distinguished
262
- v
262
+ RDF::Query::Variable.new(id, distinguished: distinguished, existential: existential)
263
263
  end
264
264
  else
265
- v = RDF::Query::Variable.new
266
- v.distinguished = distinguished
267
- v
265
+ RDF::Query::Variable.new(distinguished: distinguished, existential: existential)
268
266
  end
269
267
  end
270
268
  end # SPARQL
data/lib/sxp/reader.rb CHANGED
@@ -22,9 +22,9 @@ module SXP
22
22
  # @param [Hash{Symbol => Object}] options
23
23
  # See {#read}
24
24
  # @return [Enumerable<Object>]
25
- def self.read_url(url, options = {})
25
+ def self.read_url(url, **options)
26
26
  require 'open-uri'
27
- open(url.to_s, 'rb', nil, options) { |io| read_all(io, options) }
27
+ open(url.to_s, 'rb', nil, **options) { |io| read_all(io, **options) }
28
28
  end
29
29
 
30
30
  ##
@@ -33,7 +33,7 @@ module SXP
33
33
  # @overload read_files(*filenames)
34
34
  # @param [Enumerable<String>] filenames
35
35
  #
36
- # @overload read_files(*filenames, options)
36
+ # @overload read_files(*filenames, **options)
37
37
  # @param [Enumerable<String>] filenames
38
38
  # @param [Hash{Symbol => Object}] options
39
39
  # See {#read}
@@ -41,7 +41,7 @@ module SXP
41
41
  # @return [Enumerable<Object>]
42
42
  def read_files(*filenames)
43
43
  options = filenames.last.is_a?(Hash) ? filenames.pop : {}
44
- filenames.map { |filename| read_file(filename, options) }.inject { |sxps, sxp| sxps + sxp }
44
+ filenames.map { |filename| read_file(filename, **options) }.inject { |sxps, sxp| sxps + sxp }
45
45
  end
46
46
 
47
47
  ##
@@ -51,8 +51,8 @@ module SXP
51
51
  # @param [Hash{Symbol => Object}] options
52
52
  # See {#read}
53
53
  # @return [Enumerable<Object>]
54
- def self.read_file(filename, options = {})
55
- File.open(filename.to_s, 'rb') { |io| read_all(io, options) }
54
+ def self.read_file(filename, **options)
55
+ File.open(filename.to_s, 'rb') { |io| read_all(io, **options) }
56
56
  end
57
57
 
58
58
  ##
@@ -62,8 +62,8 @@ module SXP
62
62
  # @param [Hash{Symbol => Object}] options
63
63
  # See {#read}
64
64
  # @return [Enumerable<Object>]
65
- def self.read_all(input, options = {})
66
- self.new(input, options).read_all
65
+ def self.read_all(input, **options)
66
+ self.new(input, **options).read_all
67
67
  end
68
68
 
69
69
  ##
@@ -73,8 +73,8 @@ module SXP
73
73
  # @param [Hash{Symbol => Object}] options
74
74
  # See {#read}
75
75
  # @return [Object]
76
- def self.read(input, options = {})
77
- self.new(input, options).read
76
+ def self.read(input, **options)
77
+ self.new(input, **options).read
78
78
  end
79
79
 
80
80
  ##
@@ -82,7 +82,7 @@ module SXP
82
82
  #
83
83
  # @param [IO, StringIO, String] input
84
84
  # @param [Hash{Symbol => Object}] options
85
- def initialize(input, options = {}, &block)
85
+ def initialize(input, **options, &block)
86
86
  @options = options.dup
87
87
 
88
88
  case
@@ -127,10 +127,10 @@ module SXP
127
127
  # @param [Hash{Symbol => Object}] options
128
128
  # See {#read}
129
129
  # @return [Array]
130
- def read_all(options = {})
130
+ def read_all(**options)
131
131
  list = []
132
132
  catch (:eof) do
133
- list << read(options.merge(eof: :throw)) until eof?
133
+ list << read(eof: :throw, **options) until eof?
134
134
  end
135
135
  list
136
136
  end
@@ -145,19 +145,19 @@ module SXP
145
145
  # Expected list terminator; it's an error
146
146
  # if another terminator is found
147
147
  # @return [Object]
148
- def read(options = {})
148
+ def read(eof: nil, eol: nil, list_term: false, **options)
149
149
  skip_comments
150
150
  token, value = read_token
151
151
  case token
152
152
  when :eof
153
- throw :eof if options[:eof] == :throw
153
+ throw :eof if eof == :throw
154
154
  raise EOF, "unexpected end of input"
155
155
  when :list
156
156
  if ndx = self.class.const_get(:LPARENS).index(value)
157
- list_term = self.class.const_get(:RPARENS)[ndx]
158
- read_list(list_term)
157
+ term = self.class.const_get(:RPARENS)[ndx]
158
+ read_list(term)
159
159
  else
160
- throw :eol if options[:eol] == :throw && value == options[:list_term]
160
+ throw :eol if eol == :throw && value == list_term
161
161
  raise Error, "unexpected list terminator: ?#{value.chr}"
162
162
  end
163
163
  else value
data/lib/sxp.rb CHANGED
@@ -1,23 +1,8 @@
1
1
  require 'rational'
2
2
  require 'stringio'
3
3
 
4
- if RUBY_VERSION < '1.8.7'
5
- # @see http://rubygems.org/gems/backports
6
- begin
7
- require 'backports/1.8.7'
8
- rescue LoadError
9
- begin
10
- require 'rubygems'
11
- require 'backports/1.8.7'
12
- rescue LoadError
13
- abort "SXP.rb requires Ruby 1.8.7 or the Backports gem (hint: `gem install backports')."
14
- end
15
- end
16
- end
17
-
18
4
  require 'sxp/version'
19
5
  require 'sxp/extensions'
20
- require 'sxp/writer'
21
6
 
22
7
  module SXP
23
8
  autoload :Pair, 'sxp/pair'
@@ -32,8 +17,8 @@ module SXP
32
17
  # @param [String, #to_s] url
33
18
  # @param [Hash{Symbol => Object}] options
34
19
  # @return [Enumerable<Object>]
35
- def self.read_url(url, options = {})
36
- Reader::Basic.read_url(url, options)
20
+ def self.read_url(url, **options)
21
+ Reader::Basic.read_url(url, **options)
37
22
  end
38
23
 
39
24
  ##
@@ -42,7 +27,7 @@ module SXP
42
27
  # @overload read_files(*filenames)
43
28
  # @param [Enumerable<String>] filenames
44
29
  #
45
- # @overload read_files(*filenames, options)
30
+ # @overload read_files(*filenames, **options)
46
31
  # @param [Enumerable<String>] filenames
47
32
  # @param [Hash{Symbol => Object}] options
48
33
  #
@@ -57,8 +42,8 @@ module SXP
57
42
  # @param [String, #to_s] filename
58
43
  # @param [Hash{Symbol => Object}] options
59
44
  # @return [Enumerable<Object>]
60
- def self.read_file(filename, options = {})
61
- Reader::Basic.read_file(filename, options)
45
+ def self.read_file(filename, **options)
46
+ Reader::Basic.read_file(filename, **options)
62
47
  end
63
48
 
64
49
  ##
@@ -67,8 +52,8 @@ module SXP
67
52
  # @param [IO, StringIO, String] input
68
53
  # @param [Hash{Symbol => Object}] options
69
54
  # @return [Enumerable<Object>]
70
- def self.read_all(input, options = {})
71
- Reader::Basic.read_all(input, options)
55
+ def self.read_all(input, **options)
56
+ Reader::Basic.read_all(input, **options)
72
57
  end
73
58
 
74
59
  ##
@@ -77,8 +62,8 @@ module SXP
77
62
  # @param [IO, StringIO, String] input
78
63
  # @param [Hash{Symbol => Object}] options
79
64
  # @return [Object]
80
- def self.read(input, options = {})
81
- Reader::Basic.read(input, options)
65
+ def self.read(input, **options)
66
+ Reader::Basic.read(input, **options)
82
67
  end
83
68
 
84
69
  ##
metadata CHANGED
@@ -1,64 +1,86 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sxp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arto Bendiken
8
8
  - Gregg Kellogg
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-12-14 00:00:00.000000000 Z
12
+ date: 2022-01-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rspec
15
+ name: rdf
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '3.7'
21
- type: :development
20
+ version: '3.2'
21
+ type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '3.7'
27
+ version: '3.2'
28
28
  - !ruby/object:Gem::Dependency
29
- name: yard
29
+ name: matrix
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: amazing_print
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
46
  - - "~>"
33
47
  - !ruby/object:Gem::Version
34
- version: '0.9'
48
+ version: '1.4'
35
49
  type: :development
36
50
  prerelease: false
37
51
  version_requirements: !ruby/object:Gem::Requirement
38
52
  requirements:
39
53
  - - "~>"
40
54
  - !ruby/object:Gem::Version
41
- version: '0.9'
55
+ version: '1.4'
42
56
  - !ruby/object:Gem::Dependency
43
- name: rdf
57
+ name: rspec
44
58
  requirement: !ruby/object:Gem::Requirement
45
59
  requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '2.2'
49
- - - "<"
60
+ - - "~>"
50
61
  - !ruby/object:Gem::Version
51
- version: '4.0'
52
- type: :runtime
62
+ version: '3.10'
63
+ type: :development
53
64
  prerelease: false
54
65
  version_requirements: !ruby/object:Gem::Requirement
55
66
  requirements:
56
- - - ">="
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.10'
70
+ - !ruby/object:Gem::Dependency
71
+ name: yard
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
57
75
  - !ruby/object:Gem::Version
58
- version: '2.2'
59
- - - "<"
76
+ version: '0.9'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
60
82
  - !ruby/object:Gem::Version
61
- version: '4.0'
83
+ version: '0.9'
62
84
  description: Universal S-expression parser with specific support for Common Lisp,
63
85
  Scheme, and RDF/SPARQL
64
86
  email:
@@ -93,12 +115,11 @@ files:
93
115
  - lib/sxp/reader/scheme.rb
94
116
  - lib/sxp/reader/sparql.rb
95
117
  - lib/sxp/version.rb
96
- - lib/sxp/writer.rb
97
- homepage: http://sxp.rubyforge.org/
118
+ homepage: https://github.com/dryruby/sxp/
98
119
  licenses:
99
120
  - Unlicense
100
121
  metadata: {}
101
- post_install_message:
122
+ post_install_message:
102
123
  rdoc_options: []
103
124
  require_paths:
104
125
  - lib
@@ -106,16 +127,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
127
  requirements:
107
128
  - - ">="
108
129
  - !ruby/object:Gem::Version
109
- version: 2.2.2
130
+ version: '2.6'
110
131
  required_rubygems_version: !ruby/object:Gem::Requirement
111
132
  requirements:
112
133
  - - ">="
113
134
  - !ruby/object:Gem::Version
114
135
  version: '0'
115
136
  requirements: []
116
- rubyforge_project: sxp
117
- rubygems_version: 2.6.14
118
- signing_key:
137
+ rubygems_version: 3.3.3
138
+ signing_key:
119
139
  specification_version: 4
120
140
  summary: A pure-Ruby implementation of a universal S-expression parser.
121
141
  test_files: []
data/lib/sxp/writer.rb DELETED
@@ -1,216 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require 'bigdecimal'
3
- require 'time'
4
-
5
- ##
6
- # Extensions for Ruby's `Object` class.
7
- class Object
8
- ##
9
- # Returns the SXP representation of this object.
10
- #
11
- # @return [String]
12
- def to_sxp
13
- to_s.to_json
14
- end
15
- end
16
-
17
- ##
18
- # Extensions for Ruby's `NilClass` class.
19
- class NilClass
20
- ##
21
- # Returns the SXP representation of this object.
22
- #
23
- # @return [String]
24
- def to_sxp
25
- '#n'
26
- end
27
- end
28
-
29
- ##
30
- # Extensions for Ruby's `FalseClass` class.
31
- class FalseClass
32
- ##
33
- # Returns the SXP representation of this object.
34
- #
35
- # @return [String]
36
- def to_sxp
37
- '#f'
38
- end
39
- end
40
-
41
- ##
42
- # Extensions for Ruby's `TrueClass` class.
43
- class TrueClass
44
- ##
45
- # Returns the SXP representation of this object.
46
- #
47
- # @return [String]
48
- def to_sxp
49
- '#t'
50
- end
51
- end
52
-
53
- ##
54
- # Extensions for Ruby's `String` class.
55
- class String
56
- ##
57
- # Returns the SXP representation of this object.
58
- #
59
- # @return [String]
60
- def to_sxp
61
- inspect
62
- end
63
- end
64
-
65
- ##
66
- # Extensions for Ruby's `Symbol` class.
67
- class Symbol
68
- ##
69
- # Returns the SXP representation of this object.
70
- #
71
- # @return [String]
72
- def to_sxp
73
- to_s
74
- end
75
- end
76
-
77
- ##
78
- # Extensions for Ruby's `Integer` class.
79
- class Integer
80
- ##
81
- # Returns the SXP representation of this object.
82
- #
83
- # @return [String]
84
- def to_sxp
85
- to_s
86
- end
87
- end
88
-
89
- ##
90
- # Extensions for Ruby's `BigDecimal` class.
91
- class BigDecimal
92
- ##
93
- # Returns the SXP representation of this object.
94
- #
95
- # @return [String]
96
- def to_sxp
97
- to_f.to_s
98
- end
99
- end
100
-
101
- ##
102
- # Extensions for Ruby's `Float` class.
103
- class Float
104
- ##
105
- # Returns the SXP representation of this object.
106
- #
107
- # @return [String]
108
- def to_sxp
109
- case
110
- when nan? then 'nan.'
111
- when infinite? then (infinite? > 0 ? '+inf.' : '-inf.')
112
- else to_s
113
- end
114
- end
115
- end
116
-
117
- ##
118
- # Extensions for Ruby's `Array` class.
119
- class Array
120
- ##
121
- # Returns the SXP representation of this object.
122
- #
123
- # @return [String]
124
- def to_sxp
125
- '(' << map { |x| x.to_sxp }.join(' ') << ')'
126
- end
127
- end
128
-
129
- ##
130
- # Extensions for Ruby's `Time` class.
131
- class Time
132
- ##
133
- # Returns the SXP representation of this object.
134
- #
135
- # @return [String]
136
- def to_sxp
137
- '#@' << (respond_to?(:xmlschema) ? xmlschema : to_i).to_s
138
- end
139
- end
140
-
141
- ##
142
- # Extensions for Ruby's `Regexp` class.
143
- class Regexp
144
- ##
145
- # Returns the SXP representation of this object.
146
- #
147
- # @return [String]
148
- def to_sxp
149
- '#' << inspect
150
- end
151
- end
152
-
153
- begin
154
- require 'rdf' # For SPARQL
155
-
156
- class RDF::URI
157
- ##
158
- # Returns the SXP representation of this object.
159
- #
160
- # @return [String]
161
- def to_sxp; lexical || "<#{self}>"; end
162
- end
163
-
164
- class RDF::Node
165
- ##
166
- # Returns the SXP representation of this object.
167
- #
168
- # @return [String]
169
- def to_sxp; to_s; end
170
- end
171
-
172
- class RDF::Literal
173
- ##
174
- # Returns the SXP representation of a Literal.
175
- #
176
- # @return [String]
177
- def to_sxp
178
- case datatype
179
- when RDF::XSD.boolean, RDF::XSD.integer, RDF::XSD.double, RDF::XSD.decimal, RDF::XSD.time
180
- # Retain stated lexical form if possible
181
- valid? ? to_s : object.to_sxp
182
- else
183
- text = value.dump
184
- text << "@#{language}" if self.has_language?
185
- text << "^^#{datatype.to_sxp}" if self.has_datatype?
186
- text
187
- end
188
- end
189
- end
190
-
191
- class RDF::Query
192
- # Transform Query into an Array form of an SXP
193
- #
194
- # If Query is named, it's treated as a GroupGraphPattern, otherwise, a BGP
195
- #
196
- # @return [Array]
197
- def to_sxp
198
- res = [:bgp] + patterns
199
- (named? ? [:graph, graph_name, res] : res).to_sxp
200
- end
201
- end
202
-
203
- class RDF::Query::Pattern
204
- # Transform Query Pattern into an SXP
205
- # @return [String]
206
- def to_sxp
207
- [:triple, subject, predicate, object].to_sxp
208
- end
209
- end
210
-
211
- class RDF::Query::Variable
212
- def to_sxp; to_s; end
213
- end
214
- rescue LoadError => e
215
- # Ignore if RDF not loaded
216
- end