Commits

Pasberth Usbean  committed 7f95af4

one_of try

  • Participants
  • Parent commits 2451626

Comments (0)

Files changed (6)

File lib/regparsec/parser/combinators.rb

-class RegParsec::Regparsers::ApplyParser < RegParsec::Regparsers::Base
+module RegParsec::Regparseable
+
+  def try *regparsers, &result_proc
+    ::RegParsec::Regparsers::TryParser.new.curry!(*regparsers, &result_proc)
+  end
+
+  def apply *regparsers, &result_proc
+    ::RegParsec::Regparsers::ApplyParser.new.curry!(*regparsers, &result_proc)
+  end
+
+  def one_of *regparsers, &result_proc
+    ::RegParsec::Regparsers::OneOfParser.new.curry!(*regparsers, &result_proc)
+  end
+end
+
+module RegParsec::Regparsers
+
+class TryParser < Base
+  
+  def __regparse__ state, doing
+    state.commit!
+    case result = doing.regparse(state)
+    when Result::Success
+      result
+    else
+      state.backdate!
+      result
+    end
+  end
+end
+
+class ApplyParser < Base
 
   def __regparse__ state, *regparsers
     consumed = ''
       when Result::Success
         consumed << result.matching_string
         list << result.return_value
-        state.input.sub!(result.matching_string, '')
       when Result::Accepted
         consumed << result.matching_string
         list << result.return_value
         return Result::Invalid.new
       end
     end
-    state.backdate!
     
     Result::Success.new( :return_value => list, :matching_string => consumed )
   end
 end
 
-module RegParsec::Regparseable
-  def apply *regparsers, &result_proc
-    ::RegParsec::Regparsers::ApplyParser.new.curry!(*regparsers, &result_proc)
+class OneOfParser < Base
+  
+  def __regparse__ state, *choices
+    choices.any? do |a|
+      case result = try(a).regparse(state)
+      when Result::Success, Result::Accepted then return result
+    # when Result::Accepted then true
+      else false
+      end
+    end or Invalid.new
   end
+end
 end

File lib/regparsec/parser/primary_parsers.rb

 
   def __regparse__ state, expecting
     if state.input[0, expecting.length] == expecting
+      state.input.sub!(expecting, '')
       Result::Success.new( :return_value => expecting, :matching_string => expecting )
     elsif expecting[0, state.input.length] == state.input
       Result::Accepted.new( :return_value => state.input, :matching_string => state.input )

File lib/regparsec/regparser.rb

     end
     
     return_value = [].tap do |list|
-      buf = ""
-      while line = input.gets or !buf.empty?
-        buf << line if line
-        case result = @regparser.regparse(buf)
+      state.input = ""
+      state.commit!
+      while line = input.gets or !state.input.empty?
+        state.input << line if line
+        case result = @regparser.regparse(state)
         when Result::Success then
-          buf = buf.sub(result.matching_string, '')
+          state.commit!
           consumed << result.matching_string
           list << result.return_value
         when Result::Accepted then line ? next : break

File lib/regparsec/state_attributes.rb

-require 'regparsec'
-
 module RegParsec::StateAttributesHelpers
   
   def try_convert_into_state_attributes! attributes

File spec/regparsers/one_of_spec.rb

+require 'spec_helper'
+
+describe RegParsec::Regparsers::OneOfParser do
+  subject { described_class.new.curry!("abc", "def") }
+
+  example { subject.parse("abc").should == "abc" }
+  example { subject.regparse("abc").should == ::RegParsec::Result::Success.new( :return_value => "abc", :matching_string => "abc" ) }
+  example { subject.parse("a").should == nil }
+  example { subject.regparse("a").should == ::RegParsec::Result::Accepted.new( :return_value => "a", :matching_string => "a" ) }
+  example { subject.parse("def").should == "def" }
+  example { subject.regparse("def").should == ::RegParsec::Result::Success.new( :return_value => "def", :matching_string => "def" ) }
+  example { subject.parse("d").should == nil }
+  example { subject.regparse("d").should == ::RegParsec::Result::Accepted.new( :return_value => "d", :matching_string => "d" ) }
+  example { subject.regparse("abcdef").should == ::RegParsec::Result::Success.new( :return_value => "abc", :matching_string => "abc" ) }
+  example { subject.parse("abcdef").should == "abc" }
+  example { subject.regparse("defabc").should == ::RegParsec::Result::Success.new( :return_value => "def", :matching_string => "def" ) }
+  example { subject.parse("defabc").should == "def" }
+end

File spec/regparsers/try_spec.rb

Empty file added.