From 982d239252b54297ff3558894038871f8d3a4175 Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Fri, 17 Mar 2023 22:50:14 +1300 Subject: Please work this time --- src/parcom.cr | 83 ----------------------------------------------------------- 1 file changed, 83 deletions(-) (limited to 'src/parcom.cr') diff --git a/src/parcom.cr b/src/parcom.cr index ffa5654..8387752 100644 --- a/src/parcom.cr +++ b/src/parcom.cr @@ -77,88 +77,5 @@ module Parcom map(block) end end - - # A parser defines a process of extracting some sort of data - # from a stream of tokens. - # `Parser` objects wrap a function/block that accepts a `Tokens` object, - # and either returns a `Result`, or raises a `ParserFail`. - # This struct also defines a handful of methods for modifying a parser's - # behavior. - # - # The function that is wrapped by a parser should: - # 1. Have the type `Tokens(T) -> Result(T, U)` - # 1. Indicate failure by raising a `ParserFail` - # 1. Not introduce side-effects - # - # Instead of inheriting from `Parser`, custom parsers should be - # defined using a method that generates the parser directly: - # ``` - # struct Foo(T, U) < Parser(T, Array(U)) - # def parse(tokens) - # # This will cause headaches - # end - # end - # - # # Do this instead: - # def foo(t : T.class, u : U.class, p : Parser(T, U)) : Parser(T, U) forall T, U - # Parser(T, U).new("Foo") { |tokens| "your code here" } - # end - # ``` - struct Parser(T, U) - getter name - - def initialize(@name : String, @f : Tokens(T) -> Result(T, U)) - end - - def initialize(@name : String, &block : Tokens(T) -> Result(T, U)) - @f = block - end - - # Changes the `name` property and returns `self`. - # This should be used to specify a custom name: - # ``` - # a = Basic.token(Char, 'a').named("letter a") - # ``` - def named(name : String) : self - @name = name - self - end - - def parse(tokens : Tokens(T)) : Result(T, U) - @f.call(tokens) - end - - def parse?(tokens : Tokens(T)) : Result(T, U)? - parse(tokens) - rescue - nil - end - - def assert(f : U -> Bool) : Parser(T, U) - p = self - Parser.new("#{p.name} (assertion)") do |tokens| - result = p.parse(tokens) - unless f.call(r.value) - raise ParserFail.new("Assertion failed for value #{r.value}") - end - result - end - end - - def assert(&block : U -> Bool) : Parser(T, U) - assert(block) - end - - def map(f : U -> T) : Parser(T, V) forall V - p = self - Parser(T, V).new("#{p.name} (mapped)") do |tokens| - p.parse(tokens).map(f) - end - end - - def map(&block : U -> T) : Parser(T, V) forall V - map(block) - end - end end -- cgit v1.2.1