dolos 0.1.2 → 0.1.3

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: 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.