src/easyparse

Types

ParsingError = object of ValueError
  Source Edit
Position = object
  line*: int
  column*: int
  Source Edit
ParseState[S] = object
  source*: seq[S]
  pos*: int
  position*: Position
  Source Edit
ParseError[S] = object
  unexpected*: string
  expected*: seq[string]
  state*: ParseState[S]
  message*: string
  Source Edit
ResultKind = enum
  Success, Error
  Source Edit
ParseResult[S; T] = object
  case kind*: ResultKind
  of Success:
      value*: T
      state*: ParseState[S]

  of Error:
      error*: ParseError[S]

  
  Source Edit
Parser[S; T] = ParseState[S] -> ParseResult[S, T]
  Source Edit
EitherKind = enum
  Result, Exception
  Source Edit
Either[R; E] = object
  case kind*: EitherKind
  of Result:
      value*: R

  of Exception:
      error*: E

  
  Source Edit
ParseOut[S; T] = object
  result*: T
  rest*: seq[S]
  Source Edit
Unit = tuple[]

Unit is a void-like type that eof returns, because void exposes some "edge cases" in the compiler.

  Source Edit

Lets

letter: Parser[char, char] = satisfy(isAlphaAscii, @["letter"])
letter matches ascii letter a-zA-Z.   Source Edit
digit: Parser[char, char] = satisfy(isDigit, @["digit"])
digit matches ascii digits 0-9.   Source Edit
unit: Unit = ()
unit is the only inhabitant of the Unit type.   Source Edit
anyChar: Parser[char, char] = satisfy(proc (t: char): bool = result = true,
                                      @["anychar"])
anyChar matches any character   Source Edit

Procs

proc newline(S: typedesc): S:type {...}{.inline.}
  Source Edit
proc err[S, T](R: type ParseResult[S, T]; x: auto): R:type {...}{.inline.}
Set the result to an error.   Source Edit
proc ok[S, T](R: type ParseResult[S, T]; state: ParseState[S]; value: T): R:type {...}{.
    inline.}
Set the result to a Success   Source Edit
proc isOk[S, T](res: ParseResult[S, T]): bool {...}{.inline.}
  Source Edit
proc isErr[S, T](res: ParseResult[S, T]): bool {...}{.inline.}
  Source Edit
proc next[S](state: ParseState[S]): ParseState[S] {...}{.inline.}
Advances the parse state by a single character   Source Edit
proc parse[S, T](parser: Parser[S, T]; source: seq[S]): Either[ParseOut[S, T],
    ParseError[S]] {...}{.inline.}
Applies a given parser to the source and returns an Either type.   Source Edit
proc debugParse[T](parser: Parser[char, T]; source: string): string {...}{.inline.}
Used for debugging, returns a string of a tuple   Source Edit
proc parseOrRaise[T](parser: Parser[char, T]; source: string): T {...}{.
    raises: [ParsingError].}
parseOrRaise either returns the parsed element or raises an exception   Source Edit
proc ch(ch: char): Parser[char, char] {...}{.inline, raises: [], tags: [].}
ch matches a single character.   Source Edit
proc eof[S](): Parser[S, Unit] {...}{.inline.}
eof matches only the end of the input sequence, and in this case returns unit.   Source Edit
proc failure[S, R](): Parser[S, R] {...}{.inline.}
failure is a parser that always fails and returns an error   Source Edit
proc ifthenelse[S, R](condition: Parser[S, bool]; iftrue: Parser[S, R];
                      iffalse: Parser[S, R]): Parser[S, R] {...}{.inline.}
ifthenelse uses the condition parser, and takes one of the two branch depending on the parsed result.   Source Edit
proc sepBy1[S, R, T](parser: Parser[S, R]; separator: Parser[S, T]): Parser[S,
    seq[R]]
sepBy1 matches multiple occurrences of parser separated by separator. Parser must match with at least one occurrence.   Source Edit
proc sepBy[S, R, T](parser: Parser[S, R]; separator: Parser[S, T]): Parser[S,
    seq[R]]
