// Questa classe implementa una stringa da consumarsi da sinistra verso destra // carattere per carattere. La consumazione e` virtuale, di modo che, volendo, // si potra` riportare la stringa allo stato iniziale class Stringa{ private final String testo; // stringa incapsulata nell'oggetto: // immodificabile private int scans; // testina di scansione // (posizionata sempre all'inizio del suffisso // di 'testo' non ancora esaminato) // COSTRUTTORE DELL'OGGETTO E PRINCIPALI METODI DI MODIFICA public Stringa( String ts ){ // costruttore testo = ( ts != null ) ? ts : ""; ripristina(); } public void ripristina(){ // Dato che il campo 'testo' non verra` mai modificato dopo la costruzione // di questo oggetto, possiamo ripristinare lo stato dell'oggetto quando // vorremo, semplicemente riportando all'inizio la testina di scansione. scans = 0; // posizione sotto esame della testina di scansione } public void addentra(){ scans++; // posizione sotto esame della testina di scansione } // METODI DI ACCESSO AI CAMPI PRIVATI DELL'OGGETTO public boolean nonFinita(){ return scans < testo.length(); } public Character sottoEsame(){ return (nonFinita()) ? testo.charAt( scans ) : null; } // METODI DI ACCESSO-E-MODIFICA public boolean prox( Character c ){ // Questo metodo ci dice se, una volta sorvolati eventuali spazi iniziali // del testo residuo, ci si imbatte nel carattere atteso c // (o, qualora c==null, se non vi sia piu` residuo). Character pross = prossimoCar( ); if ( pross == null ) return c == null; if ( ! pross.equals( c ) ) return false; addentra(); return true; } public Character prossimoCar( ){ // Questo metodo ci dice in quale carattere ci si imbatte, una volta sorvolati eventuali // spazi iniziali del residuo di testo che inizia nella posizione scans. while( nonFinita( ) && testo.charAt( scans ) == ' ' ) addentra(); return ( nonFinita( ) ) ? testo.charAt( scans ) : null; } public String prossimoGettone( ){ // Questo metodo ci dice in quale carattere ci si imbatte, una volta // sorvolati eventuali spazi iniziali del residuo di testo che inizia // nella posizione scans. while( scans < testo.length( ) && testo.charAt( scans ) == ' ' ) addentra(); return ( scans >= testo.length( ) ) ? null : seguenti( ); } private String seguenti( ){ // Questo metodo serve al metodo pubblico 'prossimoGettone' // per radunare i caratteri che formano il prossimo // gettone ('token' in inglese). String acc = ""; char c; while( nonFinita() && ( c = testo.charAt( scans ) ) != ' ' ){ acc += c; addentra(); } return acc; // sequenza dei caratteri (diversi dallo spazio) accumulati } }