aboutsummaryrefslogtreecommitdiff
path: root/src/__OLD_parcom/parser.cr
diff options
context:
space:
mode:
authorMatthew Hall <hallmatthew314@gmail.com>2023-03-16 20:36:03 +1300
committerMatthew Hall <hallmatthew314@gmail.com>2023-03-16 20:36:03 +1300
commitb274828831fec26cd8b3089ffef14cb96ce2de2f (patch)
treeff5927b85a59b4d85c9e4aa269a475a7a37a54a0 /src/__OLD_parcom/parser.cr
parent77c370d27be174e0b036b33d1469e84e67a7153a (diff)
Second rewrite attempt, this one should work, monkaS
Diffstat (limited to 'src/__OLD_parcom/parser.cr')
-rw-r--r--src/__OLD_parcom/parser.cr87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/__OLD_parcom/parser.cr b/src/__OLD_parcom/parser.cr
new file mode 100644
index 0000000..ca350df
--- /dev/null
+++ b/src/__OLD_parcom/parser.cr
@@ -0,0 +1,87 @@
+require "../parcom.cr"
+
+module Parcom
+ # `Parser` is the base class of all parser objects and contains
+ # a handful of helper methods that can allow for cleaner syntax.
+ #
+ # The generic type `T` represents the type of tokens a parser will
+ # operate on (usually `Char`).
+ # The generic type `V` represents the type of value that a parser
+ # will return when parsing is successful.
+ abstract class Parser(T, V)
+ # Accepts a `Tokens(T)` and either retuns a `Result(T, V)`, or raises a
+ # `ParserFail` exception with a message providing context of where
+ # in the chain the parsing failed.
+ #
+ # The `V` in the returned `Result` is arbitrary, but the `Tokens(T)` in
+ # the returned result MUST contain the parser's input, with some tokens
+ # removed from the front proprtional to what was parsed.
+ #
+ # Example:
+ # ```
+ # hello = ParsesHello.new # inherits from Parser(Char, String)
+ # input = Tokens.from_string("Hello world!")
+ #
+ # result = hello.parse(input)
+ # result.value # => "Hello"
+ # result.tokens # => [' ', 'w', 'o', 'r', 'l', 'd', '!']
+ #
+ # bad_input = Tokens.from_string("Good evening world!")
+ # hello.parse(bad_input) # raises ParserFail
+ # ```
+ abstract def parse(tokens : Tokens(T)) : Result(T, V)
+
+ # Same as `#parse`, but returns `nil` instead of raising `ParserFail`.
+ def parse?(tokens : Tokens(T)) : Result(T, V)?
+ self.parse(tokens)
+ rescue ParserFail
+ return nil
+ end
+
+ # Constructs an `Alt` parser with `self` and `other`.
+ def |(other : Parser(T, V)) : Alt(T, V)
+ Alt.new(self, other)
+ end
+
+ # Constructs a `Plus` parser with `self` and `other`.
+ def +(other : Parser(T, U)) : Plus(T, V, U) forall U
+ Plus.new(self, other)
+ end
+
+ # Constructs a `Left` parser with `self` and `other`.
+ def <<(other : Parser(T, U)) : Left(T, V, U) forall U
+ Left.new(self, other)
+ end
+
+ # Constructs a `Right` parser with `self` and `other`.
+ def >>(other : Parser(T, U)) : Right(T, V, U) forall U
+ Right.new(self, other)
+ end
+
+ # Constructs an `Assert` parser with `self` and the given block.
+ def assert(&block : V -> Bool) : Assert(T, V)
+ Assert.new(self, &block)
+ end
+
+ # Constructs an `Assert` parser with `self` and the given proc.
+ def assert(f : V -> Bool) : Assert(T, V)
+ Assert.new(self, &f)
+ end
+
+ # Constructs a `Map` parser with `self` and the given block.
+ def map(&block : V -> U) : Map(T, V, U) forall U
+ Map.new(self, &block)
+ end
+
+ # Constructs a `Map` parser with `self` and the given proc.
+ def map(f : V -> U) : Map(T, V, U) forall U
+ Map.new(self, &f)
+ end
+
+ # Constructs a `Recover` parser with `self` and the given `V`.
+ def recover(default : V) : Recover(T, V)
+ Recover.new(self, default)
+ end
+ end
+end
+