sepBy matches multiple occurrences of parser separated by separator. Separators are discarded, and a sequence of parsers are returned.   Source Edit

Funcs

func satisfy[S](predicate: S -> bool; expected: seq[string] = @[]): Parser[S, S] {...}{.
    inline.}
satisfy matches a single object that satisfies the given predicate.   Source Edit
func optional[S, T](parser: Parser[S, T]): Parser[S, Option[T]] {...}{.inline.}
An optional parser returns an Option type if parser doesn't match.   Source Edit
func choice[S, T](parsers: openArray[Parser[S, T]]): Parser[S, T] {...}{.inline.}
choice returns the first of parsers that matches or an error otherwise.   Source Edit
func fmap[S, T, R](fn: T -> R; parser: Parser[S, T]): Parser[S, R]
fmap applies fn to the result returned by parser   Source Edit
func many[S, T](parser: Parser[S, T]): Parser[S, seq[T]] {...}{.inline.}

many applies parser zero or more times until it matches and collects the obtained result into a sequence.

To avoid infinite loops the parser stops (and returns an empty sequence) if the enclosing parser returns a result without advancing the state position.

  Source Edit
func `<|>`[S, T](p1: Parser[S, T]; p2: Parser[S, T]): Parser[S, T] {...}{.inline.}
<|> is an infix operator that acts as choice between two parsers   Source Edit
func pure[S, T](value: T): Parser[S, T] {...}{.inline.}
pure returns a parser that always returns the constant value.   Source Edit
func liftA2[S, T, R, U](f: (T, R) -> U; p0: Parser[S, T]; p1: Parser[S, R]): Parser[
    S, U] {...}{.inline.}
liftA2 matches both parsers and applies f to the result.   Source Edit
func `*>`[S, T, R](p0: Parser[S, T]; p1: Parser[S, R]): Parser[S, R] {...}{.inline.}
*> matches both parsers and returns the result of the second one.   Source Edit
func `<*`[S, T, R](p0: Parser[S, T]; p1: Parser[S, R]): Parser[S, T] {...}{.inline.}
<* matches both parsers and returns the result of the first one.   Source Edit
func oneOf[S](possibilities: seq[S]): Parser[S, S] {...}{.inline.}
oneOf matches a single element between those passed in the sequence.   Source Edit
func oneOf(possibilities: string): Parser[char, char] {...}{.inline, raises: [],
    tags: [].}
oneOf for a string divides the string into characters and then uses that standard oneOf.   Source Edit
func toSeq[S, T](parser: Parser[S, T]): Parser[S, seq[T]] {...}{.inline.}
toSeq wraps the returned element from parser into a single-item sequence.   Source Edit
func many1[S, T](parser: Parser[S, T]): Parser[S, seq[T]] {...}{.inline.}
many1 matches parser one or more times.   Source Edit
func `<?>`[S, T](parser: Parser[S, T]; name: string): Parser[S, T] {...}{.inline.}
<?> gives a name to the parser that augments the error messages given.   Source Edit
func canparse[S, T](parser: Parser[S, T]): Parser[S, bool] {...}{.inline.}
canparse tries to match parser and it returns true if a match occurred and false on error. The state is reset prior to the matching, so that one can do canparse('a') *> many('a').   Source Edit
func `<*>`[S, T, R](prec: Parser[S, proc (i0: T): R]; next: Parser[S, T]): Parser[
    S, R] {...}{.inline.}
<*> matches prec and next and then applies the result of prec to that of next.   Source Edit

Macros

macro parseApply(S: untyped; T: untyped; f: untyped; parsers: varargs[untyped]): untyped

parseApply uses the parsers one after the others and their parsed results are used as arguments to f. Here f must have len(parsers) arguments and return type T, while all parsers must be of type Parser[S, *].

typeof parser[i] == Parser[S, U_i] typeof f == (U_0, ..., U_n) -> T Resulting output: Parser[S, T]

  Source Edit

Templates

template err[R; E; ](A: type Either[R, E]; x: auto): A:type
  Source Edit
template ok[R; E; ](A: type Either[R, E]; x: auto): A:type
  Source Edit