Skip to content

Commit

Permalink
feat(combinators): add the ability to ignore a combinator's output in…
Browse files Browse the repository at this point in the history
… a group
  • Loading branch information
moxvallix committed May 20, 2023
1 parent c67bfcb commit a80ccf9
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 8 deletions.
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ GEM
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.1)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.2)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.3)
rspec-mocks (3.12.5)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.0)
Expand Down
9 changes: 6 additions & 3 deletions lib/parsby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def start(p)
end

def end(p)
Parsby.new("splicer.end(#{p.label})") { |c|
Parsby.new("splicer.end(#{p.label})", p.ignore) { |c|
begin
p.parse c
ensure
Expand Down Expand Up @@ -600,12 +600,14 @@ def label
end

attr_writer :label
attr_accessor :ignore

# Initialize parser with optional label argument, and parsing block. The
# parsing block is given an IO as argument, and its result is the result
# when parsing.
def initialize(label = nil, &b)
def initialize(label = nil, ignore = false, &b)
self.label = label if label
self.ignore = ignore
@parser = b
end

Expand Down Expand Up @@ -706,7 +708,8 @@ def <<(p)
x = parse c
y = p.parse c
# like x << y, but without modifying x.
x + [y]
# return x if it is ignored
p.ignore ? x : x + [y]
end
end

Expand Down
5 changes: 3 additions & 2 deletions lib/parsby/combinators.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ def define_combinator(name, wrap: true, &b)
# Lambda used to access private module method from instance method.
inspectable_labels_lambda = lambda {|x| inspectable_labels(x) }

define_method name do |*args, &b2|
define_method name do |*args, ignore: false, &b2|
inspected_args = inspectable_labels_lambda.call(args).map(&:inspect)
label = name.to_s
label += "(#{inspected_args.join(", ")})" unless inspected_args.empty?
# Wrap in new parser so we don't overwrite another automatic
# label.
p = m.bind(self).call(*args, &b2)
if wrap
Parsby.new(label) {|c| p.parse c }
Parsby.new(label, ignore) {|c| p.parse c }
else
p.ignore = ignore
p % label
end
end
Expand Down

0 comments on commit a80ccf9

Please sign in to comment.