xmlparser 0.6.81

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.
Files changed (52) hide show
  1. data/MANIFEST +112 -0
  2. data/README +697 -0
  3. data/README.ja +789 -0
  4. data/Rakefile +34 -0
  5. data/ext/encoding.h +91 -0
  6. data/ext/xmlparser/mkrf_conf.rb +28 -0
  7. data/ext/xmlparser/xmlparser.c +2226 -0
  8. data/lib/sax.rb +1 -0
  9. data/lib/saxdriver.rb +1 -0
  10. data/lib/wget.rb +47 -0
  11. data/lib/xml/dom/builder-ja.rb +58 -0
  12. data/lib/xml/dom/builder.rb +310 -0
  13. data/lib/xml/dom/core.rb +3276 -0
  14. data/lib/xml/dom/digest.rb +94 -0
  15. data/lib/xml/dom/visitor.rb +182 -0
  16. data/lib/xml/dom2/attr.rb +213 -0
  17. data/lib/xml/dom2/cdatasection.rb +76 -0
  18. data/lib/xml/dom2/characterdata.rb +177 -0
  19. data/lib/xml/dom2/comment.rb +81 -0
  20. data/lib/xml/dom2/core.rb +19 -0
  21. data/lib/xml/dom2/document.rb +317 -0
  22. data/lib/xml/dom2/documentfragment.rb +82 -0
  23. data/lib/xml/dom2/documenttype.rb +102 -0
  24. data/lib/xml/dom2/dombuilder.rb +277 -0
  25. data/lib/xml/dom2/dombuilderfilter.rb +12 -0
  26. data/lib/xml/dom2/domentityresolver.rb +13 -0
  27. data/lib/xml/dom2/domentityresolverimpl.rb +37 -0
  28. data/lib/xml/dom2/domexception.rb +95 -0
  29. data/lib/xml/dom2/domimplementation.rb +61 -0
  30. data/lib/xml/dom2/dominputsource.rb +29 -0
  31. data/lib/xml/dom2/element.rb +533 -0
  32. data/lib/xml/dom2/entity.rb +110 -0
  33. data/lib/xml/dom2/entityreference.rb +107 -0
  34. data/lib/xml/dom2/namednodemap.rb +138 -0
  35. data/lib/xml/dom2/node.rb +587 -0
  36. data/lib/xml/dom2/nodelist.rb +231 -0
  37. data/lib/xml/dom2/notation.rb +86 -0
  38. data/lib/xml/dom2/processinginstruction.rb +155 -0
  39. data/lib/xml/dom2/text.rb +128 -0
  40. data/lib/xml/dom2/xpath.rb +398 -0
  41. data/lib/xml/encoding-ja.rb +42 -0
  42. data/lib/xml/parser.rb +13 -0
  43. data/lib/xml/parserns.rb +236 -0
  44. data/lib/xml/sax.rb +353 -0
  45. data/lib/xml/saxdriver.rb +370 -0
  46. data/lib/xml/xpath.rb +3284 -0
  47. data/lib/xml/xpath.ry +2352 -0
  48. data/lib/xmldigest.rb +1 -0
  49. data/lib/xmltree.rb +1 -0
  50. data/lib/xmltreebuilder.rb +1 -0
  51. data/lib/xmltreevisitor.rb +1 -0
  52. metadata +111 -0
