lib/dolos/parsers.rb in dolos-0.2.0 vs lib/dolos/parsers.rb in dolos-0.2.1
- old
+ new
@@ -1,21 +1,22 @@
# frozen_string_literal: true
module Dolos
module Parsers
def string(str)
+ utf8_str = str.encode('UTF-8')
+
Parser.new do |state|
state.input.mark_offset
- utf8_str = str.encode('UTF-8')
if state.input.matches?(utf8_str)
Success.new(utf8_str, str.bytesize)
else
advanced = state.input.offset
got_error = state.input.io.string.byteslice(state.input.backup, advanced)
state.input.rollback
Failure.new(
- "Expected #{str.inspect} but got #{got_error.inspect}",
+ -> { "Expected #{str.inspect} but got #{got_error.inspect}" },
advanced,
state
)
end
end
@@ -30,11 +31,11 @@
Success.new(matched_string, matched_string.bytesize)
else
advanced = state.input.offset
state.input.rollback
Failure.new(
- "Expected pattern #{pattern.inspect} but got #{state.input.io.string.inspect}",
+ -> { "Expected pattern #{pattern.inspect} but got #{state.input.io.string.inspect}" },
advanced,
state
)
end
end
@@ -50,11 +51,11 @@
Success.new(char, char.bytesize)
else
advanced = state.input.offset
state.input.rollback
Failure.new(
- 'Expected any character but got end of input',
+ -> { 'Expected any character but got end of input' },
advanced,
state
)
end
end
@@ -62,24 +63,24 @@
# Matches any character in a string
# Example:
# char_in('abc').run('b') # => Success.new('b', 1)
def char_in(characters_string)
- characters_array = characters_string.chars
+ characters_set = characters_string.chars
Parser.new do |state|
state.input.mark_offset
char, bytesize = state.input.peek(1)
- if char && characters_array.include?(char)
+ if char && characters_set.include?(char)
Success.new(char, bytesize)
else
advanced = state.input.offset
state.input.rollback
Failure.new(
- "Expected one of #{characters_array.inspect} but got #{char.inspect}",
+ -> { "Expected one of #{characters_set.to_a.inspect} but got #{char.inspect}" },
advanced,
state
)
end
end
@@ -88,49 +89,46 @@
def char_while(predicate)
Parser.new do |state|
state.input.mark_offset
buffer = String.new
- loop do
- char, bytesize = state.input.peek(1)
- break if char.nil? || !predicate.call(char)
+ char, bytesize = state.input.peek(1)
+ while char && predicate.call(char)
buffer << char
state.input.advance(bytesize)
+ char, bytesize = state.input.peek(1)
end
if buffer.empty?
advanced = state.input.offset
Failure.new(
- "Predicate never returned true",
+ -> { "Predicate never returned true" },
advanced,
state
)
else
Success.new(buffer, 0)
end
end
end
- # Unstable API
def recursive(&block)
recursive_parser = nil
placeholder = Parser.new do |state|
raise "Recursive parser accessed before it was initialized!" if recursive_parser.nil?
recursive_parser.call.run_with_state(state).tap do |result|
if result.failure?
- error_msg = "Error in recursive structure around position #{state.input.offset}: #{result.message}"
+ error_msg = -> { "Error in recursive structure around position #{state.input.offset}: #{result.message}" }
Failure.new(error_msg, state.input.offset, state)
end
end
end
recursive_parser = -> { block.call(placeholder) }
placeholder
end
-
-
end
end