summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJed Barber <jjbarber@y7mail.com>2019-01-13 20:19:48 +1100
committerJed Barber <jjbarber@y7mail.com>2019-01-13 20:19:48 +1100
commitf8cef7edffc705cc1c168620a6ba0e76a90f6366 (patch)
tree3b783cb06805b07874cc271b4a2f935355742e41 /src
parente56d6c906e876d76b9e9c0526491d5d7472a13af (diff)
Remaining lexer combinators working
Diffstat (limited to 'src')
-rw-r--r--src/packrat-lexer-combinators.adb52
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;