diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/packrat-lexer-combinators.adb | 52 |
1 files changed, 40 insertions, 12 deletions
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; |