rexle-xpath-parser 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 696f378210d7800f7d4c79a48d6b9b12bd641209
4
- data.tar.gz: 3118e004676a3976c4685338c469eff34c347748
3
+ metadata.gz: eab4821ed8ede5bd6583130f1b8010e6be40f006
4
+ data.tar.gz: 7020ccef47cd7f31489057b3c6a7f27749e4bc3b
5
5
  SHA512:
6
- metadata.gz: 2b3611aa3dfe406a757bdb5b14c6f5bd47dc9ab14987c4695a6ac03d0ad03c31a35d43f7e3886b26c8e31caf3fd013bb8b521323064752b81a3dc6835106d7cb
7
- data.tar.gz: 9ae85c002bee277546550dcf84520ccbf168282b85e9a087417755bcfbbbb1d0302499309736031bafa623b0372793cc968cfb216599f60b004f79b6007e51fc
6
+ metadata.gz: be752255841e13d4c23bf81b501123df2d07e6887f21d27060d21cc8b92be4fb2d4c85b3ebe48bd04a5ca00a81b67869cd0e99cabd45de31e8321afa15565249
7
+ data.tar.gz: 16804a1b8ea249903b318a4b39b4e29e6cc0b972c30dc0f073e1a0aedbe3e255728230a2110d52c63d52df51f2ddb4c97fecb647951485ff85a205f5a50b1cfd
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -7,31 +7,139 @@ class RexleXPathParser
7
7
 
8
8
  attr_reader :to_a
9
9
 
10
- def initialize(s)
11
- @to_a = scan(s.clone)
10
+ def initialize(string)
11
+
12
+ tokens = tokenise string
13
+ nested_tokens = tokens.map {|x| scan(x)}
14
+ @to_a = functionalise nested_tokens
15
+
12
16
  end
13
17
 
14
- def scan(s2)
18
+ private
19
+
20
+ # maps the nested tokens to XPath functions, predicates, operators,
21
+ # and 1 or more elements
22
+ #
23
+ def functionalise(a)
15
24
 
16
- if s2.lstrip[0] == '|' then
17
- return [s2.slice!(/\s*\|\s*/).strip]
25
+ a.map do |x|
26
+
27
+ if x =~ /\w+\[/ then
28
+ epath, predicate = x.match(/^([^\[]+)\[([^\]]+)\]/).captures
29
+ epath.split('/').map {|e| [:select, e]} + [:predicate, predicate]
30
+ elsif x =~ /\|/
31
+ [:union]
32
+ elsif x =~ /\w+\(/
33
+ [x.chop.to_sym]
34
+ elsif x =~ /\d+/
35
+ [:index, x[1..-2]]
36
+ elsif x =~ /[\w\/]+/
37
+ x.split('/').map {|e| [:select, e]}
38
+ elsif x.is_a? Array
39
+ functionalise(x)
40
+ end
41
+
18
42
  end
19
43
 
20
- s1 = s2.slice!(/\w+[\(\[]/)
44
+ end
45
+
46
+ # matches a left bracket with a right bracket recursively if necessary
47
+ #
48
+ def lmatch(a, lchar, rchar)
49
+
50
+ token = []
51
+ c = a.first
52
+ token << c until (c = a.shift; c == lchar or c == rchar or a.empty?)
53
+ token << c
21
54
 
22
- if s1[-1] == '[' then
23
- s1 << s2.slice!(/[^\]]+\]|\]/)
24
- return [s1]
55
+ if c == lchar then
56
+ found, tokenx, remainderx = rmatch(a, lchar, rchar)
57
+ c = found
58
+ token << tokenx
59
+ remainder = remainderx
60
+ else
61
+ remainder = a.join
25
62
  end
26
63
 
27
- if s2[/\w+[\(\[]/] then
28
- r = [scan(s2)]
29
- r << scan(s2) while s2[/\w+[\(\[]/]
30
- s3 = s2
64
+ [c, token.join, remainder]
65
+ end
66
+
67
+ # tokeniser e.g. "a | d(c)" #=> ["a", " | ", "d(c)"]
68
+ #
69
+ def match(s)
70
+
71
+ a = []
72
+
73
+ if s =~ /^\w+\(/ then
74
+
75
+ found, token, remainder = lmatch(s.chars, '(',')')
76
+
77
+ if found == ')' then
78
+ a << token
79
+ end
80
+
81
+ elsif s =~ /^\w+\[/
82
+ found, token, remainder = lmatch(s.chars, '[',']')
83
+ a << token
31
84
  else
32
- s1 << s2.slice!(/[^\)\]]+[\)\]]|[\)\]]/)
85
+ token = s.slice!(/\w+/)
86
+ a << token
87
+ remainder = s
88
+ end
89
+
90
+ operator = remainder.slice!(/^\s*\|\s*/)
91
+
92
+ if operator then
93
+ a.concat [operator, *match(remainder)]
94
+ end
95
+
96
+ a
97
+ end
98
+
99
+ # matches a right bracket for a left bracket which has already been found.
100
+ #
101
+ def rmatch(a, lchar, rchar)
102
+
103
+ token = []
104
+ c = a.first
105
+ token << c until (c = a.shift; c == lchar or c == rchar or a.empty?)
106
+ token << c
107
+
108
+ if c == lchar then
109
+
110
+ found, tokenx, remainderx = rmatch(a, lchar, rchar)
111
+ token << tokenx
112
+
113
+ # find the rmatch for the starting token
114
+ found, tokenx, remainderx = rmatch(a, lchar, rchar)
115
+ c = found
116
+ token << tokenx
117
+ remainder = remainderx
118
+
119
+ elsif c = rchar
120
+ remainder = a.join
33
121
  end
34
122
 
35
- [s1,r,s3].compact
123
+ [c, token.join, remainder]
36
124
  end
37
- end
125
+
126
+ # accepts a token and drills into it to identify more tokens beneath it
127
+ #
128
+ def scan(s)
129
+
130
+ if s =~ /^\w+\(/ then
131
+ func = s.slice!(/\w+\(/)
132
+ remainder = s[0..-2]
133
+ if remainder =~ /^\w+\(/ then
134
+ scan(remainder)
135
+ else
136
+ [func, match(remainder)]
137
+ end
138
+ else
139
+ s
140
+ end
141
+ end
142
+
143
+ alias tokenise match
144
+
145
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rexle-xpath-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -31,7 +31,7 @@ cert_chain:
31
31
  adFNS7+S3VVpQqBQ7hIMoNW5ldGHINll6Z0dbjsCO8OFGOkrnzt9ovLffOXuQHpT
32
32
  Gpk2If0KQMuV2Q==
33
33
  -----END CERTIFICATE-----
34
- date: 2015-05-29 00:00:00.000000000 Z
34
+ date: 2015-06-04 00:00:00.000000000 Z
35
35
  dependencies: []
36
36
  description:
37
37
  email: james@r0bertson.co.uk
metadata.gz.sig CHANGED
Binary file