factbase 0.0.2 → 0.0.4

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
  SHA256:
3
- metadata.gz: 870d9d422444751180a6e69d1be17c9f89ac46e168d7fc1023e7df22829f9134
4
- data.tar.gz: 21e5886fc43c7f297a5f0dd4070d738efb4d6b2ff1f1b9d261d0007bf9ce483d
3
+ metadata.gz: dc21a8440801909645bc06e200ca9b238ab899f6ecd5ef422eec4d082fdbbfaf
4
+ data.tar.gz: 05fb34e5249ec11dd0cddcfe74888d89a3343c44afada52926f720c102804321
5
5
  SHA512:
6
- metadata.gz: 91992d0fe70646084d7da8091ca5659a3f1aa64c474cfbf328278d40b0e5bc56233abb3b316435660ca3522afd3af275c29291b4f178136ef0544cf173a6d243
7
- data.tar.gz: 97c605569af192e7f6960c0bac50777134acb917aa2085b6195d89be95687cde606084569db351025c7c0d4472247feb5f394af1e346a9f14c6af7d5422c2242
6
+ metadata.gz: 6c72854f13afe4af7be6a232c12c60025cd9d286559940e96a0ebd9decf748e13e8db4993bffe64f8416d3c03cd20f9a491c06c55434bdba2f53c32edd7d7410
7
+ data.tar.gz: e44f1b7c3c83f207ead55e5aed42844eb98dd53ee6ef5241be0e0931cbe7670dc0c6103c002ce6a4a7cbc8818784de6c7f600a7102d91a20a2dcc732a62fc5d7
@@ -20,7 +20,6 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- require 'cgi'
24
23
  require_relative 'fact'
25
24
  require_relative 'term'
26
25
 
@@ -38,7 +37,9 @@ class Factbase::Syntax
38
37
  def to_term
39
38
  @tokens ||= to_tokens
40
39
  @ast ||= to_ast(@tokens, 0)
41
- @ast[0]
40
+ term = @ast[0]
41
+ raise 'No terms found' if term.nil?
42
+ term
42
43
  end
43
44
 
44
45
  private
@@ -51,6 +52,7 @@ class Factbase::Syntax
51
52
  # is the term/literal and the second one is the position where the
52
53
  # scanning should continue.
53
54
  def to_ast(tokens, at)
55
+ raise "Closing too soon at ##{at}" if tokens[at] == :close
54
56
  return [tokens[at], at + 1] unless tokens[at] == :open
55
57
  at += 1
56
58
  op = tokens[at]
@@ -58,8 +60,11 @@ class Factbase::Syntax
58
60
  operands = []
59
61
  at += 1
60
62
  loop do
63
+ raise "End of token stream at ##{at}" if tokens[at].nil?
61
64
  break if tokens[at] == :close
62
65
  (operand, at1) = to_ast(tokens, at)
66
+ raise "Stuck at position ##{at}" if at == at1
67
+ raise "Jump back at position ##{at}" if at1 < at
63
68
  at = at1
64
69
  operands << operand
65
70
  break if tokens[at] == :close
@@ -70,7 +75,19 @@ class Factbase::Syntax
70
75
  def to_tokens
71
76
  list = []
72
77
  acc = ''
78
+ string = false
73
79
  @query.to_s.chars.each do |c|
80
+ if ['\'', '"'].include?(c)
81
+ if string && acc[acc.length - 1] == '\\'
82
+ acc = acc[0..-2]
83
+ else
84
+ string = !string
85
+ end
86
+ end
87
+ if string
88
+ acc += c
89
+ next
90
+ end
74
91
  if !acc.empty? && [' ', ')'].include?(c)
75
92
  list << acc
76
93
  acc = ''
@@ -86,11 +103,12 @@ class Factbase::Syntax
86
103
  acc += c
87
104
  end
88
105
  end
106
+ raise 'String not closed' if string
89
107
  list.map do |t|
90
108
  if t.is_a?(Symbol)
91
109
  t
92
- elsif t.start_with?('\'')
93
- CGI.unescapeHTML(t[1..-2])
110
+ elsif t.start_with?('\'', '"')
111
+ t[1..-2]
94
112
  elsif t.match?(/^[0-9]+$/)
95
113
  t.to_i
96
114
  else
data/lib/factbase/term.rb CHANGED
@@ -44,7 +44,7 @@ class Factbase::Term
44
44
  items << @op
