Hartmut,
That's a very good point. I've added it to the exception classes.
these. Just use the following code snippet instead of the simple "while (first != last) { ++first; }" loop. The following snippet is taken from
But that's not in the CVS yet, right? 'Cause I didn't see it there :) the
wave driver, where I've implemented the new techniques:
Not sure what's the point of storing the current_position in this snippet as I don't see you using it anywhere at the time of error recovery. In any case, I didn't see any suggestion of being able to position the scanner directly using position_type (and I doublt that's feasible considering that every logical position in the file has semantic state of the preprocessor associated with it). I was thinking of achieving recovery with a copy of the _iterator_ but it doesn't look like this does what I expected it to. Here's my sample snippet: try { wave_context::iterator_type p = ctx.begin(), last_known_good = p; bool done = false; while( !done ) { try { done = p == ctx.end(); std::cout << p->get_value(); ++p; last_known_good = p; } catch( boost::wave::preprocess_exception& err ) { if( err.get_severity() >= boost::wave::util::severity_error ) throw; complain( err ); p = last_known_good; } } } catch( boost::wave::cpp_exception& err ) { complain( err ); return false; } I have half-expected it to go into an infinite loop (as returning back to the failure point should cause the same error to repeat itself) then I realized that tokens that would NOT normally be returned to the user (bosy of the re-defined macro, in my case) may not be part of the state associated with the iterator. Yet something fishy happens with the state I can't quite put my finger on. Here's my example input: ============= #define Foo(x) bar##x Foo(foo1) #define Foo(x) x##bar #define Bar(x) x##foo Foo(foo2) Bar(bar1) ============= This is the result: ============= #line 2 "..\\test.cpp" barfoo1 #define Bar(x) x##foo barfoo2 Bar(bar1) ============= Note that the definition of Bar went through verbatim, which means that recovery was not achieved properly. My guess was that parsing of the body of the second definition of Foo somehow consumed the newline and didn't return it back to the stream, thus invalidating the production for the next #define (which, I imagine, was <EOL> <#> <Keyword>). I tried the modified version: ============= #define Foo(x) bar##x Foo(foo1) #define Foo(x) x##bar #define Bar(x) x##foo Foo(foo2) Bar(bar1) ============= and, sure enough, I got: ============= #line 2 "..\\test.cpp" barfoo1 #line 6 "..\\test.cpp" barfoo2 bar1foo ============= So the newline was indeed consumed irrecoverably [no pun intended!] and recovery failed. But, that's NOT the most interesting part. The most interesting part is that when I commented out all use of last_known_good from the above snippet, the code behaved EXACTLY THE SAME in both cases. Which makes me doubt very much that state has indeed been preserved within the copy of the iterator. Perhaps Wave iterator has shallow copy? I'd deduce that from the code but it's been a long day... maybe tomorrow. Regards, ...Max...