From f8cef7edffc705cc1c168620a6ba0e76a90f6366 Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Sun, 13 Jan 2019 20:19:48 +1100 Subject: Remaining lexer combinators working --- src/packrat-lexer-combinators.adb | 52 ++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/packrat-lexer-combinators.adb b/src/packrat-lexer-combinators.adb index 6405efb..1090398 100644 --- a/src/packrat-lexer-combinators.adb +++ b/src/packrat-lexer-combinators.adb @@ -65,26 +65,23 @@ package body Packrat.Lexer.Combinators is return Empty_Fail; end if; loop + exit when Position > Input'Last; Temp := Param (Input, Position); - exit when Temp.Status = Failure; - if Temp.Status = Needs_More then - Result.Status := Optional_More; - exit; - end if; + exit when Temp.Status = Failure or Temp.Status = Needs_More; Result := Result.Join (Temp); Counter := Counter + 1; Position := Start + Result.Length; - if Position > Input'Last then - Result.Status := Optional_More; - exit; - end if; end loop; if Counter < Minimum then - if Result.Status = Optional_More then + if Position > Input'Last or Temp.Status = Needs_More then Result.Status := Needs_More; else Result.Status := Failure; end if; + elsif Position > Input'Last or Temp.Status = Needs_More then + Result.Status := Optional_More; + else + Result.Status := Success; end if; return Result; end Many; @@ -93,9 +90,40 @@ package body Packrat.Lexer.Combinators is function Many_Until (Input : in Element_Array; Start : in Positive) - return Combinator_Result is + return Combinator_Result + is + Result : Combinator_Result := Create_Result (0, Success, Empty_Array); + Temp : Combinator_Result; + Position : Positive := Start; + Counter : Natural := 0; begin - return Empty_Fail; + if Start > Input'Last then + return Empty_Fail; + end if; + loop + exit when Position > Input'Last; + Temp := Param (Input, Position); + exit when Temp.Status = Failure or Temp.Status = Needs_More or Test (Input (Position)); + Result := Result.Join (Temp); + Counter := Counter + 1; + Position := Start + Result.Length; + end loop; + if Counter < Minimum then + if Position > Input'Last or Temp.Status = Needs_More then + Result.Status := Needs_More; + else + Result.Status := Failure; + end if; + elsif Position > Input'Last then + Result.Status := Needs_More; + elsif Temp.Status = Needs_More and Test (Input (Position)) then + Result.Status := Optional_More; + elsif Test (Input (Position)) then + Result.Status := Success; + else + Result.Status := Failure; + end if; + return Result; end Many_Until; -- cgit