45
45
  items += @operands.map do |o|
46
46
  if o.is_a?(String)
47
- "'#{o}'"
47
+ "'#{o.gsub("'", "\\\\'").gsub('"', '\\\\"')}'"
48
48
  else
49
49
  o.to_s
50
50
  end
data/lib/factbase.rb CHANGED
@@ -26,7 +26,7 @@
26
26
  # License:: MIT
27
27
  class Factbase
28
28
  # Current version of the library and of this class.
29
- VERSION = '0.0.2'
29
+ VERSION = '0.0.4'
30
30
 
31
31
  # Constructor.
32
32
  def initialize
@@ -48,15 +48,14 @@ class Factbase
48
48
 
49
49
  # Create a query capable of iterating.
50
50
  #
51
- # There is a Lisp-like syntax, for example (all string literals
52
- # must be HTML-escaped):
51
+ # There is a Lisp-like syntax, for example:
53
52
  #
54
- # (eq title 'Object&#20;Thinking')
53
+ # (eq title 'Object Thinking')
55
54
  # (gt time '2024-03-23T03:21:43')
56
55
  # (gt cost 42)
57
56
  # (exists seenBy)
58
57
  # (and
59
- # (eq foo '42')
58
+ # (eq foo 42)
60
59
  # (or
61
60
  # (gt bar 200)
62
61
  # (absent zzz)))
@@ -29,12 +29,23 @@ require_relative '../../lib/factbase/syntax'
29
29
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
30
30
  # License:: MIT
31
31
  class TestSyntax < Minitest::Test
32
+ def test_parses_string_right
33
+ [
34
+ "(foo 'abc')",
35
+ "(foo 'one two')",
36
+ "(foo 'one two three ')",
37
+ "(foo 'one two three ' 'tail tail')"
38
+ ].each do |q|
39
+ assert_equal(q, Factbase::Syntax.new(q).to_term.to_s)
40
+ end
41
+ end
42
+
32
43
  def test_simple_parsing
33
44
  [
34
45
  '()',
35
46
  '(foo)',
36
47
  '(foo (bar) (zz 77) )',
37
- "(eq foo 'Hello,&#x20;world!')",
48
+ "(eq foo 'Hello, world!')",
38
49
  "(or ( a 4) (b 5) () (and () (c 5) (r 7 8s 8is 'Foo')))"
39
50
  ].each do |q|
40
51
  Factbase::Syntax.new(q).to_term
@@ -46,10 +57,12 @@ class TestSyntax < Minitest::Test
46
57
  '(foo)',
47
58
  '(foo 7)',
48
59
  "(foo 7 'Dude')",
60
+ "(r 'Dude\\'s Friend')",
61
+ "(r 'I\\'m \\\"good\\\"')",
49
62
  '(foo x y z)',
50
63
  "(foo x y z t f 42 'Hi!' 33)",
51
64
  '(foo (x) y z)',
52
- "(foo (x (f (t (y 42 'Hey'))) (f) (r 3)) y z)"
65
+ "(foo (x (f (t (y 42 'Hey you'))) (f) (r 3)) y z)"
53
66
  ].each do |q|
54
67
  assert_equal(q, Factbase::Syntax.new(q).to_term.to_s)
55
68
  end
@@ -64,9 +77,29 @@ class TestSyntax < Minitest::Test
64
77
  {
65
78
  '(eq z 1)' => true,
66
79
  '(or (eq bar 888) (eq z 1))' => true,
67
- "(or (gt bar 100) (eq foo 'Hello,&#x20;world!'))" => true
80
+ "(or (gt bar 100) (eq foo 'Hello, world!'))" => true
68
81
  }.each do |k, v|
69
82
  assert_equal(v, Factbase::Syntax.new(k).to_term.matches?(m), k)
70
83
  end
71
84
  end
85
+
86
+ def test_broken_syntax
87
+ [
88
+ '',
89
+ '(foo',
90
+ '"hello, world!',
91
+ '(foo 7',
92
+ "(foo 7 'Dude'",
93
+ '(foo x y z (',
94
+ '(foo x y (z t (f 42 ',
95
+ ')foo ) y z)',
96
+ ")y 42 'Hey you)",
97
+ ')',
98
+ '"'
99
+ ].each do |q|
100
+ assert_raises do
101
+ Factbase::Syntax.new(q).to_term
102
+ end
103
+ end
104
+ end
72
105
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko