Back to Project X, and I got down to the harder chunk that I needed to do. In the end, it wasn't too badtwelve hours coding and I've pretty much broken the back of it. All down to the magic of lex and yacc, which are a bugger to get exactly right but still a hell of a lot better than trying to write a parser by hand. Lex is looking pretty old-fashioned though; the autogenerated code is still littered with macros to get around non-K&R compliant compilers (never mind ANSI compliance, which happened in 1990), and all of the communication with the rest of the code happens through global variables.
The current (v2.1) manual for Bison looks like it's a bit more modern and flexible, but the version that's pre-installed on my laptop is rather older (1.28, which I think is from around 1999). I don't think we're actually going to need reentrancy, so I just stuck with vanilla yacc in the end.