dolos 0.1.2 → 0.1.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68d26c878ffd86122b9c12273645cf351f5b20d6e1306e140c53727c29e49b2b
4
- data.tar.gz: 6bda399416128f5692e2966a46194591209f61602408e6873cb4e41f37a22ec4
3
+ metadata.gz: c8a83a078e5fa82aa8f6d28f3315597937b84c604d59e18f177a950594860e93
4
+ data.tar.gz: bccf5fc9390189e43ef9c785baeaf93b85e00d1ce480c63057cf0cc26c468050
5
5
  SHA512:
6
- metadata.gz: 7ae6b3a4750cc5bfb5f54a84d518f8d4176eaf10dfef4482f45aaadc3db422a14f04cabb65ee0e1fe85b7dfb95fa1b54c8daf4f91083f4f39beac32c70c25616
7
- data.tar.gz: e4ab436619a690d257fdaba829fcbc00ec74c56cd8fda0c754fd5f1985fe2d3b21adcda1db69f7ca116437ccf8cf9c6455f03cb05ab44b8107033db590266398
6
+ metadata.gz: 75fcc5acf6a6dfbd4eeaf7493f9f82a3d31b5d6b61c64f2d9ee3f6f7fe8856fa1392866cbde95ba12bdb06155f07ed7c9cfe46c24f4353c111bf3782f6033289
7
+ data.tar.gz: '0608ddcb140a18c1d156ae8729f4c998b1abe4b257be8e02dddff796a3e7d861892ddfebcc6f54b744e9b03d381ed029ad81954b2ff484cc2621d5b7f804d3cb'
data/README.md CHANGED
@@ -113,6 +113,10 @@ pp result.captures
113
113
  # {:building=>"8"}, {:postcode=>"01121"}, {:city=>"Vilnius"}]
114
114
 
