diff --git a/R/parsers_basic.R b/R/parsers_basic.R index 309221a..343daa4 100644 --- a/R/parsers_basic.R +++ b/R/parsers_basic.R @@ -17,7 +17,7 @@ #' that contains the parser result of the consumed part of the input vector and #' the 'right' or `R`-element that contains the unconsumed part of the vector. #' Since the outcome of succeed does not depend on its input, its result value -#' must be pre-determined, so it is included as an extra parameter. +#' must be pre-determined, so it is included as a parameter. #' #' While `succeed` never fails, `fail` always does, regardless of the input #' vector. It returns the empty list `list()` to signal this fact. @@ -37,7 +37,10 @@ #' #' @param left any R-object constructed from a parsed vector. #' @returns A list. `succeed()` returns a list with two elements named `L` and -#' `R`. `fail()` returns an empty list. +#' `R`. `fail()` returns a `marker` object which is basically an empty list +#' with a line number `n` as attribute. It is printed as the icon `[]`, +#' see [print.marker()]. Note that `n` will only correctly represent the line +#' number of failure when a parser is wrapped in the [reporter()] function. #' #' @export #' @examples @@ -61,10 +64,10 @@ fail <- function(lnr=LNR()) { function(x) new_marker(lnr) } -#' The parser that matches an element using a predicate function +#' Matching input using a logical function #' #' @description -#' `satisfy()` turns a predicate function into a parser that recognizes strings. +#' `satisfy()` turns a logical function into a parser that recognizes strings. #' #' @details #' Notice (see pseudocode) that `satisfy` fails when presented with empty @@ -106,7 +109,7 @@ satisfy <- function(b) { } } -#' The parser that matches an element using a literal string +#' Matching parser input with a literal string #' #' @description #' `literal` tests whether a supplied string literally equals a desired value. @@ -119,7 +122,8 @@ satisfy <- function(b) { #' where `F` is equivalent to the `function` declarator in R. So, we have an #' anonymous function in the argument of `satisfy`. #' -#' @param string string, a single-element character vector. +#' @param string string, a single-element character vector, or an object that +#' can be coerced to a character vector. #' @inherit satisfy return #' @export #' @examples @@ -168,7 +172,7 @@ eof <- function() { # Above we made the basic building blocks. We consider how they should be put # together to form useful parsers. -#' The parser of alternative parsers +#' Applying alternative parsers #' #' @description #' The `%or%` combinator `(p1 %or% p2)` returns the result of `p1` if `p1` is @@ -210,11 +214,11 @@ eof <- function() { } } -#' The parser of sequences of parsers +#' Applying parsers in sequence #' #' @description #' -#' `(p1 %then% p2)` recognizes anything that `p1` and `p2` would if placed in +#' `(p1 %then% p2)` recognizes anything that `p1` and `p2` would if applied in #' succession. #' #' @section Pseudocode: @@ -252,7 +256,7 @@ eof <- function() { } } -#' Manipulate results from a parser by applying a function +#' Applying a function to the result of a parser #' #' @description #' The `%using%` combinator allows us to manipulate results from a parser. The @@ -282,15 +286,15 @@ eof <- function() { } } -#' Keeping only the left or right result from a `%then%` sequence +#' Keeping only first or second result from a `%then%` sequence #' -#' @details -#' Recall that two parsers composed in sequence produce a pair of results. -#' Sometimes we are only interested in one component of the pair. For example, -#' it is common to throw away reserved words such as 'begin' and 'where' during -#' parsing. In such cases, two special versions of the `%then%` combinator are -#' useful, which throw away either the left or right result values, as reflected -#' by the position of the letter 'x' in their names. +#' @description +#' Two parsers composed in sequence produce a pair of results. Sometimes we are +#' only interested in one component of the pair. For example in the case of +#' reserved words such as 'begin' and 'end'. In such cases, two special +#' versions of the `%then%` combinator are useful, which keep either the +#' first or second result, as reflected by the position of the letter 'x' in +#' their names. #' #' @section Pseudocode: #' @@ -316,9 +320,9 @@ eof <- function() { #' #' @examples #' is_number <- function(x) grepl("\\d+",x[1]) -#' # Numbers are preceded by ">" symbols, but we only need the number itself +#' # Numbers are preceded by ">" symbols, but we only want the number #' (literal(">") %thenx% satisfy(is_number)) (c(">", "12")) -#' # Temperatures are followed by the unit 'C', but we only need the number +#' # Temperatures are followed by the unit 'C', but we only want the number #' (satisfy(is_number) %xthen% literal("C")) (c("21", "C")) #' `%xthen%` <- function(p1, p2) { @@ -349,7 +353,7 @@ eof <- function() { } } -#' Return a fixed value upon successful parsing +#' Return a fixed value instead of the result of a parser #' #' @description #' Sometimes we are not interested in the result from a parser, only that the @@ -384,23 +388,29 @@ eof <- function() { } } -## Iterated application of parsers. +## Repeaters -#' Parsers that repeat application of a parser +#' Repeated application of a parser #' #' @description -#' Often, a structure that can be parsed by a parser `p` occurs several times -#' in row in a file, or the parser can be applied zero or more times. The -#' following combinators test these conditions. +#' Often, we want to assess whether a given structure can be successfully +#' parsed through repetitive application of a parser `p`. This could involve +#' testing the parser applied multiple times in succession or determining +#' its capability to be applied zero or more times. +#' +#' The subsequent functions are designed to address and evaluate these +#' scenarios. #' #' @details -#' All these parsers except `match_n` are greedy. This means that they try to -#' apply `p` as many times as possible. If that number of times is not equal to -#' what was expected, for example if `p` can successfully parse more than `n` -#' times in `exactly(n,p)`, then the parser will fail. In contrast, -#' `match_n(n,p)` will apply `p` `n` times and no more, even if `p` could be -#' successfully applied more often. Clearly, both functions will fail if `p` -#' leads to failure after less than `n` repetitions. +#' All these parsers with the excception of `match_n` exhibit greedy behavior +#' striving to apply `p` as many times as possible. If the resulting count +#' doesn't match the expected quantity, such as in the case of `exactly(n,p)` +#' where `p` successfully parses more than `n` times, then the parser fails. +#' In contrast, `match_n(n,p)` strictly applies `p` exactly `n` times, +#' preventing any further application of `p` even if `p` could potentially be +#' applied more often. Clearly, both functions will fail if `p` fails after +#' less than `n` repetitions. +#' #' #' #' @param p a parser. @@ -506,7 +516,7 @@ match_n <- function(n, p) { } } -#' The parser that identifies a string and produces custom output +#' Identifying and processing a string and producing custom output #' #' `match_s` matches a string using a function and returns a desired object #' type. diff --git a/R/parsers_error.R b/R/parsers_error.R index ec11953..4032fe0 100644 --- a/R/parsers_error.R +++ b/R/parsers_error.R @@ -1,4 +1,4 @@ -#' Turn a parser into an error reporting parser. +#' Turn a parser into an error reporting parser #' #' Turns a parser into an error reporting parser, and when the parser is #' successful returns only the `L`-element of the parser output, the diff --git a/man/grapes-or-grapes.Rd b/man/grapes-or-grapes.Rd index 3af6079..cbebe24 100644 --- a/man/grapes-or-grapes.Rd +++ b/man/grapes-or-grapes.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/parsers_basic.R \name{\%or\%} \alias{\%or\%} -\title{The parser of alternative parsers} +\title{Applying alternative parsers} \usage{ p1 \%or\% p2 } diff --git a/man/grapes-ret-grapes.Rd b/man/grapes-ret-grapes.Rd index 5c1044e..93390e6 100644 --- a/man/grapes-ret-grapes.Rd +++ b/man/grapes-ret-grapes.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/parsers_basic.R \name{\%ret\%} \alias{\%ret\%} -\title{Return a fixed value upon successful parsing} +\title{Return a fixed value instead of the result of a parser} \usage{ p \%ret\% c } diff --git a/man/grapes-then-grapes.Rd b/man/grapes-then-grapes.Rd index 906531d..3953c82 100644 --- a/man/grapes-then-grapes.Rd +++ b/man/grapes-then-grapes.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/parsers_basic.R \name{\%then\%} \alias{\%then\%} -\title{The parser of sequences of parsers} +\title{Applying parsers in sequence} \usage{ p1 \%then\% p2 } @@ -13,7 +13,7 @@ p1 \%then\% p2 A parser. } \description{ -\code{(p1 \%then\% p2)} recognizes anything that \code{p1} and \code{p2} would if placed in +\code{(p1 \%then\% p2)} recognizes anything that \code{p1} and \code{p2} would if applied in succession. } \section{Pseudocode}{ diff --git a/man/grapes-using-grapes.Rd b/man/grapes-using-grapes.Rd index 12f9941..e5dd993 100644 --- a/man/grapes-using-grapes.Rd +++ b/man/grapes-using-grapes.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/parsers_basic.R \name{\%using\%} \alias{\%using\%} -\title{Manipulate results from a parser by applying a function} +\title{Applying a function to the result of a parser} \usage{ p \%using\% f } diff --git a/man/grapes-xthen-grapes.Rd b/man/grapes-xthen-grapes.Rd index 0764d4e..40837fc 100644 --- a/man/grapes-xthen-grapes.Rd +++ b/man/grapes-xthen-grapes.Rd @@ -3,7 +3,7 @@ \name{\%xthen\%} \alias{\%xthen\%} \alias{\%thenx\%} -\title{Keeping only the left or right result from a \verb{\%then\%} sequence} +\title{Keeping only first or second result from a \verb{\%then\%} sequence} \usage{ p1 \%xthen\% p2 @@ -16,15 +16,12 @@ p1 \%thenx\% p2 A parser. } \description{ -Keeping only the left or right result from a \verb{\%then\%} sequence -} -\details{ -Recall that two parsers composed in sequence produce a pair of results. -Sometimes we are only interested in one component of the pair. For example, -it is common to throw away reserved words such as 'begin' and 'where' during -parsing. In such cases, two special versions of the \verb{\%then\%} combinator are -useful, which throw away either the left or right result values, as reflected -by the position of the letter 'x' in their names. +Two parsers composed in sequence produce a pair of results. Sometimes we are +only interested in one component of the pair. For example in the case of +reserved words such as 'begin' and 'end'. In such cases, two special +versions of the \verb{\%then\%} combinator are useful, which keep either the +first or second result, as reflected by the position of the letter 'x' in +their names. } \section{Pseudocode}{ @@ -48,9 +45,9 @@ without the first element and without the first two elements, respectively. \examples{ is_number <- function(x) grepl("\\\\d+",x[1]) -# Numbers are preceded by ">" symbols, but we only need the number itself +# Numbers are preceded by ">" symbols, but we only want the number (literal(">") \%thenx\% satisfy(is_number)) (c(">", "12")) -# Temperatures are followed by the unit 'C', but we only need the number +# Temperatures are followed by the unit 'C', but we only want the number (satisfy(is_number) \%xthen\% literal("C")) (c("21", "C")) } diff --git a/man/literal.Rd b/man/literal.Rd index 328de22..aef82fc 100644 --- a/man/literal.Rd +++ b/man/literal.Rd @@ -2,12 +2,13 @@ % Please edit documentation in R/parsers_basic.R \name{literal} \alias{literal} -\title{The parser that matches an element using a literal string} +\title{Matching parser input with a literal string} \usage{ literal(string) } \arguments{ -\item{string}{string, a single-element character vector.} +\item{string}{string, a single-element character vector, or an object that +can be coerced to a character vector.} } \value{ A parser. diff --git a/man/match_s.Rd b/man/match_s.Rd index 97a73ec..d6d2fc0 100644 --- a/man/match_s.Rd +++ b/man/match_s.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/parsers_basic.R \name{match_s} \alias{match_s} -\title{The parser that identifies a string and produces custom output} +\title{Identifying and processing a string and producing custom output} \usage{ match_s(s) } diff --git a/man/reporter.Rd b/man/reporter.Rd index b2b12b9..a4ed422 100644 --- a/man/reporter.Rd +++ b/man/reporter.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/parsers_error.R \name{reporter} \alias{reporter} -\title{Turn a parser into an error reporting parser.} +\title{Turn a parser into an error reporting parser} \usage{ reporter(p) } diff --git a/man/satisfy.Rd b/man/satisfy.Rd index ac736dc..a668b96 100644 --- a/man/satisfy.Rd +++ b/man/satisfy.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/parsers_basic.R \name{satisfy} \alias{satisfy} -\title{The parser that matches an element using a predicate function} +\title{Matching input using a logical function} \usage{ satisfy(b) } @@ -13,7 +13,7 @@ satisfy(b) A parser. } \description{ -\code{satisfy()} turns a predicate function into a parser that recognizes strings. +\code{satisfy()} turns a logical function into a parser that recognizes strings. } \details{ Notice (see pseudocode) that \code{satisfy} fails when presented with empty diff --git a/man/succeed.Rd b/man/succeed.Rd index 1a25f65..cf397ac 100644 --- a/man/succeed.Rd +++ b/man/succeed.Rd @@ -17,7 +17,10 @@ occurs} } \value{ A list. \code{succeed()} returns a list with two elements named \code{L} and -\code{R}. \code{fail()} returns an empty list. +\code{R}. \code{fail()} returns a \code{marker} object which is basically an empty list +with a line number \code{n} as attribute. It is printed as the icon \verb{[]}, +see \code{\link[=print.marker]{print.marker()}}. Note that \code{n} will only correctly represent the line +number of failure when a parser is wrapped in the \code{\link[=reporter]{reporter()}} function. } \description{ These are the most basic constructors of a parser, but they are important @@ -29,7 +32,7 @@ The \code{succeed} parser constructs a \code{list} object with a 'left' or \code that contains the parser result of the consumed part of the input vector and the 'right' or \code{R}-element that contains the unconsumed part of the vector. Since the outcome of succeed does not depend on its input, its result value -must be pre-determined, so it is included as an extra parameter. +must be pre-determined, so it is included as a parameter. While \code{succeed} never fails, \code{fail} always does, regardless of the input vector. It returns the empty list \code{list()} to signal this fact. diff --git a/man/zero_or_more.Rd b/man/zero_or_more.Rd index 7c7e850..b72863d 100644 --- a/man/zero_or_more.Rd +++ b/man/zero_or_more.Rd @@ -6,7 +6,7 @@ \alias{exactly} \alias{zero_or_one} \alias{match_n} -\title{Parsers that repeat application of a parser} +\title{Repeated application of a parser} \usage{ zero_or_more(p) @@ -27,18 +27,23 @@ match_n(n, p) A parser. } \description{ -Often, a structure that can be parsed by a parser \code{p} occurs several times -in row in a file, or the parser can be applied zero or more times. The -following combinators test these conditions. +Often, we want to assess whether a given structure can be successfully +parsed through repetitive application of a parser \code{p}. This could involve +testing the parser applied multiple times in succession or determining +its capability to be applied zero or more times. + +The subsequent functions are designed to address and evaluate these +scenarios. } \details{ -All these parsers except \code{match_n} are greedy. This means that they try to -apply \code{p} as many times as possible. If that number of times is not equal to -what was expected, for example if \code{p} can successfully parse more than \code{n} -times in \code{exactly(n,p)}, then the parser will fail. In contrast, -\code{match_n(n,p)} will apply \code{p} \code{n} times and no more, even if \code{p} could be -successfully applied more often. Clearly, both functions will fail if \code{p} -leads to failure after less than \code{n} repetitions. +All these parsers with the excception of \code{match_n} exhibit greedy behavior +striving to apply \code{p} as many times as possible. If the resulting count +doesn't match the expected quantity, such as in the case of \code{exactly(n,p)} +where \code{p} successfully parses more than \code{n} times, then the parser fails. +In contrast, \code{match_n(n,p)} strictly applies \code{p} exactly \code{n} times, +preventing any further application of \code{p} even if \code{p} could potentially be +applied more often. Clearly, both functions will fail if \code{p} fails after +less than \code{n} repetitions. } \section{Pseudocode}{