La única variación va a ser el reconocimiento de comentarios. Los comentarios empiezan con un # y terminan con el final de línea.
void Script::SkipWhitespace(ISTREAM& i) { while(i.good() && unsigned(i.peek())<256 && (iswspace(i.peek()) || i.peek()=='#')) { if(i.peek()=='#') { i.get(); while(i.good() && i.peek()!='\n') i.get(); } else i.get(); } }
Es importante dejar claro aquí que no vamos a soportar UNICODE (ni siquiera el famoso "pila de caca") y cualquier carácter por encima del 255 será considerado extraño. De ahí la condición en la guarda del bucle.
Trabajar con iostreams es un poco pesadilla porque no usa excepciones para cosas que deberían ser excepciones (de hecho, los gurús del C++ se quejan a menudo de esta parte de la biblioteca estándar). Poco más podemos hacer para remediarlo que ir comprobando con i.good() cada vez.
Otra función que se usará de vez en cuando es la que espera consumir un token raw (un carácter) en concreto. Es muy simple.
void Script::ConsumeRawToken(ISTREAM& i, ISTREAM::int_type c, wchar_t const* msg) { TOKEN t=ReadToken(i); if(t.type!=T_RAW || t.raw!=c) throw msg; }
Si el carácter no es el esperado, lanzamos una excepción con el mensaje. Como hablamos de caracteres, el token ha de ser T_RAW.
Con esto acabamos las funciones auxiliares y pasamos a la lectura de cadenas en la siguiente entrada.