src/parsnim

    Dark Mode
Search:
Group by:
  Source   Edit

Types

ParseError = object of ValueError
  Source   Edit
ParseFn[T; R] = proc (s: var State[T]): Result[R]
function defined to manipulate State for the next parser and return a result   Source   Edit
Parser[T; R] = object fn*: ParseFn[T, R] description*: string 
central object to wrap all ParseFns in   Source   Edit
Result[T] = object of RootObj kind*: ResultType ## states whether the result is a `Match` or `Failure` value*: Stream[T] ## `Parser`s translate from one stream to another hence result values are `Stream`s start_index*, end_index*: int ## start and end indices for the value/expected tag*: seq[string] ## an optional seq of strings that can be used to mark results for further processing description*: string ## describes what the value would represent. used when erroring on failed parsing expected*: Stream[T] ## for failures, what value wanted to be. used when erroring on failed parsing 
Result objects are returned by all parsers   Source   Edit
ResultType = enum Match, Failure
  Source   Edit
State[T] = object index*: int stream*: Stream[T] 
object passed to all parsers to track position and the stream being parsed   Source   Edit
Stream[T] = seq[T]
Stream is an alias for seq[T]   Source   Edit

Procs

proc `$`(parser: Parser): string
  Source   Edit
proc `$`(state: State): string
  Source   Edit
proc `and`[T, R](parser, other: Parser[T, R]): Parser[T, R]
parser and other must both match at the current position in the stream
let p = test_proc(proc(c: char): auto = parseInt($c)>2, "greater than 2") and test_proc(proc(c: char): auto = parseInt($c)<= 10, "less than or equal to 10") echo p echo p.parse("4") # <Parser: greater than 2 and less than or equal to 10> # @['4'] p.parse("1") # Error: unhandled exception: failed to parse with error: Expected `greater than 2` got @['1'] @ 0:1 [ParseError]
  Source   Edit
proc `not`[T, R](parser: Parser[T, R]): Parser[T, R]
inverts a Result so that a failure is instead a match and vice-versa
let p = not test_char('c') echo p echo p.parse("p") # <Parser: not char c> # @['p']
  Source   Edit
proc `or`[T, R](parser, other: Parser[T, R]): Parser[T, R]
parser or other must match
let p = test_char('c') or test_char('p') echo p echo p.parse("p") # <Parser: char c or char p> # @['p']
  Source   Edit
proc anything[T]()
  Source   Edit
proc at_least(parser: Parser; n: int): auto
finds parser at least n times   Source   Edit
proc at_most(parser: Parser; n: int): auto
finds parser up to n times   Source   Edit
proc describe(parser: var Parser; desc: string): Parser
describe a parser   Source   Edit
proc failure[T](start_index, end_index: int; description: string): Result[T]
function to generate Failure Results without an expected value   Source   Edit
proc failure[T](start_index, end_index: int; expected: Stream[T]; description: string): Result[T]
function to generate Failure Results with an expected value   Source   Edit
proc many(parser: Parser): Parser
finds parser until it doesn't
let t = (test_char('c')).many().then(test_char('p')) echo t echo t.parse("ccccp") # <Parser: char c many times then char p> # @['c', 'c', 'c', 'c', 'p']
  Source   Edit
proc map[T, R, NR](parser: Parser[T, R]; item: NR): Parser[T, NR]
takes a parser that goes from Stream[T]->Stream[R] and transforms it to Stream[T]->Stream[NR]   Source   Edit
proc map[T, R, NR](parser: Parser[T, R]; map_fn: proc (x: R): NR): Parser[T, NR]
takes a parser that goes from Stream[T]->Stream[R] and transforms it to Stream[T]->Stream[NR]   Source   Edit
proc map[T, R, NR](parser: Parser[T, R]; map_fn: proc (x: seq[R]): seq[NR]): Parser[ T, NR]
takes a parser that goes from Stream[T]->Stream[R] and transforms it to Stream[T]->Stream[NR]   Source   Edit
proc nothing[T]()
  Source   Edit
proc optional(parser: Parser): auto
tries to find parser and if not continues   Source   Edit
proc pad(parser: Parser[char, char]): Parser[char, char] {. ...raises: [ValueError, RegexError], tags: [].}
optional whitespace
echo test_char('c').pad.parse("c ") # @['c']
  Source   Edit
proc pad(parser: Parser[char, string]): Parser[char, string] {. ...raises: [ValueError, RegexError], tags: [].}
optional whitespace
echo test_string("hello").pad.parse("hello ") # @["hello"]
  Source   Edit
proc parse[char, R](parser: Parser[char, R]; stream: string): Stream[R]
run a parser on a stream that is a string   Source   Edit
proc parse[T, R](parser: Parser[T, R]; stream: Stream[T]): Stream[R]
run a parser on a stream   Source   Edit
proc parse_partial[T, R](parser: Parser[T, R]; state: var State[T]): Result[R]
  Source   Edit
proc parse_partial[T, R](parser: Parser[T, R]; stream: Stream[T]): Result[R]
  Source   Edit
proc skip[T, R](parser, other: Parser[T, R]): Parser[T, R]
parses parser then other but ignores other result   Source   Edit
proc space(parser: Parser[char, char]): Parser[char, char] {. ...raises: [ValueError], tags: [].}
optional whitespace
echo test_char('c').space.parse("c ") # @['c']
  Source   Edit
proc space(parser: Parser[char, string]): Parser[char, string] {. ...raises: [ValueError], tags: [].}
optional whitespace
let p = test_string("9").space echo p.parse("9") # @["9"]
  Source   Edit
proc str[T](parser: Parser[T, char]): Parser[T, string]
  Source   Edit
proc success[T](start_index, end_index: int; value: Stream[T]; description: string): Result[T]
function to generate Match Results   Source   Edit
proc tag[T, R](parser: Parser[T, R]; tag: string): Parser[T, R]
creates a parser that tags parser results   Source   Edit
proc test_char(test: char): Parser[char, char] {....raises: [], tags: [].}
test if a char is next in the stream (usually a string for char test)   Source   Edit
proc test_item[T](test: T; description: string): auto
test if a single test item is next in the stream   Source   Edit
proc test_proc[T](test_proc_var: proc (x: T): bool; description: string): Parser[ T, T]
tests a procedure against the next value in the stream
let p = test_proc(proc(c: char): auto = parseInt($c)>2, "greater than 2") echo p echo p.parse("4") # <Parser: greater than 2> # @['4']
  Source   Edit
proc test_proc[T](test_proc_var: proc (x: T): bool; description: string; expected: T): Parser[T, T]
tests a procedure against the next value in the stream
let p = test_proc(proc(c: char): auto = c== '4', "the character '4'", "'4'") echo p echo p.parse("4") # <Parser: the character '4'> # @['4']
  Source   Edit
proc test_regex(pattern: Regex; description: string): Parser[char, string] {. ...raises: [ValueError], tags: [].}
tests if a regex pattern is next in a stream
let r = test_regex(re"[a-zA-Z_][a-zA-Z0-9_]*", "identifier") echo r echo r.parse("_hello1984") # <Parser: regex identifier> # @["_hello1984"]
  Source   Edit
proc test_regex_string(pattern: Regex; description: string): Parser[string, string] {....raises: [], tags: [].}
  Source   Edit
proc test_seq[T](test_seq: Stream[T]; description: string): Parser[T, T]
tests if the test_seq is the next sequence of the state's stream

let t = test_seq("abc".to_seq, "alphabet") echo t echo t.parse("abc") # <Parser: alphabet> # @['a', 'b', 'c']

  Source   Edit
proc test_string(test: string): auto {....raises: [ValueError], tags: [].}
tests if a string is next in a stream (special case of test_seq)

let t = test_string("abc") echo t echo t.parse("abc") # <Parser: string abc> # @["abc"]

  Source   Edit
proc then[T, R](parser, other: Parser[T, R]): Parser[T, R]
parses parser then other and rolls them together

let t = test_char('c').then(test_char('p')) echo t echo t.parse("cp") # <Parser: char c then char p> # @['c', 'p']

  Source   Edit
proc times[T, R](parser: Parser[T, R]; min: int; max: int = -1): Parser[T, R]
looks for parser to repeat >=min and <=max times
let t = (not test_char('c')).times(3) echo t echo t.parse("abd") # <Parser: not char c 3 times> # @['a', 'b', 'd']
  Source   Edit
proc until[T, R](self, parser: Parser[T, R]): Parser[T, R]
looks for the current parser self until parser matches
let p = (test_char('c')).until(test_char('p')) echo p echo p.parse("ccccp") # <Parser: char c until not char c> # @['c', 'c', 'c', 'c', 'p']
  Source   Edit

Converters

converter to_bool(res: Result): bool
Results are truthy/falsey   Source   Edit