1. C'est pas dur. On fait ici le choix d'un lexème donné pour la fin de flux. Un autre choix est d'exprimer la fin de flux par null mais ce sera vite pénible.
    class Token { final static int INT=0, ARROW=1, EOF=2, SEMI=3 ; int nature ; int asInt ; Token (int nat) { nature = nat ; } Token (int nat, int val) { nature = nat ; asInt = val ; } }
    On note les deux constructeurs distincts à cause des types distincts de leurs arguments (on parle de surcharge).
  2. Il faut juste prévoir une méthode read et un constructeur,qui range le Reader dans un champ privé.
    class Lexer { private Reader in ; Lexer (Reader in) { this.in = in ; } Token read() { … } }
    Pour ceux que ça intéresse, une classe complète Lexer.java.
  3. Et voilà :
    Graph (Reader in) { Lexer lexer = new Lexer (in) ; succ = new List[readInt(lexer.read())] ; Token tok = lexer.read() ; while (tok.nature != Token.EOF) { int src = readInt(tok) ; readArrow(lexer.read()) ; tok = lexer.read() ; while (tok.nature != Token.SEMI) { int dst = readInt(tok) ; arc(src,dst) ; tok = lexer.read() ; } tok = lexer.read() ; } }
    Où les méthodes auxiliaires error, readInt et readToken sont :
    private static void error(String msg) { System.err.println("Erreur de syntaxe : " + msg) ; System.exit(2) ; } private static int readInt(Token tok) { if (tok.nature != Token.INT) error("Entier attendu"); return tok.asInt ; } private static void readArrow(Token tok) { if (tok.nature != Token.ARROW) error("Flèche attendue"); }