A C++ PEG parser generator
void op(parser::info &amp;lhs,parser::info &amp;rhs,parser::info &amp;r,const std::string &amp;op){


I think I'd prefer a more descriptive name than r here. I'm guessing it's intended to stand for "result", in which case I think I'd prefer to just name it result.

  peg::grammar math("Math");

  math &lt;&lt; "Math" &lt;&lt; "Set | Expression" &lt;&lt; parserTools::show("%v0\n");


It's not immediately clear why you specify Math both when you create the grammar object and when you specify rules. I think the second is naming the top-level rule Math, but it's not clear what the parameter to the constructor accomplishes.

  math &lt;&lt; "Set" &lt;&lt; "Variable '=' Sum" &lt;&lt; set &lt;&lt; parserTools::pass(1);


At least without some documentation on your parserTools, the meaning of the pass(1) isn't immediately obvious. Presumably this is (at least roughly equivalent to) a semantic rule that's executed when the associated pattern is matched. I can think of a couple of different things pass(1) might be intended to mean, but lac, context to even guess at which is likely to be accurate. Sufficient study of your documentation would undoubtedly make the meaning clear, but it wasn't immediately obvious.

This is kind of a difficult situation: you're basically defining an EDSL, which means understanding the code pretty much requires learning the language you've defined. In other words, no matter how carefully or well written the code is, it's likely to be at least somewhat difficult to understand in isolation.

Summary: looking at the code in isolation, the grammar rules are highly readable, but the (presumed) associated actions much less so.

math &lt;&lt; "Exponent" &lt;&lt; "Atomic   ('^'  Atomic  )*" &lt;&lt; parserTools::leftbinary(op);


At first glance, I'd have assumed that leftbinary was intended to signify a left-associative binary operator--but exponentiation is normally right-associative. I'm left uncertain whether:


it's a bug,
you intentionally changed it from right- to left-associative, or 
I've completely misinterpreted what leftbinary really means.




  while (1) {
    std::string str;
    IO &lt;&lt; "&gt; " &gt;&gt; str &lt;&lt; str &lt;&lt; " -&gt; ";


I have mixed feelings about this mixture of input and output in the same expression. It does lead to relatively terse code, but requires unusual care in reading to keep track of which parts are input vs. output.

Ultimately, I think it would probably be better to review the parser generator and the IO library separately. Here I'm really concentrating on the parser generator, but the design if the I/O library might well be worth examination and review in its own right.