Skip to content

Commit

Permalink
Merge pull request #157 from chrismwendt/ignore
Browse files Browse the repository at this point in the history
Add the ability to ignore a parse result
  • Loading branch information
kschiess committed May 12, 2016
2 parents ada0344 + e07a7d7 commit ff883fc
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 37 deletions.
33 changes: 0 additions & 33 deletions example/ignore.rb

This file was deleted.

1 change: 1 addition & 0 deletions lib/parslet/atoms.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module Precedence
require 'parslet/atoms/context'
require 'parslet/atoms/dsl'
require 'parslet/atoms/base'
require 'parslet/atoms/ignored'
require 'parslet/atoms/named'
require 'parslet/atoms/lookahead'
require 'parslet/atoms/alternative'
Expand Down
2 changes: 1 addition & 1 deletion lib/parslet/atoms/can_flatten.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def flatten_repetition(list, named)
return [] if named && list.empty?

# If there are only strings, concatenate them and return that.
foldl(list) { |s,e| s+e }
foldl(list.compact) { |s,e| s+e }
end

# That annoying warning 'Duplicate subtrees while merging result' comes
Expand Down
11 changes: 11 additions & 0 deletions lib/parslet/atoms/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ def maybe
Parslet::Atoms::Repetition.new(self, 0, 1, :maybe)
end

# Returns a new parslet atom that will not show up in the output. This
# is synonymous to calling #repeat(0,1). Generated tree value will always be
# nil.
#
# Example:
# str('foo').ignore
#
def ignore
Parslet::Atoms::Ignored.new(self)
end

# Chains two parslet atoms together as a sequence.
#
# Example:
Expand Down
26 changes: 26 additions & 0 deletions lib/parslet/atoms/ignored.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Ignores the result of a match.
#
# Example:
#
# str('foo') # will return 'foo',
# str('foo').ignore # will return nil
#
class Parslet::Atoms::Ignored < Parslet::Atoms::Base
attr_reader :parslet
def initialize(parslet)
super()

@parslet = parslet
end

def apply(source, context, consume_all)
success, _ = result = parslet.apply(source, context, consume_all)

return result unless success
succ(nil)
end

def to_s_inner(prec)
"ignored(#{parslet.to_s(prec)})"
end
end
15 changes: 15 additions & 0 deletions spec/parslet/atoms/ignored_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require 'spec_helper'

describe Parslet::Atoms::Ignored do
include Parslet

describe "ignore" do
it "ignores parts of the input" do
str('a').ignore.parse('a').should == nil
(str('a') >> str('b').ignore >> str('c')).parse('abc').should == 'ac'
(str('a') >> str('b').as(:name).ignore >> str('c')).parse('abc').should == 'ac'
(str('a') >> str('b').maybe.ignore >> str('c')).parse('abc').should == 'ac'
(str('a') >> str('b').maybe.ignore >> str('c')).parse('ac').should == 'ac'
end
end
end
6 changes: 3 additions & 3 deletions website/source/index.html.textile
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ title: About
# Constructs a parser using a Parser Expression Grammar
parser = str('"') >>
(
str('\\') >> any |
str('\\').ignore >> any |
str('"').absent? >> any
).repeat.as(:string) >>
str('"')

result = parser.parse %Q("this is a valid string")
result # => {:string=>"this is a valid string"@1}
result = parser.parse %Q("this is a valid \\"string\\"")
result # => {:string=>"this is a valid \"string\""@1}
</code></pre>

A small Ruby library for constructing parsers in the
Expand Down

0 comments on commit ff883fc

Please sign in to comment.