115
115
  ```
116
+ ### Roadmap
117
+ - Better error handling
118
+ - Recursive parser
119
+ - Benchmarks & parser tests
116
120
 
117
121
  ### Contributing
118
122
  Contributors are welcome. Note: since library is not yet stable, I recommend getting in touch with me before starting to work on something.
@@ -3,10 +3,12 @@
3
3
  module Dolos
4
4
  class ParserState
5
5
  attr_reader :input
6
+ attr_accessor :last_success_position
6
7
 
7
8
  def initialize(input)
8
9
  @input = StringIOWrapper.new(input)
10
+ @last_success_position = 0
9
11
  end
10
12
  end
11
-
12
13
  end
14
+
data/lib/dolos/parsers.rb CHANGED
@@ -10,14 +10,17 @@ module Dolos
10
10
  Success.new(utf8_str, str.bytesize)
11
11
  else
12
12
  advanced = state.input.offset
13
+ got_error = state.input.io.string.byteslice(state.input.backup, advanced)
13
14
  state.input.rollback
14
15
  Failure.new(
15
- "Expected #{str.inspect} but got #{state.input.io.string.inspect}",
16
- advanced
16
+ "Expected #{str.inspect} but got #{got_error.inspect}",
17
+ advanced,
18
+ state
17
19
  )
18
20
  end
19
21
  end
20
22
  end
23
+
21
24
  alias_method :c, :string
22
25
 
23
26
  def regex(pattern)
@@ -30,13 +33,13 @@ module Dolos
30
33
  state.input.rollback
31
34
  Failure.new(
32
35
  "Expected pattern #{pattern.inspect} but got #{state.input.io.string.inspect}",
33
- advanced
36
+ advanced,
37
+ state
34
38
  )
35
39
  end
36
40
  end
37
41
  end
38
42
 
39
-
40
43
  def any_char
41
44
  Parser.new do |state|
42
45
  state.input.mark_offset
@@ -48,7 +51,11 @@ module Dolos
48
51
  else
49
52
  advanced = state.input.offset
50
53
  state.input.rollback
51
- Failure.new('Expected any character but got end of input', advanced)
54
+ Failure.new(
55
+ 'Expected any character but got end of input',
56
+ advanced,
57
+ state
58
+ )
52
59
  end
53
60
  end
54
61
  end
@@ -71,7 +78,8 @@ module Dolos
71
78
  state.input.rollback
72
79
  Failure.new(
73
80
  "Expected one of #{characters_array.inspect} but got #{char.inspect}",
74
- advanced
81
+ advanced,
82
+ state
75
83
  )
76
84
  end
77
85
  end
@@ -92,7 +100,11 @@ module Dolos
92
100
 
93
101
  if buffer.empty?
94
102
  advanced = state.input.offset
95
- Failure.new("Predicate never returned true", advanced)
103
+ Failure.new(
104
+ "Predicate never returned true",
105
+ advanced,
106
+ state
107
+ )
96
108
  else
97
109
  Success.new(buffer, 0)
98
110
  end
data/lib/dolos/result.rb CHANGED
@@ -40,18 +40,37 @@ module Dolos
40
40
  end
41
41
 
42
42
  class Failure < Result
43
- attr_reader :message, :committed
43
+ attr_reader :message, :error_position, :state
44
44
 
45
- def initialize(message, committed)
45
+ def initialize(message, error_position, state)
46
46
  @message = message
47
- @committed = committed
47
+ @error_position = error_position
48
+ @state = state
48
49
  end
49
50
 
50
51
  def inspect
52
+ pretty_print
53
+ end
54
+
55
+ def pretty_print
56
+ input_string = state.input.io.string
57
+
58
+ pointer = "^" # This will point to the error position
59
+
60
+ context_range = 10 # Chars before and after the error to display
61
+
62
+ start_index = [error_position - context_range, 0].max
63
+ end_index = [error_position + context_range, input_string.length].max
64
+
65
+ substring = input_string[start_index..end_index]
66
+
67
+ padding = error_position - start_index
68
+
51
69
  [
52
- "Failure",
53
- "message: #{message}",
54
- "committed: #{committed}"
70
+ "Failure: #{message}",
71
+ substring,
72
+ "#{' ' * padding}#{pointer}",
73
+ "Error Position: #{error_position}, Last Success Position: #{state.last_success_position}"
55
74
  ].join("\n")
56
75
  end
57
76
 
@@ -22,7 +22,6 @@ module Dolos
22
22
 
23
23
  def matches?(utf8_str)
24
24
  read = io.read(utf8_str.bytesize)
25
- io.seek(offset)
26
25
 
27
26
  if read.nil?
28
27
  false
data/lib/dolos/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dolos
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.3"
5
5
  end
data/lib/dolos.rb CHANGED
@@ -22,7 +22,11 @@ module Dolos
22
22
  end
23
23
 
24
24
  def run_with_state(state)
25
- parser_proc.call(state)
25
+ result = parser_proc.call(state)
26
+ if result.success?
27
+ state.last_success_position = state.input.offset
28
+ end
29
+ result
26
30
  end
27
31
 
28
32
  def capture!
@@ -112,6 +116,7 @@ module Dolos
112
116
  values = []
113
117
  captures = []
114
118
  count = 0
119
+ state.input.mark_offset
115
120
 
116
121
  while count < n_max
117
122
  result = run_with_state(state.dup)
@@ -125,7 +130,12 @@ module Dolos
125
130
  end
126
131
 
127
132
  if count < n_min
128
- Failure.new("Expected parser to match at least #{n_min} times but matched only #{count} times", false)
133
+ error_pos = state.input.offset
134
+ Failure.new(
135
+ "Expected parser to match at least #{n_min} times but matched only #{count} times",
136
+ error_pos,
137
+ state
138
+ )
129
139
  else
130
140
  Success.new(values, 0, captures)
131
141
  end
@@ -1,6 +1,7 @@
1
1
  module Dolos
2
2
  class ParserState
3
3
  attr_reader input: Dolos::StringIOWrapper
4
+ attr_accessor last_success_position: Integer
4
5
 
5
6
  def initialize: (String) -> void
6
7
  end
data/sig/dolos/result.rbs CHANGED
@@ -16,6 +16,7 @@ module Dolos
16
16
 
17
17
  class Failure < Result[bot]
18
18
  attr_reader committed: bool
19
+ attr_reader error_position: Integer
19
20
  attr_reader message: String
20
21
 
21
22
  def captures: -> []
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dolos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - benetis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-16 00:00:00.000000000 Z
11
+ date: 2023-08-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Parser combinators library for Ruby. In active development, not stable
14
14
  yet.