aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parcom.cr36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/parcom.cr b/src/parcom.cr
index 2a61c2d..f0295a3 100644
--- a/src/parcom.cr
+++ b/src/parcom.cr
@@ -67,6 +67,14 @@ module Parcom
Plus.new(self, other)
end
+ def <<(other : Parser(T, U)) : Left(T, V, U) forall U
+ Left.new(self, other)
+ end
+
+ def >>(other : Parser(T, U)) : Right(T, V, U) forall U
+ Right.new(self, other)
+ end
+
def assert(f : V -> Bool)
Assert.new(self, &f)
end
@@ -233,6 +241,34 @@ module Parcom
end
end
+ class Left(T, V, U) < Parser(T, V)
+ @p : Map(T, {V, U}, V)
+
+ def initialize(p1 : Parser(T, V), p2 : Parser(T, U))
+ @p = (p1 + p2).map(&.first)
+ end
+
+ def parse(tokens : TokenStream(T)) : Result(T, V)
+ @p.parse(tokens)
+ rescue ex : ParserException
+ raise ParserException.new("Left: #{ex.message}")
+ end
+ end
+
+ class Right(T, V, U) < Parser(T, U)
+ @p : Map(T, {V, U}, U)
+
+ def initialize(p1 : Parser(T, V), p2 : Parser(T, U))
+ @p = (p1 + p2).map(&.last)
+ end
+
+ def parse(tokens : TokenStream(T)) : Result(T, U)
+ @p.parse(tokens)
+ rescue ex : ParserException
+ raise ParserException.new("Right: #{ex.message}")
+ end
+ end
+
class Recover(T, V) < Parser(T, V)
@p : Map(T, V?, V)