@@ -0,0 +1,370 @@
1
+ ## -*- Ruby -*-
2
+ ## SAX Driver for XML::Parser (experimental)
3
+ ## 1999 by yoshidam
4
+ ##
5
+ ## Limitation:
6
+ ## * AttributeList#getType always returns 'CDATA'.
7
+ ## * DocumentHandler#ignorableWhitespace is never called.
8
+ ## * ErrorHandler#warning and ErrorHandler#error are never called.
9
+ ## * Locator#getLineNumber and Locator#getColumnNumber do not
10
+ ## return the proper value in DocumentHandler#characters method.
11
+ ## * Parser#setLocale is not implemented.
12
+ ## * Parser cannot parse non-local file.
13
+
14
+ require 'xml/parser'
15
+ require 'xml/sax'
16
+
17
+ module XML
18
+ class Parser
19
+ class SAXDriver
20
+ include XML::SAX::Parser
21
+ include XML::SAX::AttributeList
22
+ include XML::SAX::Locator
23
+
24
+ ## very simple URL parser
25
+ class URL
26
+ attr :scheme
27
+ attr :login
28
+ attr :urlpath
29
+
30
+ def initialize(url, url2 = nil)
31
+ @scheme = ''
32
+ @login = ''
33
+ @urlpath = ''
34
+ if url.kind_of?(String) && url2.nil?
35
+ if url =~ /^([a-z0-9\+\-\.]+):\/\/([^\/]+)(\/.*)$/
36
+ @scheme, @login, @urlpath = $1, $2, $3
37
+ else
38
+ url = File::expand_path(url)
39
+ @scheme, @login, @urlpath = "file", "localhost", url
40
+ end
41
+ elsif url.kind_of?(URL) && url2.kind_of?(String)
42
+ if url2 =~ /^([a-z0-9\+\-\.]+):\/\/([^\/]+)(\/.*)$/
43
+ @scheme, @login, @urlpath = $1, $2, $3
44
+ else
45
+ @scheme = url.scheme
46
+ @login = url.login
47
+ if url2 =~ /^\//
48
+ @urlpath = url2
49
+ else
50
+ path = url.urlpath
51
+ path =~ /^([^\#]+)\#?(.*)$/
52
+ path = $1
53
+ path =~ /^([^\?]+)\??(.*)$/
54
+ path = $1
55
+ path =~ /^(.+)\/(.*)/
56
+ path = $1
57
+ @urlpath = File.expand_path(path + '/' + url2)
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def to_s
64
+ @scheme + "://" + @login + @urlpath
65
+ end
66
+ end
67
+
68
+ ## All parser events are delegated to SAXDriver
69
+ class SAXParser < XML::Parser
70
+ include XML::SAX::Locator
71
+
72
+ def SAXParser.new(saxdriver, *rest)
73
+ obj = super(*rest)
74
+ obj.setDriver(saxdriver)
75
+ obj
76
+ end
77
+
78
+ def initialize(*args)
79
+ super(*args)
80
+ @publicId = nil
81
+ @systemId = nil
82
+ if self.respond_to?(:setParamEntityParsing)
83
+ self.setParamEntityParsing(PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
84
+ end
85
+ end
86
+
87
+ def setDriver(saxdriver)
88
+ @saxdriver = saxdriver
89
+ end
90
+
91
+ def parse(inputSource)
92
+ @systemId = inputSource.getSystemId
93
+ @saxdriver.pushLocator(self)
94
+ setBase(@systemId)
95
+ super(inputSource.getByteStream.read)
96
+ @saxdriver.popLocator
97
+ end
98
+
99
+ def getPublicId
100
+ @publicId
101
+ end
102
+
103
+ def getSystemId
104
+ @systemId
105
+ end
106
+
107
+ def getLineNumber
108
+ self.line
109
+ end
110
+
111
+ def getColumnNumber
112
+ self.column
113
+ end
114
+
115
+ def startElement(name, attr)
116
+ @saxdriver.startElement(name, attr)
117
+ end
118
+
119
+ def endElement(name)
120
+ @saxdriver.endElement(name)
121
+ end
122
+
123
+ def character(data)
124
+ @saxdriver.character(data)
125
+ end
126
+
127
+ def processingInstruction(target, data)
128
+ @saxdriver.processingInstruction(target, data)
129
+ end
130
+
131
+ def notationDecl(name, base, sysid, pubid)
132
+ @saxdriver.notationDecl(name, base, sysid, pubid)
133
+ end
134
+
135
+ def unparsedEntityDecl(name, base, sysid, pubid, notation)
136
+ @saxdriver.unparsedEntityDecl(name, base, sysid, pubid, notation)
137
+ end
138
+
139
+ def comment(data)
140
+ end
141
+
142
+ def externalEntityRef(context, base, systemId, publicId)
143
+ inputSource = @saxdriver.xmlOpen(base, systemId, publicId)
144
+ encoding = inputSource.getEncoding
145
+ if encoding
146
+ parser = SAXParser.new(@saxdriver, self, context, encoding)
147
+ else
148
+ parser = SAXParser.new(@saxdriver, self, context)
149
+ end
150
+ parser.parse(inputSource)
151
+ parser.done
152
+ end
153
+ end
154
+
155
+ class DummyLocator
156
+ include XML::SAX::Locator
157
+
158
+ def initialize(systemId)
159
+ @systemId = systemId
160
+ end
161
+
162
+ def getPublicId; nil end
163
+ def getSystemId; @systemId end
164
+ def getLineNumber; 1 end
165
+ def getColumnNumber; 1 end
166
+ end
167
+
168
+ ## open stream if it is not opened
169
+ def openInputStream(stream)
170
+ if stream.getByteStream
171
+ return stream
172
+ else stream.getSystemId
173
+ url = URL.new(stream.getSystemId)
174
+ if url.scheme == 'file' && url.login == 'localhost'
175
+ s = open(url.urlpath)
176
+ stream.setByteStream(s)
177
+ return stream
178
+ end
179
+ end
180
+ return nil
181
+ end
182
+ private :openInputStream
183
+
184
+ def xmlOpen(base, systemId, publicId)
185
+ if base.nil? || base == ""
186
+ file = URL.new(systemId)
187
+ else
188
+ file = URL.new(URL.new(base), systemId)
189
+ end
190
+ if !@entityResolver.nil?
191
+ stream = @entityResolver.resolveEntity(file.to_s, publicId)
192
+ return openInputStream(stream) if stream
193
+ end
194
+ if file.scheme == 'file' && file.login == 'localhost'
195
+ stream = open(file.urlpath)
196
+ is = XML::SAX::InputSource.new(stream)
197
+ is.setSystemId(file.to_s)
198
+ is.setPublicId(publicId)
199
+ return is
200
+ end
201
+ end
202
+
203
+ def initialize
204
+ handler = XML::SAX::HandlerBase.new
205
+ @attributes = nil
206
+ @documentHandler = handler
207
+ @dtdHandler = handler
208
+ @errorHandler = handler
209
+ @entityResolver = handler
210
+ @dataBuf = ''
211
+ @locators = []
212
+ end
213
+
214
+ ## implementation of Parser
215
+ def setEntityResolver(handler)
216
+ if !handler.kind_of?(XML::SAX::EntityResolver)
217
+ raise TypeError.new("parameter error")
218
+ end
219
+ @entityResolver = handler
220
+ end
221
+
222
+ ## implementation of Parser
223
+ def setDocumentHandler(handler)
224
+ if !handler.kind_of?(XML::SAX::DocumentHandler)
225
+ raise TypeError.new("parameter error")
226
+ end
227
+ @documentHandler = handler
228
+ end
229
+
230
+ ## implementation of Parser
231
+ def setDTDHandler(handler)
232
+ if !handler.kind_of?(XML::SAX::DTDHandler)
233
+ raise TypeError.new("parameter error")
234
+ end
235
+ @dtdHandler = handler
236
+ end
237
+
238
+ ## implementation of Parser
239
+ def setErrorHandler(handler)
240
+ if !handler.kind_of?(XML::SAX::ErrorHandler)
241
+ raise TypeError.new("parameter error")
242
+ end
243
+ @errorHandler = handler
244
+ end
245
+
246
+ ## implementation of Parser
247
+ def setLocale(locale)
248
+ raise SAXException.new("locale not supported")
249
+ end
250
+
251
+ def flushData
252
+ if @dataBuf.length > 0
253
+ @documentHandler.characters(@dataBuf, 0, @dataBuf.length)
254
+ @dataBuf = ''
255
+ end
256
+ end
257
+ private :flushData
258
+
259
+ def startElement(name, attrs)
260
+ flushData;
261
+ @attributes = attrs
262
+ @documentHandler.startElement(name, self)
263
+ end
264
+
265
+ def character(data)
266
+ @dataBuf << data
267
+ end
268
+
269
+ def endElement(name)
270
+ flushData;
271
+ @documentHandler.endElement(name)
272
+ end
273
+
274
+ def processingInstruction(target, data)
275
+ flushData;
276
+ @documentHandler.processingInstruction(target, data)
277
+ end
278
+
279
+ def notationDecl(name, base, sysid, pubid)
280
+ @dtdHandler.notationDecl(name, pubid, sysid)
281
+ end
282
+
283
+ def unparsedEntityDecl(name, base, sysid, pubid, notation)
284
+ @dtdHandler.unparsedEntityDecl(name, pubid, sysid, notation)
285
+ end
286
+
287
+ ## implementation of AttributeList
288
+ def getLength
289
+ @attributes.length
290
+ end
291
+
292
+ ## implementation of AttributeList
293
+ def getName(pos)
294
+ @attributes.keys[pos]
295
+ end
296
+
297
+ ## implementation of AttributeList
298
+ def getValue(pos)
299
+ if pos.kind_of?(String)
300
+ @attributes[pos]
301
+ else
302
+ @attributes.values[pos]
303
+ end
304
+ end
305
+
306
+ ## implementation of AttributeList
307
+ def getType(pos)
308
+ ## expat cannot get attribyte type
309
+ return "CDATA"
310
+ end
311
+
312
+ ## locator is DummyLoacator or SAXParser
313
+ def pushLocator(locator)
314
+ @locators.push(locator)
315
+ end
316
+
317
+ def popLocator
318
+ @locators.pop
319
+ end
320
+
321
+ ## implementation of Locator
322
+ def getPublicId
323
+ @locators[-1].getPublicId
324
+ end
325
+
326
+ ## implementation of Locator
327
+ def getSystemId
328
+ @locators[-1].getSystemId
329
+ end
330
+
331
+ ## implementation of Locator
332
+ def getLineNumber
333
+ @locators[-1].getLineNumber
334
+ end
335
+
336
+ ## implementation of Locator
337
+ def getColumnNumber
338
+ @locators[-1].getColumnNumber
339
+ end
340
+
341
+ ## implementation of Parser
342
+ def parse(sysid)
343
+ @documentHandler.setDocumentLocator(self)
344
+ if sysid.kind_of?(XML::SAX::InputSource)
345
+ inputSource = openInputStream(sysid.dup)
346
+ else
347
+ inputSource = openInputStream(XML::SAX::InputSource.new(sysid))
348
+ end
349
+ encoding = inputSource.getEncoding
350
+ if encoding
351
+ parser = SAXParser.new(self, encoding)
352
+ else
353
+ parser = SAXParser.new(self)
354
+ end
355
+
356
+ pushLocator(DummyLocator.new(inputSource.getSystemId))
357
+ begin
358
+ @documentHandler.startDocument
359
+ parser.parse(inputSource)
360
+ @documentHandler.endDocument
361
+ rescue XML::Parser::Error
362
+ @errorHandler.fatalError(XML::SAX::SAXParseException.new($!.to_s,
363
+ self))
364
+ rescue
365
+ @errorHandler.fatalError($!)
366
+ end
367
+ end
368
+ end
369
+ end
370
+ end
data/lib/xml/xpath.rb ADDED
@@ -0,0 +1,3284 @@
1
+ #
2
+ # xpath.rb: generated by racc (runtime embedded)
3
+ #
4
+
5
+ ###### racc/parser.rb
6
+
7
+ unless $".index 'racc/parser.rb' then
8
+ $".push 'racc/parser.rb'
9
+
10
+ type.module_eval <<'..end /home/katsu/local/lib/site_ruby/racc/parser.rb modeval..id92db944ac5', '/home/katsu/local/lib/site_ruby/racc/parser.rb', 1
11
+ #
12
+ # parser.rb
13
+ #
14
+ # Copyright (c) 1999,2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
15
+ #
16
+ # This program is free software.
17
+ # You can distribute/modify this program under the terms of
18
+ # the GNU Lesser General Public License version 2 or later.
19
+ #
20
+ # As a special exception, when this code is copied by Racc
21
+ # into a Racc output file, you may use that output file
22
+ # without restriction.
23
+ #
24
+
25
+ module Racc
26
+ class ParseError < StandardError; end
27
+ end
28
+ unless defined? ParseError then
29
+ ParseError = Racc::ParseError
30
+ end
31
+
32
+
33
+ module Racc
34
+
35
+ class Parser
36
+
37
+ private
38
+
39
+
40
+ begin
41
+ if defined? Racc_Debug_Ruby_Parser then
42
+ raise LoadError, 'debug ruby routine'
43
+ end
44
+ require 'racc/cparse'
45
+ unless new.respond_to? :_racc_do_parse_c, true then
46
+ raise LoadError, 'old cparse.so'
47
+ end
48
+ Racc_Main_Parsing_Routine = :_racc_do_parse_c
49
+ Racc_YY_Parse_Method = :_racc_yyparse_c
50
+ rescue LoadError
51
+ Racc_Main_Parsing_Routine = :_racc_do_parse_rb
52
+ Racc_YY_Parse_Method = :_racc_yyparse_rb
53
+ end
54
+
55
+ Racc_ruby_parser_version = '1.3.3'
56
+ Racc_parser_version = Racc_ruby_parser_version
57
+
58
+ def self.racc_runtime_type
59
+ if Racc_Main_Parsing_Routine == :_racc_do_parse_c then
60
+ 'c'
61
+ else
62
+ 'ruby'
63
+ end
64
+ end
65
+
66
+
67
+ def _racc_setup
68
+ t = self.type
69
+
70
+ unless t::Racc_debug_parser then
71
+ @yydebug = false
72
+ end
73
+ @yydebug = false unless defined? @yydebug
74
+
75
+ if @yydebug then
76
+ @racc_debug_out = $stderr unless defined? @racc_debug_out
77
+ @racc_debug_out ||= $stderr
78
+ end
79
+
80
+ arg = t::Racc_arg
81
+ if arg.size < 14 then
82
+ arg[13] = true
83
+ end
84
+ arg
85
+ end
86
+
87
+ def _racc_init_sysvars
88
+ @racc_state = [ 0 ]
89
+ @racc_tstack = []
90
+ @racc_vstack = []
91
+
92
+ @racc_t = nil
93
+ @racc_val = nil
94
+
95
+ @racc_read_next = true
96
+
97
+ @racc_user_yyerror = false
98
+ @racc_error_status = 0
99
+ end
100
+
101
+
102
+ ###
103
+ ### do_parse
104
+ ###
105
+
106
+ def do_parse
107
+ __send__ Racc_Main_Parsing_Routine, _racc_setup(), false
108
+ end
109
+
110
+ def next_token
111
+ raise NotImplementError, "#{self.type}\#next_token must be defined"
112
+ end
113
+
114
+ def _racc_do_parse_rb( arg, in_debug )
115
+ action_table, action_check, action_default, action_pointer,
116
+ goto_table, goto_check, goto_default, goto_pointer,
117
+ nt_base, reduce_table, token_table, shift_n,
118
+ reduce_n, use_result = arg
119
+
120
+ _racc_init_sysvars
121
+ act = i = nil
122
+ nerr = 0
123
+
124
+
125
+ catch( :racc_end_parse ) {
126
+ while true do
127
+
128
+ if i = action_pointer[ @racc_state[-1] ] then
129
+ if @racc_read_next then
130
+ if @racc_t != 0 then # $
131
+ tok, @racc_val = next_token()
132
+ @racc_t = (token_table[tok] or 1) # error token
133
+ racc_read_token( @racc_t, tok, @racc_val ) if @yydebug
134
+
135
+ @racc_read_next = false
136
+ end
137
+ end
138
+ i += @racc_t
139
+ if i >= 0 and act = action_table[i] and
140
+ action_check[i] == @racc_state[-1] then
141
+ ;
142
+ else
143
+ act = action_default[ @racc_state[-1] ]
144
+ end
145
+ else
146
+ act = action_default[ @racc_state[-1] ]
147
+ end
148
+
149
+ while act = _racc_evalact( act, arg ) do end
150
+
151
+ end
152
+ }
153
+ end
154
+
155
+
156
+ ###
157
+ ### yyparse
158
+ ###
159
+
160
+ def yyparse( recv, mid )
161
+ __send__ Racc_YY_Parse_Method, recv, mid, _racc_setup(), true
162
+ end
163
+
164
+ def _racc_yyparse_rb( recv, mid, arg, c_debug )
165
+ action_table, action_check, action_default, action_pointer,
166
+ goto_table, goto_check, goto_default, goto_pointer,
167
+ nt_base, reduce_table, token_table, shift_n,
168
+ reduce_n, use_result, = arg
169
+
170
+ _racc_init_sysvars
171
+ tok = nil
172
+ act = nil
173
+ i = nil
174
+ nerr = 0
175
+
176
+
177
+ catch( :racc_end_parse ) {
178
+ until i = action_pointer[ @racc_state[-1] ] do
179
+ while act = _racc_evalact(
180
+ action_default[ @racc_state[-1] ], arg ) do end
181
+ end
182
+
183
+ recv.__send__( mid ) do |tok, val|
184
+ # $stderr.puts "rd: tok=#{tok}, val=#{val}"
185
+ @racc_val = val
186
+ @racc_t = (token_table[tok] or 1) # error token
187
+ @racc_read_next = false
188
+
189
+ i += @racc_t
190
+ if i >= 0 and act = action_table[i] and
191
+ action_check[i] == @racc_state[-1] then
192
+ # $stderr.puts "01: act=#{act}"
193
+ else
194
+ act = action_default[ @racc_state[-1] ]
195
+ # $stderr.puts "02: act=#{act}"
196
+ # $stderr.puts "curstate=#{@racc_state[-1]}"
197
+ end
198
+
199
+ while act = _racc_evalact( act, arg ) do end
200
+
201
+ while not (i = action_pointer[ @racc_state[-1] ]) or
202
+ not @racc_read_next or
203
+ @racc_t == 0 do # $
204
+ if i and i += @racc_t and
205
+ i >= 0 and
206
+ act = action_table[i] and
207
+ action_check[i] == @racc_state[-1] then
208
+ # $stderr.puts "03: act=#{act}"
209
+ ;
210
+ else
211
+ # $stderr.puts "04: act=#{act}"
212
+ act = action_default[ @racc_state[-1] ]
213
+ end
214
+
215
+ while act = _racc_evalact( act, arg ) do end
216
+ end
217
+ end
218
+ }
219
+ end
220
+
221
+
222
+ ###
223
+ ### common
224
+ ###
225
+
226
+ def _racc_evalact( act, arg )
227
+ # $stderr.puts "ea: act=#{act}"
228
+ action_table, action_check, action_default, action_pointer,
229
+ goto_table, goto_check, goto_default, goto_pointer,
230
+ nt_base, reduce_table, token_table, shift_n,
231
+ reduce_n, use_result, = arg
232
+ nerr = 0 # tmp
233
+
234
+ if act > 0 and act < shift_n then
235
+ #
236
+ # shift
237
+ #
238
+
239
+ if @racc_error_status > 0 then
240
+ @racc_error_status -= 1 unless @racc_t == 1 # error token
241
+ end
242
+
243
+ @racc_vstack.push @racc_val
244
+ @racc_state.push act
245
+ @racc_read_next = true
246
+
247
+ if @yydebug then
248
+ @racc_tstack.push @racc_t
249
+ racc_shift( @racc_t, @racc_tstack, @racc_vstack )
250
+ end
251
+
252
+ elsif act < 0 and act > -reduce_n then
253
+ #
254
+ # reduce
255
+ #
256
+
257
+ code = catch( :racc_jump ) {
258
+ @racc_state.push _racc_do_reduce( arg, act )
259
+ false
260
+ }
261
+ if code then
262
+ case code
263
+ when 1 # yyerror
264
+ @racc_user_yyerror = true # user_yyerror
265
+ return -reduce_n
266
+ when 2 # yyaccept
267
+ return shift_n
268
+ else
269
+ raise RuntimeError, '[Racc Bug] unknown jump code'
270
+ end
271
+ end
272
+
273
+ elsif act == shift_n then
274
+ #
275
+ # accept
276
+ #
277
+
278
+ racc_accept if @yydebug
279
+ throw :racc_end_parse, @racc_vstack[0]
280
+
281
+ elsif act == -reduce_n then
282
+ #
283
+ # error
284
+ #
285
+
286
+ case @racc_error_status
287
+ when 0
288
+ unless arg[21] then # user_yyerror
289
+ nerr += 1
290
+ on_error @racc_t, @racc_val, @racc_vstack
291
+ end
292
+ when 3
293
+ if @racc_t == 0 then # is $
294
+ throw :racc_end_parse, nil
295
+ end
296
+ @racc_read_next = true
297
+ end
298
+ @racc_user_yyerror = false
299
+ @racc_error_status = 3
300
+
301
+ while true do
302
+ if i = action_pointer[ @racc_state[-1] ] then
303
+ i += 1 # error token
304
+ if i >= 0 and
305
+ (act = action_table[i]) and
306
+ action_check[i] == @racc_state[-1] then
307
+ break
308
+ end
309
+ end
310
+
311
+ throw :racc_end_parse, nil if @racc_state.size < 2
312
+ @racc_state.pop
313
+ @racc_vstack.pop
314
+ if @yydebug then
315
+ @racc_tstack.pop
316
+ racc_e_pop( @racc_state, @racc_tstack, @racc_vstack )
317
+ end
318
+ end
319
+
320
+ return act
321
+
322
+ else
323
+ raise RuntimeError, "[Racc Bug] unknown action #{act.inspect}"
324
+ end
325
+
326
+ racc_next_state( @racc_state[-1], @racc_state ) if @yydebug
327
+
328
+ nil
329
+ end
330
+
331
+ def _racc_do_reduce( arg, act )
332
+ action_table, action_check, action_default, action_pointer,
333
+ goto_table, goto_check, goto_default, goto_pointer,
334
+ nt_base, reduce_table, token_table, shift_n,
335
+ reduce_n, use_result, = arg
336
+ state = @racc_state
337
+ vstack = @racc_vstack
338
+ tstack = @racc_tstack
339
+
340
+ i = act * -3
341
+ len = reduce_table[i]
342
+ reduce_to = reduce_table[i+1]
343
+ method_id = reduce_table[i+2]
344
+ void_array = []
345
+
346
+ tmp_t = tstack[ -len, len ] if @yydebug
347
+ tmp_v = vstack[ -len, len ]
348
+ tstack[ -len, len ] = void_array if @yydebug
349
+ vstack[ -len, len ] = void_array
350
+ state[ -len, len ] = void_array
351
+
352
+ # tstack must be updated AFTER method call
353
+ if use_result then
354
+ vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
355
+ else
356
+ vstack.push __send__(method_id, tmp_v, vstack)
357
+ end
358
+ tstack.push reduce_to
359
+
360
+ racc_reduce( tmp_t, reduce_to, tstack, vstack ) if @yydebug
361
+
362
+ k1 = reduce_to - nt_base
363
+ if i = goto_pointer[ k1 ] then
364
+ i += state[-1]
365
+ if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1 then
366
+ return curstate
367
+ end
368
+ end
369
+ goto_default[ k1 ]
370
+ end
371
+
372
+ def on_error( t, val, vstack )
373
+ raise ParseError, "\nparse error on value #{val.inspect}"
374
+ end
375
+
376
+ def yyerror
377
+ throw :racc_jump, 1
378
+ end
379
+
380
+ def yyaccept
381
+ throw :racc_jump, 2
382
+ end
383
+
384
+ def yyerrok
385
+ @racc_error_status = 0
386
+ end
387
+
388
+
389
+ # for debugging output
390
+
391
+ def racc_read_token( t, tok, val )
392
+ @racc_debug_out.print 'read '
393
+ @racc_debug_out.print tok.inspect, '(internaly ', racc_token2str(t), ') '
394
+ @racc_debug_out.puts val.inspect
395
+ @racc_debug_out.puts
396
+ end
397
+
398
+ def racc_shift( tok, tstack, vstack )
399
+ @racc_debug_out.puts "shift #{racc_token2str tok}"
400
+ racc_print_stacks tstack, vstack
401
+ @racc_debug_out.puts
402
+ end
403
+
404
+ def racc_reduce( toks, sim, tstack, vstack )
405
+ out = @racc_debug_out
406
+ out.print 'reduce '
407
+ if toks.empty? then
408
+ out.print ' <none>'
409
+ else
410
+ toks.each {|t| out.print ' ', racc_token2str(t) }
411
+ end
412
+ out.puts " --> #{racc_token2str(sim)}"
413
+
414
+ racc_print_stacks tstack, vstack
415
+ @racc_debug_out.puts
416
+ end
417
+
418
+ def racc_accept
419
+ @racc_debug_out.puts 'accept'
420
+ @racc_debug_out.puts
421
+ end
422
+
423
+ def racc_e_pop( state, tstack, vstack )
424
+ @racc_debug_out.puts 'error recovering mode: pop token'
425
+ racc_print_states state
426
+ racc_print_stacks tstack, vstack
427
+ @racc_debug_out.puts
428
+ end
429
+
430
+ def racc_next_state( curstate, state )
431
+ @racc_debug_out.puts "goto #{curstate}"
432
+ racc_print_states state
433
+ @racc_debug_out.puts
434
+ end
435
+
436
+ def racc_print_stacks( t, v )
437
+ out = @racc_debug_out
438
+ out.print ' ['
439
+ t.each_index do |i|
440
+ out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
441
+ end
442
+ out.puts ' ]'
443
+ end
444
+
445
+ def racc_print_states( s )
446
+ out = @racc_debug_out
447
+ out.print ' ['
448
+ s.each {|st| out.print ' ', st }
449
+ out.puts ' ]'
450
+ end
451
+
452
+ def racc_token2str( tok )
453
+ type::Racc_token_to_s_table[tok] or
454
+ raise RuntimeError, "[Racc Bug] can't convert token #{tok} to string"
455
+ end
456
+
457
+ end
458
+
459
+ end
460
+ ..end /home/katsu/local/lib/site_ruby/racc/parser.rb modeval..id92db944ac5
461
+ end # end of racc/parser.rb
462
+
463
+
464
+ #
465
+ # xpath.rb : generated by racc
466
+ #
467
+
468
+ module XPath
469
+
470
+ class Error < StandardError ; end
471
+ class CompileError < Error ; end
472
+ class TypeError < Error ; end
473
+ class NameError < Error ; end
474
+ class ArgumentError < Error ; end
475
+ class InvalidOperation < Error ; end
476
+
477
+
478
+ class XPathProc
479
+
480
+ def initialize(proc, source)
481
+ @proc = proc
482
+ @source = source
483
+ end
484
+
485
+ attr_reader :source
486
+
487
+ def call(context)
488
+ @proc.call context
489
+ end
490
+
491
+ end
492
+
493
+
494
+ def self.compile(src, pattern = false)
495
+ @compiler = Compiler.new unless defined? @compiler
496
+ @compiler.compile src, pattern
497
+ end
498
+
499
+
500
+
501
+ module XPathObject
502
+
503
+ def _type
504
+ type.name.sub(/\A.*::(?:XPath)?(?=[^:]+\z)/, '')
505
+ end
506
+ private :_type
507
+
508
+ def type_error(into)
509
+ raise XPath::TypeError, "failed to convert #{_type} into #{into}"
510
+ end
511
+ private :type_error
512
+
513
+
514
+ def to_str # => to Ruby String
515
+ type_error 'String'
516
+ end
517
+
518
+ def to_f # => to Ruby Float
519
+ type_error 'Float'
520
+ end
521
+
522
+ def true? # => to Ruby Boolean
523
+ type_error 'Boolean'
524
+ end
525
+
526
+ def to_ruby # => to Ruby Object
527
+ self
528
+ end
529
+
530
+ def to_predicate # => to Ruby Float, true or false. shouldn't override.
531
+ true?
532
+ end
533
+
534
+
535
+ def to_string(context) # => to XPath String. shouldn't override.
536
+ context.make_string to_str
537
+ end
538
+
539
+ def to_number(context) # => to XPath Number. shouldn't override.
540
+ context.make_number to_f
541
+ end
542
+
543
+ def to_boolean(context) # => to XPath Boolean. shouldn't override.
544
+ context.make_boolean true?
545
+ end
546
+
547
+
548
+ public
549
+
550
+ # called from compiled XPath expression
551
+
552
+ def ==(other)
553
+ if other.is_a? XPathNodeSet or
554
+ other.is_a? XPathBoolean or other.is_a? XPathNumber then
555
+ other == self
556
+ else
557
+ to_str == other.to_str
558
+ end
559
+ end
560
+
561
+ def <(other)
562
+ if other.is_a? XPathNodeSet then
563
+ other > self
564
+ else
565
+ to_f < other.to_f
566
+ end
567
+ end
568
+
569
+ def >(other)
570
+ if other.is_a? XPathNodeSet then
571
+ other < self
572
+ else
573
+ to_f > other.to_f
574
+ end
575
+ end
576
+
577
+ def <=(other)
578
+ if other.is_a? XPathNodeSet then
579
+ other >= self
580
+ else
581
+ to_f <= other.to_f
582
+ end
583
+ end
584
+
585
+ def >=(other)
586
+ if other.is_a? XPathNodeSet then
587
+ other <= self
588
+ else
589
+ to_f >= other.to_f
590
+ end
591
+ end
592
+
593
+ def **(other)
594
+ type_error 'NodeSet'
595
+ end
596
+
597
+ def predicate(&block)
598
+ type_error 'NodeSet'
599
+ end
600
+
601
+ def at(pos)
602
+ type_error 'NodeSet'
603
+ end
604
+
605
+ def funcall(name) # for XPointer
606
+ raise XPath::NameError, "undefined function `#{name}' for #{_type}"
607
+ end
608
+
609
+ end
610
+
611
+
612
+
613
+
614
+ class XPathBoolean
615
+
616
+ include XPathObject
617
+
618
+ class << self
619
+ attr_reader :instance
620
+ private :new
621
+ end
622
+
623
+ def to_str
624
+ true?.to_s
625
+ end
626
+
627
+ # def to_f
628
+ # def true?
629
+
630
+ def to_ruby
631
+ true?
632
+ end
633
+
634
+ def to_boolean(context)
635
+ self
636
+ end
637
+
638
+ def ==(other)
639
+ true? == other.true?
640
+ end
641
+
642
+ end
643
+
644
+
645
+ class XPathTrueClass < XPathBoolean
646
+
647
+ @instance = new
648
+
649
+ def to_f
650
+ 1.0
651
+ end
652
+
653
+ def true?
654
+ true
655
+ end
656
+
657
+ end
658
+
659
+
660
+ class XPathFalseClass < XPathBoolean
661
+
662
+ @instance = new
663
+
664
+ def to_f
665
+ 0.0
666
+ end
667
+
668
+ def true?
669
+ false
670
+ end
671
+
672
+ end
673
+
674
+
675
+ XPathTrue = XPathTrueClass.instance
676
+ XPathFalse = XPathFalseClass.instance
677
+
678
+
679
+
680
+
681
+ class XPathNumber
682
+
683
+ include XPathObject
684
+
685
+ def initialize(num)
686
+ raise ::TypeError, "must be a Float" unless num.is_a? Float
687
+ @value = num
688
+ end
689
+
690
+ def to_str
691
+ if @value.nan? then
692
+ 'NaN'
693
+ elsif @value.infinite? then
694
+ if @value < 0 then
695
+ '-Infinity'
696
+ else
697
+ 'Infinity'
698
+ end
699
+ else
700
+ sprintf("%.100f", @value).gsub(/\.?0+\z/, '') # enough?
701
+ end
702
+ end
703
+
704
+ def to_f
705
+ @value
706
+ end
707
+
708
+ def true?
709
+ @value != 0.0 and not @value.nan?
710
+ end
711
+
712
+ def to_ruby
713
+ to_f
714
+ end
715
+
716
+ def to_predicate
717
+ to_f
718
+ end
719
+
720
+ def to_number(context)
721
+ self
722
+ end
723
+
724
+
725
+ def ==(other)
726
+ if other.is_a? XPathNodeSet or other.is_a? XPathBoolean then
727
+ other == self
728
+ else
729
+ @value == other.to_f
730
+ end
731
+ end
732
+
733
+ def +(other)
734
+ @value += other.to_f
735
+ self
736
+ end
737
+
738
+ def -(other)
739
+ @value -= other.to_f
740
+ self
741
+ end
742
+
743
+ def *(other)
744
+ @value *= other.to_f
745
+ self
746
+ end
747
+
748
+ def /(other)
749
+ @value /= other.to_f
750
+ self
751
+ end
752
+
753
+ def %(other)
754
+ n = other.to_f
755
+ f = @value % n
756
+ f = -f if @value < 0
757
+ f = -f if n < 0
758
+ @value = f
759
+ self
760
+ end
761
+
762
+ def -@
763
+ @value = -@value
764
+ self
765
+ end
766
+
767
+ def floor
768
+ @value = @value.floor.to_f
769
+ self
770
+ end
771
+
772
+ def ceil
773
+ @value = @value.ceil.to_f
774
+ self
775
+ end
776
+
777
+ def round
778
+ f = @value
779
+ unless f.nan? or f.infinite? then
780
+ if f >= 0.0 then
781
+ @value = f.round.to_f
782
+ elsif f - f.truncate >= -0.5 then
783
+ @value = f.ceil.to_f
784
+ else
785
+ @value = f.floor.to_f
786
+ end
787
+ end
788
+ self
789
+ end
790
+
791
+ end
792
+
793
+
794
+
795
+
796
+ class XPathString
797
+
798
+ include XPathObject
799
+
800
+ def initialize(str)
801
+ raise ::TypeError, "must be a String" unless str.is_a? String
802
+ @value = str
803
+ end
804
+
805
+ def to_str
806
+ @value
807
+ end
808
+
809
+ def to_f
810
+ if /\A\s*(-?\d+\.?\d*)(?:\s|\z)/ =~ @value then
811
+ $1.to_f
812
+ else
813
+ 0.0 / 0.0 # NaN
814
+ end
815
+ end
816
+
817
+ def true?
818
+ not @value.empty?
819
+ end
820
+
821
+ def to_ruby
822
+ to_str
823
+ end
824
+
825
+ def to_string(context)
826
+ self
827
+ end
828
+
829
+
830
+ def concat(s)
831
+ @value = @value + s
832
+ self
833
+ end
834
+
835
+ def start_with?(s)
836
+ /\A#{Regexp.quote(s)}/ =~ @value
837
+ end
838
+
839
+ def contain?(s)
840
+ /#{Regexp.quote(s)}/ =~ @value
841
+ end
842
+
843
+ def substring_before(s)
844
+ if /#{Regexp.quote(s)}/ =~ @value then
845
+ @value = $`
846
+ else
847
+ @value = ''
848
+ end
849
+ self
850
+ end
851
+
852
+ def substring_after(s)
853
+ if /#{Regexp.quote(s)}/ =~ @value then
854
+ @value = $'
855
+ else
856
+ @value = ''
857
+ end
858
+ self
859
+ end
860
+
861
+ def substring(start, len)
862
+ start = start.round.to_f
863
+ if start.infinite? or start.nan? then
864
+ @value = ''
865
+ elsif len then
866
+ len = len.round.to_f
867
+ maxlen = start + len
868
+ len = maxlen - 1.0 if len >= maxlen
869
+ if start <= 1.0 then
870
+ start = 0
871
+ else
872
+ start = start.to_i - 1
873
+ end
874
+ if len.nan? or len < 1.0 then
875
+ @value = ''
876
+ elsif len.infinite? then
877
+ # @value = @value[start..-1]
878
+ /\A[\W\w]{0,#{start}}/ =~ @value
879
+ @value = $'
880
+ else
881
+ # @value = @value[start, len.to_i]
882
+ /\A[\W\w]{0,#{start}}([\W\w]{0,#{len.to_i}})/ =~ @value
883
+ @value = $1
884
+ end
885
+ elsif start > 1.0 then
886
+ # @value = @value[(start-1)..-1]
887
+ /\A[\W\w]{0,#{start.to_i-1}}/ =~ @value
888
+ @value = $'
889
+ end
890
+ raise "BUG" unless @value
891
+ self
892
+ end
893
+
894
+ def size
895
+ @value.gsub(/[^\Wa-zA-Z_\d]/, ' ').size
896
+ end
897
+
898
+ def normalize_space
899
+ @value = @value.strip
900
+ @value.gsub!(/\s+/, ' ')
901
+ self
902
+ end
903
+
904
+ def translate(from, to)
905
+ to = to.split(//)
906
+ h = {}
907
+ from.split(//).each_with_index { |i,n|
908
+ h[i] = to[n] unless h.key? i
909
+ }
910
+ @value = @value.gsub(/[#{Regexp.quote(h.keys.join)}]/) { |s| h[s] }
911
+ self
912
+ end
913
+
914
+ def replace(str)
915
+ @value = str
916
+ self
917
+ end
918
+
919
+ end
920
+
921
+
922
+
923
+
924
+
925
+ class Compiler < Racc::Parser
926
+
927
+ module_eval <<'..end xpath.ry modeval..idcc62899492', 'xpath.ry', 268
928
+
929
+ module CompilePhaseObject
930
+
931
+ def invoke_conv(expr, conv_method)
932
+ return unless conv_method
933
+ if conv_method == '.to_number' or
934
+ conv_method == '.to_string' or
935
+ conv_method == '.to_boolean' then
936
+ expr.push conv_method, '(', nil, ')'
937
+ else
938
+ expr.push conv_method
939
+ end
940
+ end
941
+ private :invoke_conv
942
+
943
+ end
944
+
945
+
946
+ module ConstantObject
947
+
948
+ include CompilePhaseObject
949
+
950
+ def to_string
951
+ StringConstant.new to_str
952
+ end
953
+
954
+ def to_number
955
+ NumberConstant.new self
956
+ end
957
+
958
+ def to_boolean
959
+ if true? then
960
+ ConstantTrue
961
+ else
962
+ ConstantFalse
963
+ end
964
+ end
965
+
966
+ end
967
+
968
+
969
+ module BooleanConstant
970
+
971
+ include ConstantObject
972
+
973
+ def value_type
974
+ :boolean
975
+ end
976
+
977
+ def expr(conv_method = nil)
978
+ if conv_method == '.to_ruby' or conv_method == '.true?' then
979
+ [ true?.to_s ]
980
+ else
981
+ ret = [ nil, '.make_boolean(', true?.to_s, ')' ]
982
+ invoke_conv ret, conv_method unless conv_method == '.to_boolean'
983
+ ret
984
+ end
985
+ end
986
+
987
+ end
988
+
989
+ class ConstantTrueClass < XPathTrueClass
990
+ include BooleanConstant
991
+ @instance = new
992
+ end
993
+
994
+ class ConstantFalseClass < XPathFalseClass
995
+ include BooleanConstant
996
+ @instance = new
997
+ end
998
+
999
+ ConstantTrue = ConstantTrueClass.instance
1000
+ ConstantFalse = ConstantFalseClass.instance
1001
+
1002
+
1003
+
1004
+ class NumberConstant < XPathNumber
1005
+
1006
+ include ConstantObject
1007
+
1008
+ def value_type
1009
+ :number
1010
+ end
1011
+
1012
+ def initialize(src)
1013
+ f = src.to_f
1014
+ if src.is_a? ConstantObject and s = dump_float(f) then
1015
+ src = s
1016
+ end
1017
+ @src = [ src ]
1018
+ @precedence = 1
1019
+ super f
1020
+ end
1021
+
1022
+ attr_reader :precedence
1023
+ protected :precedence
1024
+
1025
+ def to_number
1026
+ self
1027
+ end
1028
+
1029
+
1030
+ def expr(conv_method = nil)
1031
+ @src.collect! { |i|
1032
+ if i.is_a? ConstantObject then
1033
+ i.expr '.to_f'
1034
+ else
1035
+ i
1036
+ end
1037
+ }
1038
+ expr = @src
1039
+ expr.flatten!
1040
+ @src = :draff # for debug
1041
+ unless conv_method == '.to_ruby' or conv_method == '.to_f' then
1042
+ expr[0, 0] = [ nil, '.make_number(' ]
1043
+ expr.push(')')
1044
+ invoke_conv expr, conv_method unless conv_method == '.to_number'
1045
+ end
1046
+ expr
1047
+ end
1048
+
1049
+
1050
+ private
1051
+
1052
+ def dump_float(f)
1053
+ if f.finite? and f == eval(s = f.to_s) then
1054
+ s
1055
+ elsif f.infinite? then
1056
+ if f > 0 then
1057
+ '(1.0 / 0.0)'
1058
+ else
1059
+ '(-1.0 / 0.0)'
1060
+ end
1061
+ elsif f.nan? then
1062
+ '(0.0 / 0.0)'
1063
+ else
1064
+ nil
1065
+ end
1066
+ end
1067
+
1068
+
1069
+ def concat(op, other, prec)
1070
+ @src.unshift('(').push(')') if @precedence < prec
1071
+ if other.precedence < prec then
1072
+ @src.push(op).push('(').concat(other.expr('.to_f')).push(')')
1073
+ else
1074
+ @src.push(op).concat(other.expr('.to_f'))
1075
+ end
1076
+ @precedence = prec
1077
+ end
1078
+
1079
+
1080
+ public
1081
+
1082
+ def self.def_arithmetic_operator(op, precedence)
1083
+ module_eval <<_, __FILE__, __LINE__ + 1
1084
+ def #{op}(other)
1085
+ super other
1086
+ if s = dump_float(@value) then
1087
+ @src.clear
1088
+ @src.push s
1089
+ else
1090
+ concat ' #{op} ', other, #{precedence}
1091
+ end
1092
+ self
1093
+ end
1094
+ _
1095
+ end
1096
+
1097
+ def_arithmetic_operator '+', 0
1098
+ def_arithmetic_operator '-', 0
1099
+ def_arithmetic_operator '*', 1
1100
+ def_arithmetic_operator '/', 1
1101
+
1102
+ class << self
1103
+ undef def_arithmetic_operator
1104
+ end
1105
+
1106
+ def %(other)
1107
+ orig = @value
1108
+ super other
1109
+ if s = dump_float(@value) then
1110
+ @src.clear
1111
+ @src.push s
1112
+ else
1113
+ f = other.to_f
1114
+ other = -other if orig % f == -@value
1115
+ concat ' % ', other, 1
1116
+ end
1117
+ self
1118
+ end
1119
+
1120
+ def -@
1121
+ super
1122
+ if s = dump_float(@value) then
1123
+ @src.clear
1124
+ @src.push s
1125
+ else
1126
+ if @src.size == 1 then
1127
+ @src.unshift '-'
1128
+ else
1129
+ @src.unshift('-(').push(')')
1130
+ end
1131
+ @precedence = 1
1132
+ end
1133
+ self
1134
+ end
1135
+
1136
+ end
1137
+
1138
+
1139
+
1140
+ class StringConstant < XPathString
1141
+
1142
+ include ConstantObject
1143
+
1144
+ def value_type
1145
+ :string
1146
+ end
1147
+
1148
+ def to_string
1149
+ self
1150
+ end
1151
+
1152
+ def expr(conv_method = nil)
1153
+ if conv_method == '.to_ruby' or conv_method == '.to_str' then
1154
+ [ @value.dump ]
1155
+ else
1156
+ ret = [ nil, '.make_string(', @value.dump, ')' ]
1157
+ invoke_conv ret, conv_method unless conv_method == '.to_string'
1158
+ ret
1159
+ end
1160
+ end
1161
+
1162
+ end
1163
+
1164
+
1165
+
1166
+ class Expression
1167
+
1168
+ include CompilePhaseObject
1169
+
1170
+ def initialize(expr)
1171
+ if expr.is_a? ConstantObject then
1172
+ @value = expr
1173
+ else
1174
+ raise "BUG" unless expr.is_a? Array
1175
+ @value = nil
1176
+ @valuetype = nil
1177
+ @expr = expr
1178
+ end
1179
+ @unary = true
1180
+ end
1181
+
1182
+ attr_reader :value
1183
+
1184
+
1185
+ def value_type
1186
+ if @value then
1187
+ @value.value_type
1188
+ else
1189
+ @valuetype
1190
+ end
1191
+ end
1192
+
1193
+
1194
+ def unarize
1195
+ unless @unary then
1196
+ @expr.unshift('(').push(')')
1197
+ @unary = true
1198
+ end
1199
+ self
1200
+ end
1201
+
1202
+
1203
+ def self.def_comparison_operator(name, op)
1204
+ module_eval <<_, __FILE__, __LINE__ + 1
1205
+ def #{name}(other)
1206
+ if @value and other.value then
1207
+ if @value #{op} other.value then
1208
+ @value = ConstantTrue
1209
+ else
1210
+ @value = ConstantFalse
1211
+ end
1212
+ @unary = true
1213
+ else
1214
+ @expr = expr.push(' #{op} ').concat(other.expr)
1215
+ @valuetype = :ruby_boolean
1216
+ @unary = false
1217
+ end
1218
+ self
1219
+ end
1220
+ _
1221
+ end
1222
+
1223
+ def self.def_arithmetic_operator(*ops)
1224
+ ops.each { |op|
1225
+ module_eval <<_, __FILE__, __LINE__ + 1
1226
+ def #{op}(other)
1227
+ if @value and other.value then
1228
+ @value = @value.to_number #{op} other.value.to_number
1229
+ else
1230
+ @expr = expr('.to_number').push(' #{op} ')
1231
+ # not 'to_number', for a little speed up :-)
1232
+ @expr.concat other.expr('.to_f')
1233
+ @valuetype = :number
1234
+ @unary = false
1235
+ end
1236
+ self
1237
+ end
1238
+ _
1239
+ }
1240
+ end
1241
+
1242
+ def_comparison_operator 'eq', '=='
1243
+ def_comparison_operator 'neq', '!='
1244
+ def_comparison_operator 'lt', '<'
1245
+ def_comparison_operator 'gt', '>'
1246
+ def_comparison_operator 'le', '<='
1247
+ def_comparison_operator 'ge', '>='
1248
+ def_arithmetic_operator '+', '-', '*', '/', '%'
1249
+
1250
+ class << self
1251
+ undef def_comparison_operator
1252
+ undef def_arithmetic_operator
1253
+ end
1254
+
1255
+ def -@
1256
+ if @value then
1257
+ @value = -@value.to_number
1258
+ else
1259
+ unarize
1260
+ @expr = expr('.to_number').unshift('-')
1261
+ end
1262
+ self
1263
+ end
1264
+
1265
+ def logical_or(other)
1266
+ if @value and @value.true? then
1267
+ @value = ConstantTrue
1268
+ @unary = true
1269
+ @expr = @valuetype = nil
1270
+ else
1271
+ @expr = expr('.true?').push(' || ').concat(other.expr('.true?'))
1272
+ @valuetype = :ruby_boolean
1273
+ @unary = false
1274
+ end
1275
+ self
1276
+ end
1277
+
1278
+ def logical_and(other)
1279
+ if @value and not @value.true? then
1280
+ @value = ConstantFalse
1281
+ @unary = true
1282
+ @expr = @valuetype = nil
1283
+ else
1284
+ @expr = expr('.true?').push(' && ').concat(other.expr('.true?'))
1285
+ @valuetype = :ruby_boolean
1286
+ @unary = false
1287
+ end
1288
+ self
1289
+ end
1290
+
1291
+ def **(other)
1292
+ @expr = expr.push(' ** ').concat(other.expr)
1293
+ @valuetype = nil
1294
+ @unary = false
1295
+ self
1296
+ end
1297
+
1298
+
1299
+ def add_predicate(pred)
1300
+ unarize
1301
+ @expr = expr.concat(pred)
1302
+ @valuetype = nil
1303
+ self
1304
+ end
1305
+
1306
+ def <<(other)
1307
+ path = other.expr
1308
+ path.shift # nil
1309
+ path.shift # .to_nodeset
1310
+ add_predicate path
1311
+ end
1312
+
1313
+ def add_step(axis)
1314
+ add_predicate [ ".step(:#{axis.tr('-','_')})" ]
1315
+ end
1316
+
1317
+
1318
+ def expr(conv_method = nil)
1319
+ if @value then
1320
+ ret = @value.expr(conv_method)
1321
+ @value = nil
1322
+ elsif @valuetype == :ruby_boolean then
1323
+ ret = @expr
1324
+ unless conv_method == '.to_ruby' or conv_method == '.true?' then
1325
+ ret[0, 0] = [ nil, '.make_boolean(' ]
1326
+ ret.push ')'
1327
+ invoke_conv ret, conv_method unless conv_method == '.to_boolean'
1328
+ end
1329
+ elsif @valuetype == :number and conv_method == '.to_number' then
1330
+ ret = @expr
1331
+ elsif @valuetype == :string and conv_method == '.to_string' then
1332
+ ret = @expr
1333
+ elsif @valuetype == :boolean and conv_method == '.to_boolean' then
1334
+ ret = @expr
1335
+ else
1336
+ if conv_method then
1337
+ unarize
1338
+ invoke_conv @expr, conv_method
1339
+ end
1340
+ ret = @expr
1341
+ end
1342
+ @expr = :draff # for debug
1343
+ ret
1344
+ end
1345
+
1346
+ end
1347
+
1348
+
1349
+
1350
+ class LocationPath
1351
+
1352
+ include CompilePhaseObject
1353
+
1354
+ def initialize
1355
+ @root = false
1356
+ @steps = [] # [ axis, [ tests ], predicates ]
1357
+ end
1358
+
1359
+ attr_reader :root, :steps
1360
+ protected :root, :steps
1361
+
1362
+ def absolute!
1363
+ @root = true
1364
+ self
1365
+ end
1366
+
1367
+
1368
+ def add_step(axis, nodetype = false, localpart = false,
1369
+ namespace = false, predicate = nil)
1370
+ if nodetype == false and localpart == false and namespace == false then
1371
+ append_step axis, [], predicate
1372
+ else
1373
+ append_step axis, [ [ nodetype, localpart, namespace ] ], predicate
1374
+ end
1375
+ self
1376
+ end
1377
+
1378
+
1379
+ def <<(other)
1380
+ raise "BUG" if other.root
1381
+ other = other.steps
1382
+ other.each { |step|
1383
+ if step[0] then
1384
+ append_step(*step)
1385
+ else
1386
+ add_predicate(step[2])
1387
+ end
1388
+ }
1389
+ self
1390
+ end
1391
+
1392
+
1393
+ def add_predicate(pred)
1394
+ @steps.push [ nil, nil, pred ]
1395
+ self
1396
+ end
1397
+
1398
+
1399
+ def **(other)
1400
+ unless other.is_a? LocationPath then
1401
+ ret = nil
1402
+ else
1403
+ othersteps = other.steps
1404
+ size = @steps.size
1405
+ unless size == othersteps.size then
1406
+ othersize = othersteps.size
1407
+ if size >= othersize then
1408
+ ret = (@steps[0, othersize] == othersize and self)
1409
+ else
1410
+ ret = (othersteps[0, size] == @steps and other)
1411
+ end
1412
+ else
1413
+ last = @steps.pop
1414
+ otherlast = othersteps.pop
1415
+ if @steps == othersteps and mix_step(last, otherlast) then
1416
+ ret = self
1417
+ else
1418
+ ret = nil
1419
+ end
1420
+ @steps.push last
1421
+ othersteps.push otherlast
1422
+ end
1423
+ end
1424
+ ret or Expression.new(expr) ** other
1425
+ end
1426
+
1427
+
1428
+ private
1429
+
1430
+ UnifiableAxes = {
1431
+ 'descendant' => {
1432
+ 'descendant-or-self' => 'descendant',
1433
+ },
1434
+ 'descendant-or-self' => {
1435
+ 'child' => 'descendant',
1436
+ 'descendant' => 'descendant',
1437
+ 'descendant-or-self' => 'descendant-or-self',
1438
+ },
1439
+ 'ancestor' => {
1440
+ 'ancestor-or-self' => 'ancestor',
1441
+ },
1442
+ 'ancestor-or-self' => {
1443
+ 'parent' => 'ancestor',
1444
+ 'ancestor' => 'ancestor',
1445
+ 'ancestor-or-self' => 'ancestor-or-self',
1446
+ },
1447
+ 'following-sibling' => {
1448
+ 'following-sibling' => 'following-sibling',
1449
+ },
1450
+ 'preceding-sibling' => {
1451
+ 'preceding-sibling' => 'preceding-sibling',
1452
+ },
1453
+ 'following' => {
1454
+ 'following' => 'following',
1455
+ 'following-sibling' => 'following',
1456
+ },
1457
+ 'preceding' => {
1458
+ 'preceding' => 'preceding',
1459
+ 'preceding-sibling' => 'preceding',
1460
+ },
1461
+ 'child' => {
1462
+ 'following-sibling' => 'child',
1463
+ 'preceding-sibling' => 'child',
1464
+ },
1465
+ }
1466
+ UnifiableAxes.default = {}
1467
+
1468
+
1469
+ def append_step(axis, test, predicate)
1470
+ lastaxis, lasttest, lastpred = laststep = @steps.last
1471
+ if axis == 'self' and test.empty? then
1472
+ @steps.push [ nil, nil, predicate ] if predicate
1473
+ elsif lastaxis and lasttest.empty? and
1474
+ not lastpred and not predicate and
1475
+ w = UnifiableAxes[lastaxis][axis] then
1476
+ laststep[0] = w
1477
+ laststep[1] = test
1478
+ else
1479
+ @steps.push [ axis, test, predicate ]
1480
+ end
1481
+ end
1482
+
1483
+
1484
+ def mix_step(step, other)
1485
+ if step[0] and step[0] == other[0] and step[2] == other[2] then
1486
+ step[1].concat other[1]
1487
+ step
1488
+ else
1489
+ nil
1490
+ end
1491
+ end
1492
+
1493
+
1494
+ public
1495
+
1496
+ def expr(conv_method = nil)
1497
+ if @root then
1498
+ expr = [ nil, '.root_nodeset' ]
1499
+ else
1500
+ expr = [ nil, '.to_nodeset' ]
1501
+ end
1502
+ @steps.each { |axis,test,predicate|
1503
+ if axis.nil? then # predicate only
1504
+ expr.concat predicate
1505
+ elsif test.empty? and not predicate then
1506
+ expr.push ".select_all(:#{axis.tr('-','_')})"
1507
+ else
1508
+ expr.push ".step(:#{axis.tr('-','_')})"
1509
+ if test.empty? then
1510
+ expr.push ' { |n| n.select_all'
1511
+ else
1512
+ expr.push ' { |n| n.select { |i| '
1513
+ test.each { |nodetype,localpart,namespace|
1514
+ if nodetype then
1515
+ expr.push "i.node_type == :#{nodetype.tr('-','_')}", ' && '
1516
+ end
1517
+ if localpart then
1518
+ expr.push "i.name_localpart == #{localpart.dump}", ' && '
1519
+ end
1520
+ if namespace.nil? then
1521
+ expr.push 'i.namespace_uri.nil?', ' && '
1522
+ elsif namespace then
1523
+ namespace = namespace.dump
1524
+ expr.push('i.namespace_uri == ', nil,
1525
+ ".get_namespace(#{namespace})", ' && ')
1526
+ end
1527
+ expr[-1] = ' or '
1528
+ }
1529
+ expr[-1] = ' }'
1530
+ end
1531
+ expr.concat predicate if predicate
1532
+ expr.push ' }'
1533
+ end
1534
+ }
1535
+ @steps = :draff # for debug
1536
+ invoke_conv expr, conv_method
1537
+ expr
1538
+ end
1539
+
1540
+
1541
+ def value_type
1542
+ nil
1543
+ end
1544
+
1545
+ def value
1546
+ nil
1547
+ end
1548
+
1549
+ def unarize
1550
+ self
1551
+ end
1552
+
1553
+ def self.redirect_to_expr(*ops)
1554
+ ops.each { |op|
1555
+ name = op
1556
+ name = op[1..-1] if op[0] == ?.
1557
+ module_eval <<_, __FILE__, __LINE__ + 1
1558
+ def #{name}(arg) ; Expression.new(expr) #{op} arg ; end
1559
+ _
1560
+ }
1561
+ end
1562
+
1563
+ redirect_to_expr('.eq', '.neq', '.lt', '.gt', '.le', '.ge',
1564
+ '+', '-', '*', '/', '%', '.logical_or', '.logical_and')
1565
+
1566
+ class << self
1567
+ undef redirect_to_expr
1568
+ end
1569
+
1570
+ def -@
1571
+ -Expression.new(expr)
1572
+ end
1573
+
1574
+ end
1575
+
1576
+
1577
+
1578
+
1579
+ Delim = '\\s\\(\\)\\[\\]\\.@,\\/\\|\\*\\+"\'=!<>:'
1580
+ Name = "[^-#{Delim}][^#{Delim}]*"
1581
+
1582
+ Operator = {
1583
+ '@' => true, '::' => true, '(' => true, '[' => true,
1584
+ :MUL => true, 'and' => true, 'or' => true, 'mod' => true, 'div' => true,
1585
+ '/' => true, '//' => true, '|' => true, '+' => true,
1586
+ '-' => true, '=' => true, '!=' => true, '<' => true,
1587
+ '<=' => true, '>' => true, '>=' => true,
1588
+ ':' => false
1589
+ # ':' '*' => '*' must not be a MultiplyOperator
1590
+ # ':' 'and' => 'and' must be a OperatorName
1591
+ }
1592
+
1593
+ NodeType = {
1594
+ 'comment' => true,
1595
+ 'text' => true,
1596
+ 'processing-instruction' => true,
1597
+ 'node' => true,
1598
+ }
1599
+
1600
+
1601
+ private
1602
+
1603
+ def axis?(s)
1604
+ /\A[-a-zA-Z]+\z/ =~ s
1605
+ end
1606
+
1607
+ def nodetype?(s)
1608
+ NodeType.key? s
1609
+ end
1610
+
1611
+ def tokenize(src)
1612
+ token = []
1613
+ src.scan(/(\.\.?|\/\/?|::?|!=|[<>]=?|[-()\[\].@,|+=*])|
1614
+ ("[^"]*"|'[^']*')|(\d+\.?\d*)|
1615
+ (\$?#{Name}(?::#{Name})?)|
1616
+ \s+|./ox) { |delim,literal,number,name| #/
1617
+ if delim then
1618
+ if delim == '*' then
1619
+ delim = :MUL if (prev = token[-1]) and not Operator.key? prev[0]
1620
+ elsif delim == '::' then
1621
+ prev = token[-1]
1622
+ if prev and prev[0] == :Name and axis? prev[1] then
1623
+ prev[0] = :AxisName
1624
+ end
1625
+ elsif delim == '(' then
1626
+ if (prev = token[-1]) and prev[0] == :Name then
1627
+ if nodetype? prev[1] then
1628
+ prev[0] = :NodeType
1629
+ else
1630
+ prev[0] = :FuncName
1631
+ end
1632
+ end
1633
+ end
1634
+ token.push [ delim, delim ]
1635
+ elsif name then
1636
+ prev = token[-1]
1637
+ if name[0] == ?$ then
1638
+ name[0,1] = ''
1639
+ token.push [ :Variable, name ]
1640
+ elsif Operator.key? name and
1641
+ (prev = token[-1]) and not Operator[prev[0]] then
1642
+ token.push [ name, name ]
1643
+ else
1644
+ token.push [ :Name, name ]
1645
+ end
1646
+ elsif number then
1647
+ number << '.0' unless number.include? ?.
1648
+ token.push [ :Number, number ]
1649
+ elsif literal then
1650
+ literal.chop!
1651
+ literal[0,1] = ''
1652
+ token.push [ :Literal, literal ]
1653
+ else
1654
+ s = $&.strip
1655
+ token.push [ s, s ] unless s.empty?
1656
+ end
1657
+ }
1658
+ token
1659
+ end
1660
+
1661
+
1662
+ public
1663
+
1664
+ def compile(src, pattern = false)
1665
+ @token = tokenize(src)
1666
+ @token.push [ false, :end ]
1667
+ @token.each { |i| p i } if @yydebug
1668
+ @token.reverse!
1669
+ @token.push [ :PATTERN, nil ] if pattern
1670
+ @context = 'context0'
1671
+ ret = do_parse
1672
+ ret = ret.unshift("proc { |context0| ").push(" }").join
1673
+ print ">>>>\n", ret, "\n<<<<\n" if @yydebug
1674
+ XPathProc.new eval(ret), src
1675
+ end
1676
+
1677
+
1678
+ def initialize(debug = false)
1679
+ super()
1680
+ @yydebug = debug
1681
+ end
1682
+
1683
+
1684
+ private
1685
+
1686
+ def next_token
1687
+ @token.pop
1688
+ end
1689
+
1690
+
1691
+ def is_xpointer?
1692
+ false
1693
+ end
1694
+
1695
+
1696
+ def on_error(*args) # tok, val, values
1697
+ raise CompileError, 'parse error'
1698
+ end
1699
+
1700
+
1701
+ ..end xpath.ry modeval..idcc62899492
1702
+
1703
+ ##### racc 1.3.3 generates ###
1704
+
1705
+ racc_reduce_table = [
1706
+ 0, 0, :racc_error,
1707
+ 0, 39, :_reduce_1,
1708
+ 1, 39, :_reduce_2,
1709
+ 2, 39, :_reduce_3,
1710
+ 1, 41, :_reduce_none,
1711
+ 3, 41, :_reduce_5,
1712
+ 3, 40, :_reduce_6,
1713
+ 3, 40, :_reduce_7,
1714
+ 3, 40, :_reduce_8,
1715
+ 3, 40, :_reduce_9,
1716
+ 3, 40, :_reduce_10,
1717
+ 3, 40, :_reduce_11,
1718
+ 3, 40, :_reduce_12,
1719
+ 3, 40, :_reduce_13,
1720
+ 3, 40, :_reduce_14,
1721
+ 3, 40, :_reduce_15,
1722
+ 2, 40, :_reduce_16,
1723
+ 3, 40, :_reduce_17,
1724
+ 3, 40, :_reduce_18,
1725
+ 3, 40, :_reduce_19,
1726
+ 3, 40, :_reduce_20,
1727
+ 1, 40, :_reduce_none,
1728
+ 1, 40, :_reduce_none,
1729
+ 3, 40, :_reduce_23,
1730
+ 3, 40, :_reduce_24,
1731
+ 1, 43, :_reduce_25,
1732
+ 3, 43, :_reduce_26,
1733
+ 1, 43, :_reduce_27,
1734
+ 1, 43, :_reduce_28,
1735
+ 1, 43, :_reduce_29,
1736
+ 2, 43, :_reduce_30,
1737
+ 4, 45, :_reduce_31,
1738
+ 0, 47, :_reduce_32,
1739
+ 1, 47, :_reduce_33,
1740
+ 3, 47, :_reduce_34,
1741
+ 0, 48, :_reduce_35,
1742
+ 0, 49, :_reduce_36,
1743
+ 5, 46, :_reduce_37,
1744
+ 1, 42, :_reduce_38,
1745
+ 2, 42, :_reduce_39,
1746
+ 2, 42, :_reduce_40,
1747
+ 1, 42, :_reduce_none,
1748
+ 1, 44, :_reduce_42,
1749
+ 3, 44, :_reduce_43,
1750
+ 3, 44, :_reduce_44,
1751
+ 0, 51, :_reduce_45,
1752
+ 0, 52, :_reduce_46,
1753
+ 8, 44, :_reduce_47,
1754
+ 1, 50, :_reduce_48,
1755
+ 1, 50, :_reduce_49,
1756
+ 3, 50, :_reduce_50,
1757
+ 0, 55, :_reduce_none,
1758
+ 2, 55, :_reduce_52,
1759
+ 1, 54, :_reduce_53,
1760
+ 1, 54, :_reduce_54,
1761
+ 3, 54, :_reduce_55,
1762
+ 4, 54, :_reduce_56,
1763
+ 0, 56, :_reduce_none,
1764
+ 1, 56, :_reduce_none,
1765
+ 0, 53, :_reduce_59,
1766
+ 1, 53, :_reduce_60,
1767
+ 2, 53, :_reduce_none ]
1768
+
1769
+ racc_reduce_n = 62
1770
+
1771
+ racc_shift_n = 100
1772
+
1773
+ racc_action_table = [
1774
+ -1, 75, 87, 16, 19, 16, 19, 82, 2, 9,
1775
+ 12, 9, 12, 42, 44, 47, 48, 5, 7, 10,
1776
+ 14, 18, 43, 20, 1, 4, 71, 2, 84, 16,
1777
+ 19, 26, 83, 47, 48, 9, 12, 7, 10, 14,
1778
+ 18, 26, 20, 1, 4, 46, 2, 26, 16, 19,
1779
+ 52, 49, 54, 50, 9, 12, 7, 10, 14, 18,
1780
+ -32, 20, 1, 4, -32, 2, 88, 16, 19, 47,
1781
+ 48, 47, 48, 9, 12, 7, 10, 14, 18, -32,
1782
+ 20, 1, 4, -32, 2, 90, 16, 19, 47, 48,
1783
+ 43, 79, 9, 12, 7, 10, 14, 18, 78, 20,
1784
+ 1, 4, 95, 2, 26, 16, 19, 96, 37, 83,
1785
+ 99, 9, 12, 7, 10, 14, 18, nil, 20, 1,
1786
+ 4, nil, 2, nil, 16, 19, nil, nil, nil, nil,
1787
+ 9, 12, 7, 10, 14, 18, nil, 20, 1, 4,
1788
+ nil, 2, nil, 16, 19, nil, nil, nil, nil, 9,
1789
+ 12, 7, 10, 14, 18, nil, 20, 1, 4, nil,
1790
+ 2, nil, 16, 19, nil, nil, nil, nil, 9, 12,
1791
+ 7, 10, 14, 18, nil, 20, 1, 4, nil, 2,
1792
+ nil, 16, 19, nil, nil, nil, nil, 9, 12, 7,
1793
+ 10, 14, 18, nil, 20, 1, 4, nil, 2, nil,
1794
+ 16, 19, nil, nil, nil, nil, 9, 12, 7, 10,
1795
+ 14, 18, nil, 20, 1, 4, nil, 2, nil, 16,
1796
+ 19, nil, nil, nil, nil, 9, 12, 7, 10, 14,
1797
+ 18, nil, 20, 1, 4, nil, 2, nil, 16, 19,
1798
+ nil, nil, nil, nil, 9, 12, 7, 10, 14, 18,
1799
+ nil, 20, 1, 4, nil, 2, nil, 16, 19, nil,
1800
+ nil, nil, nil, 9, 12, 7, 10, 14, 18, nil,
1801
+ 20, 1, 4, nil, 2, nil, 16, 19, nil, nil,
1802
+ nil, nil, 9, 12, 7, 10, 14, 18, nil, 20,
1803
+ 1, 4, nil, 2, nil, 16, 19, nil, nil, nil,
1804
+ nil, 9, 12, 7, 10, 14, 18, nil, 20, 1,
1805
+ 4, nil, 2, nil, 16, 19, nil, nil, nil, nil,
1806
+ 9, 12, 7, 10, 14, 18, nil, 20, 1, 4,
1807
+ nil, 2, nil, 16, 19, nil, nil, nil, nil, 9,
1808
+ 12, 7, 10, 14, 18, nil, 20, 1, 4, nil,
1809
+ 2, nil, 16, 19, nil, nil, nil, nil, 9, 12,
1810
+ 7, 10, 14, 18, nil, 20, 1, 4, nil, 2,
1811
+ nil, 16, 19, nil, nil, nil, nil, 9, 12, 7,
1812
+ 10, 14, 18, nil, 20, 1, 4, nil, 2, nil,
1813
+ 16, 19, nil, nil, nil, nil, 9, 12, 7, 10,
1814
+ 14, 18, nil, 20, 1, 4, 16, 19, nil, 16,
1815
+ 19, nil, 9, 12, nil, 9, 12, 26, nil, 29,
1816
+ 31, 33, 35, 23, 25, 27, 28, 30, 32, 34,
1817
+ 36, 24, 7, 10, 7, 10, 26, 81, 29, 31,
1818
+ 33, 16, 19, 16, 19, 16, 19, 9, 12, 9,
1819
+ 12, 9, 12, 26, nil, 29, 31, 33, 35, 23,
1820
+ 25, 27, 28, 30, 32, 34, 36, 24, 26, nil,
1821
+ 29, 31, 33, 35, 23, 25, 27, 28, 30, 32,
1822
+ 34, 36, 24, 26, nil, 29, 31, 33, 35, 23,
1823
+ 25, 27, 28, 30, 32, 34, 36, 24, 26, nil,
1824
+ 29, 31, 33, 35, 23, 25, 27, 28, 30, 32,
1825
+ 34, 36, 24, 26, nil, 29, 31, 33, 35, 23,
1826
+ 25, 27, 28, 30, 32, 34, 36, 26, nil, 29,
1827
+ 31, 33, 35, 23, 25, 27, 28, 30, 32, 34,
1828
+ 26, nil, 29, 31, 33, 35, 23, 25, 27, 28,
1829
+ 30, 26, nil, 29, 31, 33, 35, 23, 25, 27,
1830
+ 28, 30, 16, 19, -59, -59, nil, -59, 9, 12,
1831
+ 16, 19, nil, nil, nil, nil, 9, 12, 26, nil,
1832
+ 29, 31, 33, 35, 23, 26, nil, 29, 31, 33,
1833
+ 35, 23, 26, nil, 29, 31, 33, 35, 23, 26,
1834
+ nil, 29, 31, 33, 35, 23, 26, nil, 29, 31,
1835
+ 33 ]
1836
+
1837
+ racc_action_check = [
1838
+ 0, 47, 75, 48, 48, 47, 47, 54, 0, 48,
1839
+ 48, 47, 47, 11, 11, 40, 40, 0, 0, 0,
1840
+ 0, 0, 11, 0, 0, 0, 38, 23, 70, 0,
1841
+ 0, 61, 70, 13, 13, 0, 0, 23, 23, 23,
1842
+ 23, 22, 23, 23, 23, 12, 37, 63, 23, 23,
1843
+ 15, 15, 21, 15, 23, 23, 37, 37, 37, 37,
1844
+ 37, 37, 37, 37, 37, 94, 78, 37, 37, 41,
1845
+ 41, 74, 74, 37, 37, 94, 94, 94, 94, 94,
1846
+ 94, 94, 94, 94, 36, 79, 94, 94, 72, 72,
1847
+ 80, 50, 94, 94, 36, 36, 36, 36, 49, 36,
1848
+ 36, 36, 89, 35, 65, 36, 36, 93, 4, 97,
1849
+ 98, 36, 36, 35, 35, 35, 35, nil, 35, 35,
1850
+ 35, nil, 34, nil, 35, 35, nil, nil, nil, nil,
1851
+ 35, 35, 34, 34, 34, 34, nil, 34, 34, 34,
1852
+ nil, 83, nil, 34, 34, nil, nil, nil, nil, 34,
1853
+ 34, 83, 83, 83, 83, nil, 83, 83, 83, nil,
1854
+ 73, nil, 83, 83, nil, nil, nil, nil, 83, 83,
1855
+ 73, 73, 73, 73, nil, 73, 73, 73, nil, 33,
1856
+ nil, 73, 73, nil, nil, nil, nil, 73, 73, 33,
1857
+ 33, 33, 33, nil, 33, 33, 33, nil, 32, nil,
1858
+ 33, 33, nil, nil, nil, nil, 33, 33, 32, 32,
1859
+ 32, 32, nil, 32, 32, 32, nil, 18, nil, 32,
1860
+ 32, nil, nil, nil, nil, 32, 32, 18, 18, 18,
1861
+ 18, nil, 18, 18, 18, nil, 31, nil, 18, 18,
1862
+ nil, nil, nil, nil, 18, 18, 31, 31, 31, 31,
1863
+ nil, 31, 31, 31, nil, 30, nil, 31, 31, nil,
1864
+ nil, nil, nil, 31, 31, 30, 30, 30, 30, nil,
1865
+ 30, 30, 30, nil, 2, nil, 30, 30, nil, nil,
1866
+ nil, nil, 30, 30, 2, 2, 2, 2, nil, 2,
1867
+ 2, 2, nil, 29, nil, 2, 2, nil, nil, nil,
1868
+ nil, 2, 2, 29, 29, 29, 29, nil, 29, 29,
1869
+ 29, nil, 25, nil, 29, 29, nil, nil, nil, nil,
1870
+ 29, 29, 25, 25, 25, 25, nil, 25, 25, 25,
1871
+ nil, 26, nil, 25, 25, nil, nil, nil, nil, 25,
1872
+ 25, 26, 26, 26, 26, nil, 26, 26, 26, nil,
1873
+ 27, nil, 26, 26, nil, nil, nil, nil, 26, 26,
1874
+ 27, 27, 27, 27, nil, 27, 27, 27, nil, 28,
1875
+ nil, 27, 27, nil, nil, nil, nil, 27, 27, 28,
1876
+ 28, 28, 28, nil, 28, 28, 28, nil, 24, nil,
1877
+ 28, 28, nil, nil, nil, nil, 28, 28, 24, 24,
1878
+ 24, 24, nil, 24, 24, 24, 44, 44, nil, 24,
1879
+ 24, nil, 44, 44, nil, 24, 24, 53, nil, 53,
1880
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
1881
+ 53, 53, 71, 71, 5, 5, 67, 53, 67, 67,
1882
+ 67, 42, 42, 71, 71, 5, 5, 42, 42, 71,
1883
+ 71, 5, 5, 3, nil, 3, 3, 3, 3, 3,
1884
+ 3, 3, 3, 3, 3, 3, 3, 3, 69, nil,
1885
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
1886
+ 69, 69, 69, 92, nil, 92, 92, 92, 92, 92,
1887
+ 92, 92, 92, 92, 92, 92, 92, 92, 86, nil,
1888
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
1889
+ 86, 86, 86, 56, nil, 56, 56, 56, 56, 56,
1890
+ 56, 56, 56, 56, 56, 56, 56, 68, nil, 68,
1891
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
1892
+ 66, nil, 66, 66, 66, 66, 66, 66, 66, 66,
1893
+ 66, 64, nil, 64, 64, 64, 64, 64, 64, 64,
1894
+ 64, 64, 7, 7, 7, 7, nil, 7, 7, 7,
1895
+ 10, 10, nil, nil, nil, nil, 10, 10, 57, nil,
1896
+ 57, 57, 57, 57, 57, 60, nil, 60, 60, 60,
1897
+ 60, 60, 59, nil, 59, 59, 59, 59, 59, 62,
1898
+ nil, 62, 62, 62, 62, 62, 55, nil, 55, 55,
1899
+ 55 ]
1900
+
1901
+ racc_action_pointer = [
1902
+ 0, nil, 266, 451, 87, 416, nil, 533, nil, nil,
1903
+ 541, -5, 8, 15, nil, 19, nil, nil, 209, nil,
1904
+ nil, 52, 39, 19, 380, 304, 323, 342, 361, 285,
1905
+ 247, 228, 190, 171, 114, 95, 76, 38, 24, nil,
1906
+ -3, 51, 412, nil, 377, nil, nil, -24, -26, 65,
1907
+ 70, nil, nil, 415, 7, 604, 511, 576, nil, 590,
1908
+ 583, 29, 597, 45, 549, 102, 538, 434, 525, 466,
1909
+ 6, 414, 70, 152, 53, -19, nil, nil, 35, 62,
1910
+ 63, nil, nil, 133, nil, nil, 496, nil, nil, 80,
1911
+ nil, nil, 481, 79, 57, nil, nil, 83, 88, nil ]
1912
+
1913
+ racc_action_default = [
1914
+ -59, -28, -59, -2, -62, -59, -42, -38, -21, -60,
1915
+ -59, -22, -62, -41, -25, -62, -48, -29, -59, -49,
1916
+ -27, -62, -16, -59, -59, -59, -59, -59, -59, -59,
1917
+ -59, -59, -59, -59, -59, -59, -59, -59, -3, -4,
1918
+ -39, -40, -59, -35, -59, -30, -61, -59, -59, -54,
1919
+ -62, -51, -53, -62, -62, -15, -6, -10, -20, -11,
1920
+ -12, -17, -13, -18, -8, -19, -9, -14, -7, -33,
1921
+ -62, -59, -23, -59, -24, -62, -43, -44, -62, -57,
1922
+ -50, -26, 100, -59, -31, -5, -36, -45, -55, -62,
1923
+ -58, -52, -34, -62, -59, -56, -37, -46, -62, -47 ]
1924
+
1925
+ racc_goto_table = [
1926
+ 3, 45, 22, 39, 70, 40, 76, 77, 41, 73,
1927
+ 38, 93, 21, 94, 98, 51, 80, 89, 53, nil,
1928
+ nil, nil, nil, 55, 56, 57, 58, 59, 60, 61,
1929
+ 62, 63, 64, 65, 66, 67, 68, nil, nil, nil,
1930
+ 72, nil, 74, nil, nil, nil, nil, nil, nil, nil,
1931
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
1932
+ nil, 97, nil, nil, nil, nil, nil, nil, nil, 85,
1933
+ 91, nil, nil, 86, nil, nil, nil, nil, nil, nil,
1934
+ nil, nil, nil, 92 ]
1935
+
1936
+ racc_goto_check = [
1937
+ 2, 8, 2, 4, 9, 6, 12, 12, 6, 10,
1938
+ 3, 11, 1, 13, 14, 16, 17, 18, 2, nil,
1939
+ nil, nil, nil, 2, 2, 2, 2, 2, 2, 2,
1940
+ 2, 2, 2, 2, 2, 2, 2, nil, nil, nil,
1941
+ 6, nil, 6, nil, nil, nil, nil, nil, nil, nil,
1942
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
1943
+ nil, 9, nil, nil, nil, nil, nil, nil, nil, 4,
1944
+ 8, nil, nil, 2, nil, nil, nil, nil, nil, nil,
1945
+ nil, nil, nil, 2 ]
1946
+
1947
+ racc_goto_pointer = [
1948
+ nil, 12, 0, 5, -2, nil, -2, nil, -10, -33,
1949
+ -34, -75, -41, -74, -83, nil, 0, -35, -62 ]
1950
+
1951
+ racc_goto_default = [
1952
+ nil, nil, 69, nil, 8, 11, 13, 17, nil, nil,
1953
+ nil, nil, 6, nil, nil, 15, nil, nil, nil ]
1954
+
1955
+ racc_token_table = {
1956
+ false => 0,
1957
+ Object.new => 1,
1958
+ "|" => 2,
1959
+ :NEG => 3,
1960
+ :MUL => 4,
1961
+ "div" => 5,
1962
+ "mod" => 6,
1963
+ "+" => 7,
1964
+ "-" => 8,
1965
+ "<" => 9,
1966
+ ">" => 10,
1967
+ "<=" => 11,
1968
+ ">=" => 12,
1969
+ "=" => 13,
1970
+ "!=" => 14,
1971
+ "and" => 15,
1972
+ "or" => 16,
1973
+ :PATTERN => 17,
1974
+ "/" => 18,
1975
+ "//" => 19,
1976
+ :Variable => 20,
1977
+ "(" => 21,
1978
+ ")" => 22,
1979
+ :Literal => 23,
1980
+ :Number => 24,
1981
+ :FuncName => 25,
1982
+ "," => 26,
1983
+ "[" => 27,
1984
+ "]" => 28,
1985
+ "." => 29,
1986
+ ".." => 30,
1987
+ "*" => 31,
1988
+ :Name => 32,
1989
+ ":" => 33,
1990
+ :NodeType => 34,
1991
+ "@" => 35,
1992
+ :AxisName => 36,
1993
+ "::" => 37 }
1994
+
1995
+ racc_use_result_var = false
1996
+
1997
+ racc_nt_base = 38
1998
+
1999
+ Racc_arg = [
2000
+ racc_action_table,
2001
+ racc_action_check,
2002
+ racc_action_default,
2003
+ racc_action_pointer,
2004
+ racc_goto_table,
2005
+ racc_goto_check,
2006
+ racc_goto_default,
2007
+ racc_goto_pointer,
2008
+ racc_nt_base,
2009
+ racc_reduce_table,
2010
+ racc_token_table,
2011
+ racc_shift_n,
2012
+ racc_reduce_n,
2013
+ racc_use_result_var ]
2014
+
2015
+ Racc_debug_parser = false
2016
+
2017
+ ##### racc system variables end #####
2018
+
2019
+ # reduce 0 omitted
2020
+
2021
+ module_eval <<'.,.,', 'xpath.ry', 27
2022
+ def _reduce_1( val, _values)
2023
+ []
2024
+ end
2025
+ .,.,
2026
+
2027
+ module_eval <<'.,.,', 'xpath.ry', 30
2028
+ def _reduce_2( val, _values)
2029
+ expr = val[0].expr('.to_ruby')
2030
+ expr.collect! { |i| i or @context }
2031
+ expr
2032
+ end
2033
+ .,.,
2034
+
2035
+ module_eval <<'.,.,', 'xpath.ry', 36
2036
+ def _reduce_3( val, _values)
2037
+ expr = val[0].expr('.to_ruby')
2038
+ expr.collect! { |i| i or @context }
2039
+ expr
2040
+ end
2041
+ .,.,
2042
+
2043
+ # reduce 4 omitted
2044
+
2045
+ module_eval <<'.,.,', 'xpath.ry', 43
2046
+ def _reduce_5( val, _values)
2047
+ val[0] ** val[2]
2048
+ end
2049
+ .,.,
2050
+
2051
+ module_eval <<'.,.,', 'xpath.ry', 46
2052
+ def _reduce_6( val, _values)
2053
+ val[0].logical_or val[2]
2054
+ end
2055
+ .,.,
2056
+
2057
+ module_eval <<'.,.,', 'xpath.ry', 48
2058
+ def _reduce_7( val, _values)
2059
+ val[0].logical_and val[2]
2060
+ end
2061
+ .,.,
2062
+
2063
+ module_eval <<'.,.,', 'xpath.ry', 50
2064
+ def _reduce_8( val, _values)
2065
+ val[0].eq val[2]
2066
+ end
2067
+ .,.,
2068
+
2069
+ module_eval <<'.,.,', 'xpath.ry', 52
2070
+ def _reduce_9( val, _values)
2071
+ val[0].neq val[2]
2072
+ end
2073
+ .,.,
2074
+
2075
+ module_eval <<'.,.,', 'xpath.ry', 54
2076
+ def _reduce_10( val, _values)
2077
+ val[0].lt val[2]
2078
+ end
2079
+ .,.,
2080
+
2081
+ module_eval <<'.,.,', 'xpath.ry', 56
2082
+ def _reduce_11( val, _values)
2083
+ val[0].gt val[2]
2084
+ end
2085
+ .,.,
2086
+
2087
+ module_eval <<'.,.,', 'xpath.ry', 58
2088
+ def _reduce_12( val, _values)
2089
+ val[0].le val[2]
2090
+ end
2091
+ .,.,
2092
+
2093
+ module_eval <<'.,.,', 'xpath.ry', 60
2094
+ def _reduce_13( val, _values)
2095
+ val[0].ge val[2]
2096
+ end
2097
+ .,.,
2098
+
2099
+ module_eval <<'.,.,', 'xpath.ry', 62
2100
+ def _reduce_14( val, _values)
2101
+ val[0] + val[2]
2102
+ end
2103
+ .,.,
2104
+
2105
+ module_eval <<'.,.,', 'xpath.ry', 64
2106
+ def _reduce_15( val, _values)
2107
+ val[0] - val[2]
2108
+ end
2109
+ .,.,
2110
+
2111
+ module_eval <<'.,.,', 'xpath.ry', 66
2112
+ def _reduce_16( val, _values)
2113
+ -val[1]
2114
+ end
2115
+ .,.,
2116
+
2117
+ module_eval <<'.,.,', 'xpath.ry', 68
2118
+ def _reduce_17( val, _values)
2119
+ val[0] * val[2]
2120
+ end
2121
+ .,.,
2122
+
2123
+ module_eval <<'.,.,', 'xpath.ry', 70
2124
+ def _reduce_18( val, _values)
2125
+ val[0] / val[2]
2126
+ end
2127
+ .,.,
2128
+
2129
+ module_eval <<'.,.,', 'xpath.ry', 72
2130
+ def _reduce_19( val, _values)
2131
+ val[0] % val[2]
2132
+ end
2133
+ .,.,
2134
+
2135
+ module_eval <<'.,.,', 'xpath.ry', 75
2136
+ def _reduce_20( val, _values)
2137
+ # Why `**' is used for unionizing node-sets is that its
2138
+ # precedence is higher than any other binary operators
2139
+ # in Ruby.
2140
+ val[0] ** val[2]
2141
+ end
2142
+ .,.,
2143
+
2144
+ # reduce 21 omitted
2145
+
2146
+ # reduce 22 omitted
2147
+
2148
+ module_eval <<'.,.,', 'xpath.ry', 83
2149
+ def _reduce_23( val, _values)
2150
+ val[0] << val[2]
2151
+ end
2152
+ .,.,
2153
+
2154
+ module_eval <<'.,.,', 'xpath.ry', 85
2155
+ def _reduce_24( val, _values)
2156
+ val[0].add_step('descendant-or-self') << val[2]
2157
+ end
2158
+ .,.,
2159
+
2160
+ module_eval <<'.,.,', 'xpath.ry', 89
2161
+ def _reduce_25( val, _values)
2162
+ Expression.new [ nil,'.get_variable(',val[0].dump,')' ]
2163
+ end
2164
+ .,.,
2165
+
2166
+ module_eval <<'.,.,', 'xpath.ry', 92
2167
+ def _reduce_26( val, _values)
2168
+ val[1].unarize
2169
+ end
2170
+ .,.,
2171
+
2172
+ module_eval <<'.,.,', 'xpath.ry', 94
2173
+ def _reduce_27( val, _values)
2174
+ Expression.new StringConstant.new(val[0])
2175
+ end
2176
+ .,.,
2177
+
2178
+ module_eval <<'.,.,', 'xpath.ry', 96
2179
+ def _reduce_28( val, _values)
2180
+ Expression.new NumberConstant.new(val[0])
2181
+ end
2182
+ .,.,
2183
+
2184
+ module_eval <<'.,.,', 'xpath.ry', 98
2185
+ def _reduce_29( val, _values)
2186
+ Expression.new val[0]
2187
+ end
2188
+ .,.,
2189
+
2190
+ module_eval <<'.,.,', 'xpath.ry', 100
2191
+ def _reduce_30( val, _values)
2192
+ val[0].add_predicate val[1]
2193
+ end
2194
+ .,.,
2195
+
2196
+ module_eval <<'.,.,', 'xpath.ry', 104
2197
+ def _reduce_31( val, _values)
2198
+ val[2][0,0] = [ nil, ".funcall(#{val[0].dump}" ]
2199
+ val[2].push(')')
2200
+ end
2201
+ .,.,
2202
+
2203
+ module_eval <<'.,.,', 'xpath.ry', 109
2204
+ def _reduce_32( val, _values)
2205
+ []
2206
+ end
2207
+ .,.,
2208
+
2209
+ module_eval <<'.,.,', 'xpath.ry', 111
2210
+ def _reduce_33( val, _values)
2211
+ val[0].expr.unshift ', '
2212
+ end
2213
+ .,.,
2214
+
2215
+ module_eval <<'.,.,', 'xpath.ry', 113
2216
+ def _reduce_34( val, _values)
2217
+ val[0].push(', ').concat(val[2].expr)
2218
+ end
2219
+ .,.,
2220
+
2221
+ module_eval <<'.,.,', 'xpath.ry', 117
2222
+ def _reduce_35( val, _values)
2223
+ c = @context
2224
+ @context = c.succ
2225
+ c
2226
+ end
2227
+ .,.,
2228
+
2229
+ module_eval <<'.,.,', 'xpath.ry', 123
2230
+ def _reduce_36( val, _values)
2231
+ c = @context
2232
+ @context = _values[-2]
2233
+ c
2234
+ end
2235
+ .,.,
2236
+
2237
+ module_eval <<'.,.,', 'xpath.ry', 129
2238
+ def _reduce_37( val, _values)
2239
+ expr = val[2]
2240
+ valuetype = expr.value_type
2241
+ value = expr.value
2242
+ if valuetype == :number then
2243
+ if value then
2244
+ f = value.to_f
2245
+ if f > 0 and f.truncate == f then
2246
+ [ ".at(#{f.to_i})" ]
2247
+ else
2248
+ [ '.at(0)' ] # clear
2249
+ end
2250
+ else
2251
+ expr.expr('.to_f').
2252
+ unshift('.at(').push(')')
2253
+ end
2254
+ elsif value then
2255
+ if value.true? then
2256
+ []
2257
+ else
2258
+ [ '.at(0)' ] # clear
2259
+ end
2260
+ else
2261
+ c = val[3]
2262
+ if valuetype == :ruby_boolean then
2263
+ conv = '.true?'
2264
+ else
2265
+ conv = '.to_predicate'
2266
+ end
2267
+ a = expr.expr(conv)
2268
+ a.collect! { |i| i or c }
2269
+ a.unshift(".predicate { |#{c}| ").push(' }')
2270
+ end
2271
+ end
2272
+ .,.,
2273
+
2274
+ module_eval <<'.,.,', 'xpath.ry', 164
2275
+ def _reduce_38( val, _values)
2276
+ LocationPath.new.absolute!
2277
+ end
2278
+ .,.,
2279
+
2280
+ module_eval <<'.,.,', 'xpath.ry', 166
2281
+ def _reduce_39( val, _values)
2282
+ val[1].absolute!
2283
+ end
2284
+ .,.,
2285
+
2286
+ module_eval <<'.,.,', 'xpath.ry', 169
2287
+ def _reduce_40( val, _values)
2288
+ path = LocationPath.new
2289
+ path.absolute!
2290
+ path.add_step('descendant-or-self') << val[1]
2291
+ end
2292
+ .,.,
2293
+
2294
+ # reduce 41 omitted
2295
+
2296
+ module_eval <<'.,.,', 'xpath.ry', 176
2297
+ def _reduce_42( val, _values)
2298
+ LocationPath.new.add_step(*val[0])
2299
+ end
2300
+ .,.,
2301
+
2302
+ module_eval <<'.,.,', 'xpath.ry', 178
2303
+ def _reduce_43( val, _values)
2304
+ val[0].add_step(*val[2])
2305
+ end
2306
+ .,.,
2307
+
2308
+ module_eval <<'.,.,', 'xpath.ry', 181
2309
+ def _reduce_44( val, _values)
2310
+ val[0].add_step('descendant-or-self').add_step(*val[2])
2311
+ end
2312
+ .,.,
2313
+
2314
+ module_eval <<'.,.,', 'xpath.ry', 186
2315
+ def _reduce_45( val, _values)
2316
+ c = @context
2317
+ @context = c.succ
2318
+ c
2319
+ end
2320
+ .,.,
2321
+
2322
+ module_eval <<'.,.,', 'xpath.ry', 192
2323
+ def _reduce_46( val, _values)
2324
+ c = @context
2325
+ @context = _values[-2]
2326
+ c
2327
+ end
2328
+ .,.,
2329
+
2330
+ module_eval <<'.,.,', 'xpath.ry', 198
2331
+ def _reduce_47( val, _values)
2332
+ on_error unless is_xpointer?
2333
+ args = val[5]
2334
+ c = val[6]
2335
+ args.collect! { |i| i or c }
2336
+ args[0] = ".funcall(#{val[2].dump}) { |#{c}| ["
2337
+ args.push '] }'
2338
+ val[0].add_predicate args
2339
+ end
2340
+ .,.,
2341
+
2342
+ module_eval <<'.,.,', 'xpath.ry', 208
2343
+ def _reduce_48( val, _values)
2344
+ [ 'self', false, false, false, nil ]
2345
+ end
2346
+ .,.,
2347
+
2348
+ module_eval <<'.,.,', 'xpath.ry', 210
2349
+ def _reduce_49( val, _values)
2350
+ [ 'parent', false, false, false, nil ]
2351
+ end
2352
+ .,.,
2353
+
2354
+ module_eval <<'.,.,', 'xpath.ry', 213
2355
+ def _reduce_50( val, _values)
2356
+ nodetest = val[1]
2357
+ unless nodetest[0] then
2358
+ axis = val[0]
2359
+ if axis != 'attribute' and axis != 'namespace' then
2360
+ nodetest[0] = 'element'
2361
+ end
2362
+ end
2363
+ nodetest[0] = false if nodetest[0] == 'node'
2364
+ nodetest.unshift(val[0]).push(val[2])
2365
+ end
2366
+ .,.,
2367
+
2368
+ # reduce 51 omitted
2369
+
2370
+ module_eval <<'.,.,', 'xpath.ry', 226
2371
+ def _reduce_52( val, _values)
2372
+ (val[0] || []).concat val[1]
2373
+ end
2374
+ .,.,
2375
+
2376
+ module_eval <<'.,.,', 'xpath.ry', 229
2377
+ def _reduce_53( val, _values)
2378
+ [ false, false, false ]
2379
+ end
2380
+ .,.,
2381
+
2382
+ module_eval <<'.,.,', 'xpath.ry', 232
2383
+ def _reduce_54( val, _values)
2384
+ if /:/ =~ val[0] then
2385
+ [ false, $', $` ] #' <= for racc
2386
+ else
2387
+ [ false, val[0], nil ]
2388
+ end
2389
+ end
2390
+ .,.,
2391
+
2392
+ module_eval <<'.,.,', 'xpath.ry', 240
2393
+ def _reduce_55( val, _values)
2394
+ on_error if /:/ =~ val[0]
2395
+ [ false, false, val[0] ]
2396
+ end
2397
+ .,.,
2398
+
2399
+ module_eval <<'.,.,', 'xpath.ry', 245
2400
+ def _reduce_56( val, _values)
2401
+ nodetype = val[0]
2402
+ arg = val[2]
2403
+ if arg and nodetype != 'processing-instruction' then
2404
+ raise CompileError,
2405
+ "nodetest #{nodetype}() requires no argument"
2406
+ end
2407
+ [ nodetype, arg || false, false ]
2408
+ end
2409
+ .,.,
2410
+
2411
+ # reduce 57 omitted
2412
+
2413
+ # reduce 58 omitted
2414
+
2415
+ module_eval <<'.,.,', 'xpath.ry', 258
2416
+ def _reduce_59( val, _values)
2417
+ 'child'
2418
+ end
2419
+ .,.,
2420
+
2421
+ module_eval <<'.,.,', 'xpath.ry', 260
2422
+ def _reduce_60( val, _values)
2423
+ 'attribute'
2424
+ end
2425
+ .,.,
2426
+
2427
+ # reduce 61 omitted
2428
+
2429
+ def _reduce_none( val, _values)
2430
+ val[0]
2431
+ end
2432
+
2433
+ end # class Compiler
2434
+
2435
+
2436
+ #
2437
+ # Client NodeVisitor a NodeAdapter a Node
2438
+ # | | | |
2439
+ # |=| | | |
2440
+ # | |--{visit(node)}-->|=| | |
2441
+ # | | | |---{accept(self)}----------------->|=|
2442
+ # | | |=| | | |
2443
+ # | | | | | |
2444
+ # | | |=|<------------------{on_**(self)}---|=|
2445
+ # | | | | | |
2446
+ # | | | |--{wrap(node)}-->|=| |
2447
+ # | | | | | | |
2448
+ # | | | | |=| |
2449
+ # | |<--[NodeAdapter]--|=| | |
2450
+ # | | | | |
2451
+ # | |-----{request}----------------------->|=| |
2452
+ # | | | | |--{request}--->|=|
2453
+ # | | | | | | |
2454
+ # | | | | |<-----[Data]---|=|
2455
+ # | |<--------------------------[Data]-----|=| |
2456
+ # | | | | |
2457
+ # |=| | | |
2458
+ # | | | |
2459
+ #
2460
+
2461
+
2462
+ class TransparentNodeVisitor
2463
+
2464
+ def visit(node)
2465
+ node
2466
+ end
2467
+
2468
+ end
2469
+
2470
+
2471
+ class NullNodeAdapter
2472
+
2473
+ def node
2474
+ self
2475
+ end
2476
+
2477
+ def root
2478
+ nil
2479
+ end
2480
+
2481
+ def parent
2482
+ nil
2483
+ end
2484
+
2485
+ def children
2486
+ []
2487
+ end
2488
+
2489
+ def each_following_siblings
2490
+ end
2491
+
2492
+ def each_preceding_siblings
2493
+ end
2494
+
2495
+ def attributes
2496
+ []
2497
+ end
2498
+
2499
+ def namespaces
2500
+ []
2501
+ end
2502
+
2503
+ def index
2504
+ 0
2505
+ end
2506
+
2507
+ def node_type
2508
+ nil
2509
+ end
2510
+
2511
+ def name_localpart
2512
+ nil
2513
+ end
2514
+
2515
+ def qualified_name
2516
+ name_localpart
2517
+ end
2518
+
2519
+ def namespace_uri
2520
+ nil
2521
+ end
2522
+
2523
+ def string_value
2524
+ ''
2525
+ end
2526
+
2527
+ def lang
2528
+ nil
2529
+ end
2530
+
2531
+ def select_id(*ids)
2532
+ raise XPath::Error, "selection by ID is not supported"
2533
+ end
2534
+
2535
+ end
2536
+
2537
+
2538
+
2539
+
2540
+ class AxisIterator
2541
+
2542
+ def reverse_order?
2543
+ false
2544
+ end
2545
+
2546
+ end
2547
+
2548
+
2549
+ class ReverseAxisIterator < AxisIterator
2550
+
2551
+ def reverse_order?
2552
+ true
2553
+ end
2554
+
2555
+ end
2556
+
2557
+
2558
+ class SelfIterator < AxisIterator
2559
+
2560
+ def each(node, visitor)
2561
+ yield visitor.visit(node)
2562
+ end
2563
+
2564
+ end
2565
+
2566
+
2567
+ class ChildIterator < AxisIterator
2568
+
2569
+ def each(node, visitor, &block)
2570
+ visitor.visit(node).children.each { |i| yield visitor.visit(i) }
2571
+ end
2572
+
2573
+ end
2574
+
2575
+
2576
+ class ParentIterator < AxisIterator
2577
+
2578
+ def each(node, visitor)
2579
+ parent = visitor.visit(node).parent
2580
+ yield visitor.visit(parent) if parent
2581
+ end
2582
+
2583
+ end
2584
+
2585
+
2586
+ class AncestorIterator < ReverseAxisIterator
2587
+
2588
+ def each(node, visitor)
2589
+ node = visitor.visit(node).parent
2590
+ while node
2591
+ i = visitor.visit(node)
2592
+ parent = i.parent
2593
+ yield i
2594
+ node = parent
2595
+ end
2596
+ end
2597
+
2598
+ end
2599
+
2600
+
2601
+ class AncestorOrSelfIterator < AncestorIterator
2602
+
2603
+ def each(node, visitor)
2604
+ yield visitor.visit(node)
2605
+ super
2606
+ end
2607
+
2608
+ end
2609
+
2610
+
2611
+ class DescendantIterator < AxisIterator
2612
+
2613
+ def each(node, visitor)
2614
+ stack = visitor.visit(node).children.reverse
2615
+ while node = stack.pop
2616
+ i = visitor.visit(node)
2617
+ stack.concat i.children.reverse
2618
+ yield i
2619
+ end
2620
+ end
2621
+
2622
+ end
2623
+
2624
+
2625
+ class DescendantOrSelfIterator < DescendantIterator
2626
+
2627
+ def each(node, visitor)
2628
+ yield visitor.visit(node)
2629
+ super
2630
+ end
2631
+
2632
+ end
2633
+
2634
+
2635
+ class FollowingSiblingIterator < AxisIterator
2636
+
2637
+ def each(node, visitor)
2638
+ visitor.visit(node).each_following_siblings { |i|
2639
+ yield visitor.visit(i)
2640
+ }
2641
+ end
2642
+
2643
+ end
2644
+
2645
+
2646
+ class PrecedingSiblingIterator < ReverseAxisIterator
2647
+
2648
+ def each(node, visitor)
2649
+ visitor.visit(node).each_preceding_siblings { |i|
2650
+ yield visitor.visit(i)
2651
+ }
2652
+ end
2653
+
2654
+ end
2655
+
2656
+
2657
+ class FollowingIterator < DescendantOrSelfIterator
2658
+
2659
+ def each(node, visitor)
2660
+ while parent = (a = visitor.visit(node)).parent
2661
+ a.each_following_siblings { |i| super i, visitor }
2662
+ node = parent
2663
+ end
2664
+ end
2665
+
2666
+ end
2667
+
2668
+
2669
+ class PrecedingIterator < ReverseAxisIterator
2670
+
2671
+ def each(node, visitor)
2672
+ while parent = (adaptor = visitor.visit(node)).parent
2673
+ adaptor.each_preceding_siblings { |i|
2674
+ stack = visitor.visit(i).children.dup
2675
+ while node = stack.pop
2676
+ a = visitor.visit(node)
2677
+ stack.concat a.children
2678
+ yield a
2679
+ end
2680
+ yield visitor.visit(i)
2681
+ }
2682
+ node = parent
2683
+ end
2684
+ end
2685
+
2686
+ end
2687
+
2688
+
2689
+ class AttributeIterator < AxisIterator
2690
+
2691
+ def each(node, visitor)
2692
+ visitor.visit(node).attributes.each { |i| yield visitor.visit(i) }
2693
+ end
2694
+
2695
+ end
2696
+
2697
+
2698
+ class NamespaceIterator < AxisIterator
2699
+
2700
+ def each(node, visitor)
2701
+ visitor.visit(node).namespaces.each { |i| yield visitor.visit(i) }
2702
+ end
2703
+
2704
+ end
2705
+
2706
+
2707
+
2708
+
2709
+ class XPathNodeSet
2710
+
2711
+ class LocationStep < XPathNodeSet
2712
+
2713
+ def initialize(context)
2714
+ @context = context
2715
+ @visitor = context.visitor
2716
+ @nodes = []
2717
+ end
2718
+
2719
+ def set_iterator(iterator)
2720
+ @iterator = iterator
2721
+ end
2722
+
2723
+ def reuse(node)
2724
+ @node = node
2725
+ @nodes.clear
2726
+ end
2727
+
2728
+ def select
2729
+ @iterator.each(@node, @visitor) { |i|
2730
+ node = i.node
2731
+ @nodes.push node if yield(i)
2732
+ }
2733
+ self
2734
+ end
2735
+
2736
+ def select_all
2737
+ @iterator.each(@node, @visitor) { |i| @nodes.push i.node }
2738
+ self
2739
+ end
2740
+
2741
+ end
2742
+
2743
+
2744
+ include XPathObject
2745
+
2746
+ def initialize(context, *nodes)
2747
+ @context = context.dup
2748
+ @visitor = context.visitor
2749
+ nodes.sort! { |a,b| compare_position a, b }
2750
+ @nodes = nodes
2751
+ end
2752
+
2753
+ attr_reader :nodes
2754
+ protected :nodes
2755
+
2756
+
2757
+ def to_str
2758
+ if @nodes.empty? then
2759
+ ''
2760
+ else
2761
+ @visitor.visit(@nodes[0]).string_value
2762
+ end
2763
+ end
2764
+
2765
+ def to_f
2766
+ to_string(@context).to_f
2767
+ end
2768
+
2769
+ def true?
2770
+ not @nodes.empty?
2771
+ end
2772
+
2773
+ def to_ruby
2774
+ @nodes
2775
+ end
2776
+
2777
+
2778
+ def self.def_comparison_operator(*ops)
2779
+ ops.each { |op|
2780
+ module_eval <<_, __FILE__, __LINE__ + 1
2781
+ def #{op}(other)
2782
+ if other.is_a? XPathBoolean then
2783
+ other #{op} self.to_boolean
2784
+ else
2785
+ visitor = @visitor
2786
+ str = @context.make_string('')
2787
+ ret = false
2788
+ @nodes.each { |node|
2789
+ str.replace visitor.visit(node).string_value
2790
+ break if ret = (other #{op} str)
2791
+ }
2792
+ ret
2793
+ end
2794
+ end
2795
+ _
2796
+ }
2797
+ end
2798
+
2799
+ def_comparison_operator '==', '<', '>', '<=', '>='
2800
+
2801
+ class << self
2802
+ undef def_comparison_operator
2803
+ end
2804
+
2805
+ def **(other)
2806
+ super unless other.is_a? XPathNodeSet
2807
+ merge other.nodes
2808
+ self
2809
+ end
2810
+
2811
+
2812
+ def count
2813
+ @nodes.size
2814
+ end
2815
+
2816
+ def first
2817
+ @nodes[0]
2818
+ end
2819
+
2820
+ def each(&block)
2821
+ @nodes.each(&block)
2822
+ end
2823
+
2824
+
2825
+ def funcall(name) # for XPointer
2826
+ raise "BUG" unless block_given?
2827
+ func = ('f_' + name.tr('-', '_')).intern
2828
+ super unless respond_to? func, true
2829
+ size = @nodes.size
2830
+ pos = 1
2831
+ c = @context.dup
2832
+ begin
2833
+ @nodes.collect! { |node|
2834
+ c.reuse node, pos, size
2835
+ pos += 1
2836
+ args = yield(c)
2837
+ send(func, node, *args)
2838
+ }
2839
+ rescue Object::ArgumentError
2840
+ if $@[1] == "#{__FILE__}:#{__LINE__-3}:in `send'" then
2841
+ raise XPath::ArgumentError, "#{$!} for `#{name}'"
2842
+ end
2843
+ raise
2844
+ end
2845
+ self
2846
+ end
2847
+
2848
+
2849
+ private
2850
+
2851
+ def compare_position(node1, node2)
2852
+ visitor = @visitor
2853
+ ancestors1 = []
2854
+ ancestors2 = []
2855
+ p1 = visitor.visit(node1).parent
2856
+ while p1
2857
+ ancestors1.push node1
2858
+ p1 = visitor.visit(node1 = p1).parent
2859
+ end
2860
+ p2 = visitor.visit(node2).parent
2861
+ while p2
2862
+ ancestors2.push node2
2863
+ p2 = visitor.visit(node2 = p2).parent
2864
+ end
2865
+ unless node1 == node2 then
2866
+ raise XPath::Error, "can't compare the positions of given two nodes"
2867
+ end
2868
+ n = -1
2869
+ ancestors1.reverse_each { |node1|
2870
+ node2 = ancestors2[n]
2871
+ unless node1 == node2 then
2872
+ break unless node2
2873
+ return visitor.visit(node1).index - visitor.visit(node2).index
2874
+ end
2875
+ n -= 1
2876
+ }
2877
+ ancestors1.size - ancestors2.size
2878
+ end
2879
+
2880
+
2881
+ def merge(other)
2882
+ if @nodes.empty? or other.empty? then
2883
+ @nodes.concat other
2884
+ elsif (n = compare_position(@nodes.last, other.first)) <= 0 then
2885
+ @nodes.pop if n == 0
2886
+ @nodes.concat other
2887
+ elsif (n = compare_position(other.last, @nodes.first)) <= 0 then
2888
+ other.pop if n == 0
2889
+ @nodes = other.concat(@nodes)
2890
+ else
2891
+ newnodes = []
2892
+ nodes = @nodes
2893
+ until nodes.empty? or other.empty?
2894
+ n = compare_position(nodes.last, other.last)
2895
+ if n > 0 then
2896
+ newnodes.push nodes.pop
2897
+ elsif n < 0 then
2898
+ newnodes.push other.pop
2899
+ else
2900
+ newnodes.push nodes.pop
2901
+ other.pop
2902
+ end
2903
+ end
2904
+ newnodes.reverse!
2905
+ @nodes.concat(other).concat(newnodes)
2906
+ end
2907
+ end
2908
+
2909
+
2910
+ IteratorForAxis = {
2911
+ :self => SelfIterator.new,
2912
+ :child => ChildIterator.new,
2913
+ :parent => ParentIterator.new,
2914
+ :ancestor => AncestorIterator.new,
2915
+ :ancestor_or_self => AncestorOrSelfIterator.new,
2916
+ :descendant => DescendantIterator.new,
2917
+ :descendant_or_self => DescendantOrSelfIterator.new,
2918
+ :following => FollowingIterator.new,
2919
+ :preceding => PrecedingIterator.new,
2920
+ :following_sibling => FollowingSiblingIterator.new,
2921
+ :preceding_sibling => PrecedingSiblingIterator.new,
2922
+ :attribute => AttributeIterator.new,
2923
+ :namespace => NamespaceIterator.new,
2924
+ }
2925
+
2926
+ def get_iterator(axis)
2927
+ ret = IteratorForAxis[axis]
2928
+ unless ret then
2929
+ raise XPath::NameError, "invalid axis `#{axis.id2name.tr('_','-')}'"
2930
+ end
2931
+ ret
2932
+ end
2933
+
2934
+ def make_location_step
2935
+ if defined? @__lstep__ then
2936
+ @__lstep__
2937
+ else
2938
+ @__lstep__ = LocationStep.new(@context)
2939
+ end
2940
+ end
2941
+
2942
+
2943
+ public
2944
+
2945
+ def step(axis)
2946
+ iterator = get_iterator(axis)
2947
+ lstep = make_location_step
2948
+ lstep.set_iterator iterator
2949
+ oldnodes = @nodes
2950
+ @nodes = []
2951
+ oldnodes.each { |node|
2952
+ lstep.reuse node
2953
+ nodes = yield(lstep).nodes
2954
+ nodes.reverse! if iterator.reverse_order?
2955
+ merge nodes
2956
+ }
2957
+ self
2958
+ end
2959
+
2960
+
2961
+ def select_all(axis)
2962
+ iterator = get_iterator(axis)
2963
+ visitor = @visitor
2964
+ oldnodes = @nodes
2965
+ @nodes = []
2966
+ oldnodes.each { |start|
2967
+ nodes = []
2968
+ iterator.each(start, visitor) { |i| nodes.push i.node }
2969
+ nodes.reverse! if iterator.reverse_order?
2970
+ merge nodes
2971
+ }
2972
+ self
2973
+ end
2974
+
2975
+
2976
+ def predicate
2977
+ context = @context
2978
+ size = @nodes.size
2979
+ pos = 1
2980
+ result = nil
2981
+ newnodes = @nodes.reject { |node|
2982
+ context.reuse node, pos, size
2983
+ pos += 1
2984
+ result = yield(context)
2985
+ break if result.is_a? Numeric
2986
+ not result
2987
+ }
2988
+ if result.is_a? Numeric then
2989
+ at result
2990
+ else
2991
+ @nodes = newnodes
2992
+ end
2993
+ self
2994
+ end
2995
+
2996
+
2997
+ def at(pos)
2998
+ n = pos.to_i
2999
+ if n != pos or n <= 0 then
3000
+ node = nil
3001
+ else
3002
+ node = @nodes[n - 1]
3003
+ end
3004
+ @nodes.clear
3005
+ @nodes.push node if node
3006
+ self
3007
+ end
3008
+
3009
+ end
3010
+
3011
+
3012
+
3013
+ class Context
3014
+
3015
+ def initialize(node, namespace = nil, variable = nil, visitor = nil)
3016
+ visitor = TransparentNodeVisitor.new unless visitor
3017
+ @visitor = visitor
3018
+ @node = node
3019
+ @context_position = 1
3020
+ @context_size = 1
3021
+ @variables = variable
3022
+ @namespaces = namespace || {}
3023
+ end
3024
+
3025
+ attr_reader :visitor, :node, :context_position, :context_size
3026
+
3027
+ def reuse(node, pos = 1, size = 1)
3028
+ @variables = nil
3029
+ @node, @context_position, @context_size = node, pos, size
3030
+ end
3031
+
3032
+
3033
+ def get_variable(name)
3034
+ value = @variables && @variables[name] # value should be a XPathObjcect.
3035
+ raise XPath::NameError, "undefined variable `#{name}'" unless value
3036
+ value
3037
+ end
3038
+
3039
+
3040
+ PredefinedNamespace = {
3041
+ 'xml' => 'http://www.w3.org/XML/1998/namespace',
3042
+ }
3043
+
3044
+ def get_namespace(prefix)
3045
+ ret = @namespaces[prefix] || PredefinedNamespace[prefix]
3046
+ raise XPath::Error, "undeclared namespace `#{prefix}'" unless ret
3047
+ ret
3048
+ end
3049
+
3050
+
3051
+ def make_string(str)
3052
+ XPathString.new str
3053
+ end
3054
+
3055
+ def make_number(num)
3056
+ XPathNumber.new num
3057
+ end
3058
+
3059
+ def make_boolean(f)
3060
+ if f then
3061
+ XPathTrue
3062
+ else
3063
+ XPathFalse
3064
+ end
3065
+ end
3066
+
3067
+ def make_nodeset(*nodes)
3068
+ XPathNodeSet.new(self, *nodes)
3069
+ end
3070
+
3071
+
3072
+ def to_nodeset
3073
+ make_nodeset @node
3074
+ end
3075
+
3076
+ def root_nodeset
3077
+ make_nodeset @visitor.visit(@node).root
3078
+ end
3079
+
3080
+
3081
+ def funcall(name, *args)
3082
+ begin
3083
+ send('f_' + name.tr('-', '_'), *args)
3084
+ rescue Object::NameError
3085
+ if $@[0] == "#{__FILE__}:#{__LINE__-2}:in `send'" then
3086
+ raise XPath::NameError, "undefined function `#{name}'"
3087
+ end
3088
+ raise
3089
+ rescue Object::ArgumentError
3090
+ if $@[1] == "#{__FILE__}:#{__LINE__-7}:in `send'" then
3091
+ raise XPath::ArgumentError, "#{$!} for `#{name}'"
3092
+ end
3093
+ raise
3094
+ end
3095
+ end
3096
+
3097
+
3098
+ private
3099
+
3100
+ def must(type, *args)
3101
+ args.each { |i|
3102
+ unless i.is_a? type then
3103
+ s = type.name.sub(/\A.*::(?:XPath)?(?=[^:]+\z)/, '')
3104
+ raise XPath::TypeError, "argument must be #{s}"
3105
+ end
3106
+ }
3107
+ end
3108
+
3109
+ def must_be_nodeset(*args)
3110
+ must XPathNodeSet, *args
3111
+ end
3112
+
3113
+
3114
+ def f_last
3115
+ make_number @context_size.to_f
3116
+ end
3117
+
3118
+ def f_position
3119
+ make_number @context_position.to_f
3120
+ end
3121
+
3122
+ def f_count(nodeset)
3123
+ must_be_nodeset nodeset
3124
+ make_number nodeset.count.to_f
3125
+ end
3126
+
3127
+ def f_id(obj)
3128
+ unless obj.is_a? XPathNodeSet then
3129
+ ids = obj.to_str.strip.split(/\s+/)
3130
+ else
3131
+ ids = []
3132
+ obj.each { |node| ids.push @visitor.visit(node).string_value }
3133
+ end
3134
+ root = @visitor.visit(@node).root
3135
+ make_nodeset(*@visitor.visit(root).select_id(*ids))
3136
+ end
3137
+
3138
+ def f_local_name(nodeset = nil)
3139
+ unless nodeset then
3140
+ n = @node
3141
+ else
3142
+ must_be_nodeset nodeset
3143
+ n = nodeset.first
3144
+ end
3145
+ n = @visitor.visit(n) if n
3146
+ n = n.name_localpart if n
3147
+ n = '' unless n
3148
+ make_string n
3149
+ end
3150
+
3151
+ def f_namespace_uri(nodeset = nil)
3152
+ unless nodeset then
3153
+ n = @node
3154
+ else
3155
+ must_be_nodeset nodeset
3156
+ n = nodeset.first
3157
+ end
3158
+ n = @visitor.visit(n) if n
3159
+ n = n.namespace_uri if n
3160
+ n = '' unless n
3161
+ make_string n
3162
+ end
3163
+
3164
+ def f_name(nodeset = nil)
3165
+ unless nodeset then
3166
+ n = @node
3167
+ else
3168
+ must_be_nodeset nodeset
3169
+ n = nodeset.first
3170
+ end
3171
+ n = @visitor.visit(n) if n
3172
+ n = n.qualified_name if n
3173
+ n = '' unless n
3174
+ make_string n
3175
+ end
3176
+
3177
+
3178
+ def f_string(obj = nil)
3179
+ obj = to_nodeset unless obj
3180
+ obj.to_string self
3181
+ end
3182
+
3183
+ def f_concat(str, str2, *strs)
3184
+ s = str2.to_str.dup
3185
+ strs.each { |i| s << i.to_str }
3186
+ str.to_string(self).concat(s)
3187
+ end
3188
+
3189
+ def f_starts_with(str, sub)
3190
+ make_boolean str.to_string(self).start_with?(sub.to_str)
3191
+ end
3192
+
3193
+ def f_contains(str, sub)
3194
+ make_boolean str.to_string(self).contain?(sub.to_str)
3195
+ end
3196
+
3197
+ def f_substring_before(str, sub)
3198
+ str.to_string(self).substring_before sub.to_str
3199
+ end
3200
+
3201
+ def f_substring_after(str, sub)
3202
+ str.to_string(self).substring_after sub.to_str
3203
+ end
3204
+
3205
+ def f_substring(str, start, len = nil)
3206
+ len = len.to_number(self) if len
3207
+ str.to_string(self).substring start.to_number(self), len
3208
+ end
3209
+
3210
+ def f_string_length(str = nil)
3211
+ if str then
3212
+ str = str.to_string(self)
3213
+ else
3214
+ str = make_string(@node.string_value)
3215
+ end
3216
+ make_number str.size.to_f
3217
+ end
3218
+
3219
+ def f_normalize_space(str = nil)
3220
+ if str then
3221
+ str = str.to_string(self)
3222
+ else
3223
+ str = make_string(@node.string_value)
3224
+ end
3225
+ str.normalize_space
3226
+ end
3227
+
3228
+ def f_translate(str, from, to)
3229
+ str.to_string(self).translate from.to_str, to.to_str
3230
+ end
3231
+
3232
+
3233
+ def f_boolean(obj)
3234
+ obj.to_boolean self
3235
+ end
3236
+
3237
+ def f_not(bool)
3238
+ make_boolean(!bool.true?)
3239
+ end
3240
+
3241
+ def f_true
3242
+ make_boolean true
3243
+ end
3244
+
3245
+ def f_false
3246
+ make_boolean false
3247
+ end
3248
+
3249
+ def f_lang(str)
3250
+ lang = @visitor.visit(@node).lang
3251
+ make_boolean(lang && /\A#{Regexp.quote(str.to_str)}(?:-|\z)/i =~ lang)
3252
+ end
3253
+
3254
+
3255
+ def f_number(obj = nil)
3256
+ obj = to_nodeset unless obj
3257
+ obj.to_number self
3258
+ end
3259
+
3260
+ def f_sum(nodeset)
3261
+ must_be_nodeset nodeset
3262
+ sum = 0.0
3263
+ nodeset.each { |node|
3264
+ sum += make_string(@visitor.visit(node).string_value).to_f
3265
+ }
3266
+ make_number sum
3267
+ end
3268
+
3269
+ def f_floor(num)
3270
+ num.to_number(self).floor
3271
+ end
3272
+
3273
+ def f_ceiling(num)
3274
+ num.to_number(self).ceil
3275
+ end
3276
+
3277
+ def f_round(num)
3278
+ num.to_number(self).round
3279
+ end
3280
+
3281
+ end
3282
+
3283
+
3284
+ end