Review of Parser library begins today
Marshall Clow via Boost-announce <[email protected]> Mon, 19 Feb 2024 08:33:26 -0800
| Newsgroups | gmane.comp.lib.boost.announce |
|---|---|
| Message-ID | <C453DC7E-F43E-4E59-99B2-BEE83A730C68__46955.7084654056$1708360530$gmane$org@gmail.com> |
--===============7879121084963786495== Content-Type: multipart/alternative; boundary="Apple-Mail=_19AA5CFE-5FE4-46DE-9F29-E26694DED6C7" --Apple-Mail=_19AA5CFE-5FE4-46DE-9F29-E26694DED6C7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 The review of Zach Laine=E2=80=99s proposed Boost.Parser library begins = today and will end on February 28th. =46rom the introduction page of the documentation: Boost.Parser is a parser combinator library. That is, it consists of a = set of low-level primitive parsers, and operations that can be used to = combine those parsers into more complicated parsers. There are primitive parsers that parse epsilon (the empty string), = chars, ints, floats, etc. There are operations which combine parsers to create new parsers. For = instance, the Kleene star operation takes an existing parser p and = creates a new parser that matches zero or more occurrences of whatever p = matches. Both callable objects and operator overloads are used for the = combining operations. For instance, operator*() is used for Kleene star, = and you can also write repeat(n)[p] to create a parser for exactly n = repetitions of p. Boost.Parser also tries to accommodate the multiple ways that people = often want to get a parse result out of their parsing code. Some parsing = may best be done by returning an object that represents the result of = the parse. Other parsing may best be done by filling in a preexisting = data structure. Yet other parsing may best be done by parsing small = sections of a large document, and reporting the results of subparsers as = they are finished, via callbacks. Boost.Parser accommodates all these = ways of working, and even makes it possible to do callback-based or = non-callback-based parsing without rewriting any code (except by = changing the top-level call from parse() to callback_parse()). All of Boost.Parser's public interfaces are sentinel- and = range-friendly, just like the interfaces in std::ranges. Boost.Parser is Unicode-aware through and through. When you parse ranges = of char, Boost.Parser does not assume any particular encoding =E2=80=94 = not Unicode or any other encoding. Parsing of inputs other than plain = chars assumes that the input is Unicode. In the Unicode-aware code = paths, all parsing is done by matching code points. This means that you = can feed UTF-8 strings into Boost.Parser, both as input and within your = parser, and the right sort of matching occurs. For instance, if your = parser is trying to match repetitions of the char '\xcc' (which is a = lead byte from a UTF-8 sequence, and so is malformed UTF-8 if not = followed by an appropriate UTF-8 code unit), it will not match the start = of "\xcc\x80" (UTF-8 for the code point U+0300). Boost.Parser knows that = the matching must be whole-code-point, and so it interprets the char = '\xcc' as the code point U+00CC. Error reporting is important to get right, and it is important to make = errors easy to understand, especially for end-users. Boost.Parser = produces runtime parse error messages that are very similar to the = diagnostics that you get when compiling with GCC and Clang (it even = supports warnings that don't fail the parse). The exact token associated = with a diagnostic can be reported to the user, with the containing line = quoted, and with a marker pointing right at the token. Boost.Parser = takes care of this for you; your parser does not need to include any = special code to make this happen. Of course, you can also replace the = error handler entirely, if it doesn't fit your needs. Debugging complex parsers can be a real nightmare. Boost.Parser makes it = trivial to get a trace of your entire parse, with easy-to-read (and very = verbose) indications of where each part of the trace is within the = parse, the state of values produced by the parse, etc. Again, you don't = need to write any code to make this happen =E2=80=94 you just pass a = parameter to parse(). Github: https://github.com/tzlaine/parser Docs https://tzlaine.github.io/parser =E2=80=94 Marshall --Apple-Mail=_19AA5CFE-5FE4-46DE-9F29-E26694DED6C7 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 <html><head><meta http-equiv=3D"content-type" content=3D"text/html; = charset=3Dutf-8"></head><body style=3D"overflow-wrap: break-word; = -webkit-nbsp-mode: space; line-break: after-white-space;"><div>The = review of Zach Laine=E2=80=99s proposed Boost.Parser library begins = today and will end on February 28th.</div><div><br></div><div>=46rom the = introduction page of the = documentation:</div><div><br></div><div><div>Boost.Parser is a parser = combinator library. That is, it consists of a set of low-level primitive = parsers, and operations that can be used to combine those parsers into = more complicated parsers.</div><div><br></div><div>There are primitive = parsers that parse epsilon (the empty string), chars, ints, floats, = etc.</div><div><br></div><div>There are operations which combine parsers = to create new parsers. For instance, the Kleene star operation takes an = existing parser p and creates a new parser that matches zero or more = occurrences of whatever p matches. Both callable objects and operator = overloads are used for the combining operations. For instance, = operator*() is used for Kleene star, and you can also write repeat(n)[p] = to create a parser for exactly n repetitions of = p.</div><div><br></div><div>Boost.Parser also tries to accommodate the = multiple ways that people often want to get a parse result out of their = parsing code. Some parsing may best be done by returning an object that = represents the result of the parse. Other parsing may best be done by = filling in a preexisting data structure. Yet other parsing may best be = done by parsing small sections of a large document, and reporting the = results of subparsers as they are finished, via callbacks. Boost.Parser = accommodates all these ways of working, and even makes it possible to do = callback-based or non-callback-based parsing without rewriting any code = (except by changing the top-level call from parse() to = callback_parse()).</div><div><br></div><div>All of Boost.Parser's public = interfaces are sentinel- and range-friendly, just like the interfaces in = std::ranges.</div><div><br></div><div>Boost.Parser is Unicode-aware = through and through. When you parse ranges of char, Boost.Parser does = not assume any particular encoding =E2=80=94 not Unicode or any other = encoding. Parsing of inputs other than plain chars assumes that the = input is Unicode. In the Unicode-aware code paths, all parsing is done = by matching code points. This means that you can feed UTF-8 strings into = Boost.Parser, both as input and within your parser, and the right sort = of matching occurs. For instance, if your parser is trying to match = repetitions of the char '\xcc' (which is a lead byte from a UTF-8 = sequence, and so is malformed UTF-8 if not followed by an appropriate = UTF-8 code unit), it will not match the start of "\xcc\x80" (UTF-8 for = the code point U+0300). Boost.Parser knows that the matching must be = whole-code-point, and so it interprets the char '\xcc' as the code point = U+00CC.</div><div><br></div><div>Error reporting is important to get = right, and it is important to make errors easy to understand, especially = for end-users. Boost.Parser produces runtime parse error messages that = are very similar to the diagnostics that you get when compiling with GCC = and Clang (it even supports warnings that don't fail the parse). The = exact token associated with a diagnostic can be reported to the user, = with the containing line quoted, and with a marker pointing right at the = token. Boost.Parser takes care of this for you; your parser does not = need to include any special code to make this happen. Of course, you can = also replace the error handler entirely, if it doesn't fit your = needs.</div><div><br></div><div>Debugging complex parsers can be a real = nightmare. Boost.Parser makes it trivial to get a trace of your entire = parse, with easy-to-read (and very verbose) indications of where each = part of the trace is within the parse, the state of values produced by = the parse, etc. Again, you don't need to write any code to make this = happen =E2=80=94 you just pass a parameter to = parse().</div><div><br></div></div><div>Github:</div><div><a = href=3D"https://github.com/tzlaine/parser">https://github.com/tzlaine/pars= er</a><br><br>Docs<br><a = href=3D"https://tzlaine.github.io/parser">https://tzlaine.github.io/parser= </a><br><br></div><div><br></div><div>=E2=80=94 = Marshall</div><div><br></div></body></html>= --Apple-Mail=_19AA5CFE-5FE4-46DE-9F29-E26694DED6C7-- --===============7879121084963786495== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline