Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

+ Consistent behaviour for .maybe and .repeat

  • Loading branch information...
commit 49dfbc475ff2b0bd9be3994f99d166d0d360c949 1 parent 418d6bb
@kschiess authored
View
3  HISTORY.txt
@@ -3,6 +3,9 @@
+ Uses throw/catch internally for an order of magnitude increase in execution
speed.
+ + str('foo').maybe will now return an empty string again. Use .as(...) to
+ name things and get back [] from #repeat and nil from #maybe.
+
= 1.0.1 / 17Jan2011
A happy new year!
View
13 lib/parslet/atoms/base.rb
@@ -169,7 +169,7 @@ def as(name)
# Takes a mixed value coming out of a parslet and converts it to a return
# value for the user by dropping things and merging hashes.
#
- def flatten(value) # :nodoc:
+ def flatten(value, named=false) # :nodoc:
# Passes through everything that isn't an array of things
return value unless value.instance_of? Array
@@ -184,9 +184,9 @@ def flatten(value) # :nodoc:
when :sequence
return flatten_sequence(result)
when :maybe
- return result.first
+ return named ? result.first : result.first || ''
when :repetition
- return flatten_repetition(result)
+ return flatten_repetition(result, named)
end
fail "BUG: Unknown tag #{tag.inspect}."
@@ -221,7 +221,7 @@ def merge_fold(l, r) # :nodoc:
fail "Unhandled case when foldr'ing sequence."
end
- def flatten_repetition(list) # :nodoc:
+ def flatten_repetition(list, named) # :nodoc:
if list.any? { |e| e.instance_of?(Hash) }
# If keyed subtrees are in the array, we'll want to discard all
# strings inbetween. To keep them, name them.
@@ -236,8 +236,11 @@ def flatten_repetition(list) # :nodoc:
flatten(1)
end
+ # Consistent handling of empty lists, when we act on a named result
+ return [] if named && list.empty?
+
# If there are only strings, concatenate them and return that.
- list.inject('') { |s,e| s<<(e||'') }
+ list.inject('') { |s,e| s<<e }
end
def self.precedence(prec) # :nodoc:
View
4 lib/parslet/atoms/named.rb
@@ -15,7 +15,7 @@ def initialize(parslet, name) # :nodoc:
def apply(source, context) # :nodoc:
value = parslet.apply(source, context)
-
+
return value if value.error?
success(
produce_return_value(
@@ -31,6 +31,6 @@ def error_tree # :nodoc:
end
private
def produce_return_value(val) # :nodoc:
- { name => flatten(val) }
+ { name => flatten(val, true) }
end
end
View
25 spec/parslet/atom_results_spec.rb
@@ -17,8 +17,15 @@
[str('a').as(:a) >> (str('b') >> str('c').as(:a)).repeat, 'abc',
[{:a=>'a'}, {:a=>'c'}]],
- [str('a').as(:a).repeat >> str('b').as(:b).repeat, 'ab', [{:a=>'a'}, {:b=>'b'}]]
+ [str('a').as(:a).repeat >> str('b').as(:b).repeat, 'ab', [{:a=>'a'}, {:b=>'b'}]],
+ # Repetition behaviour / named vs. unnamed
+ [str('f').repeat, '', ''],
+ [str('f').repeat.as(:f), '', {:f => []}],
+
+ # Maybe behaviour / named vs. unnamed
+ [str('f').maybe, '', ''],
+ [str('f').maybe.as(:f), '', {:f => nil}],
].each do |parslet, input, result|
context "#{parslet.inspect}" do
it "should parse \"#{input}\" into \"#{result}\"" do
@@ -26,21 +33,5 @@
end
end
end
-
end
-
- let(:foo) { str('foo') }
- describe "foo.maybe" do
- let(:parslet) { foo.maybe }
-
- context "when given no matching input" do
- subject { parslet.parse('') }
- it { should == nil }
- end
- context "when matching" do
- subject { parslet.parse('foo') }
- it { should == 'foo' }
- end
- end
-
end
View
2  spec/parslet/atoms_spec.rb
@@ -106,7 +106,7 @@ def src(str); Parslet::Source.new str; end
context "when parsing ''" do
subject { parslet.parse('') }
- it { should == nil }
+ it { should == '' }
end
end
describe "str('foo') >> str('bar')" do
Please sign in to comment.
Something went wrong with that request. Please try again.