On Thu, Feb 29, 2024 at 8:18 PM Zach Laine via Boost
On Thu, Feb 29, 2024 at 4:44 PM David Sankel via Boost
wrote: Consider char_ https://tzlaine.github.io/parser/doc/html/boost/parser/char_.html's documentation. It includes no examples and fails to mention it can be used without arguments.
I can certainly mention that in that reference entry. Ticket: https://github.com/tzlaine/parser/issues/150
Great, thanks!
# What is your evaluation of the design?
Much of the wealth of research into parser combinators wasn't incorporated into this library. I didn't see in the documentation, for example, an easy way to "map" one parser's attribute into another. This kind of thing should be a basis operation provided by the library.
Could you explain what you mean by this? This happens implicitly usually, and you can explicitly do it in semantic actions. Do you mean something else?
An implicit example would be:
struct s {int i, double d; }; std::vector<s> s_vec; bool success = bp::parse("...", *(bp::int_ >> double_), bp::ws, s_vec);
The sequence parser on the inside is feeding its attributes into the repeat-parser on the outside.
If a parser p has attribute type T (a T parser), and you have a function f of type U(T), I would expect there to be an easy way to convert the T parser into a U parser. Something like map(f, p).
# What is your evaluation of the implementation?
The usage of has_include is a ODR nightmare for large codebases. It would be better to generate some kind of config.hpp that sets these definitions at compile time.
This is a great point. Ticket: https://github.com/tzlaine/parser/issues/151
Thanks!
For custom variant/tuple types, user specialization of variable templates is also an ODR nightmare. Again, a config.hpp would be better for this. For this, though, I don't think the configurability is worth the complexity. We have standard types for these so we should use them.
Huh? There's no ODR here.
Agreed, you can strike that comment.
Overall, I think the syntax has too much focus on magically filling in
user-provided structures instead of the basics of monadic parser combinators and basis operations.
Sure, this parser lib focuses on attribute generation more than any one other feature, to be sure. That's part of its legacy -- Spirit 2 and Spirit X3 have the same focus, and I'm a fan.
Parser combinator libraries have progressed a lot since then and, having used both styles extensively, I'm much more eager to pick up one of the more modern designs. I would expect a Boost library to reflect the state of the art not only in language features used, but also in API design for the domain.
Consider the following Haskell parser which evaluates simple parenthesized sum expressions. I wasn't able to use Boost.Parser to accomplish this after reading the documentation and several attempts. I'm sure it's possible, but I don't see how it can be done using the combiners and primitives provided.
import Text.Parsec.String (Parser)import Text.Parsec integer :: Parser Integerinteger = do n <- many1 digit return (read n) integerPlus :: Parser IntegerintegerPlus = do x <- integer y <- (try $ char '+' >> expression) <|> return 0 return $ x+y parentheses :: Parser Integerparentheses = do char '(' x <- expression char ')' return x expression :: Parser Integerexpression = integerPlus <|> parentheses
No idea what any of that means.
Above is a parser that parses expressions like "23+(42+1)+7". The resulting attribute is an evaluation of the expression (e.g. 66). It looks like the above code was garbled in formatting, but you can see it here on godbolt ( https://godbolt.org/z/s4x78bPK8). It is using Parsec, a simple monadic parser editor combinator library written in Haskell. I highly suggest folks writing parser generators read up on it as its authors did an impressive job figuring out the essential operations and building something both easy and expressive. Thanks for reviewing!
Sure thing!