Salve sono uno studente di informatica al secondo anno.
Come compito del corso di "Linguaggi formali e traduttori" il professore ci ha assegnato come esercizio l'implementazione di un Lexer in linguaggio java. Qui sotto vi riporto il codice
codice:

import java.io.*; 
import java.util.*;


public class Lexer {


    public static int line = 1;
    private char peek = ' ';
    
    private void readch(BufferedReader br) {
        try {
            peek = (char) br.read();
        } catch (IOException exc) {
            peek = (char) -1; // ERROR
        }
    }


    public Token lexical_scan(BufferedReader br) {
        while (peek == ' ' || peek == '\t' || peek == '\n'  || peek == '\r') {
            if (peek == '\n') line++;
            readch(br);
        }
        
        switch (peek) {
            case '!':
                peek = ' ';
                return Token.not;
    // ... gestire i casi di +, -, *, /, ;, (, ), {, } ... //
            case '+':
                peek = ' ';
                return Token.plus;
                
            case '-':
                peek = ' ';
                return Token.minus;
            case '*':
                peek = ' ';
                return Token.mult;
                
            case '/':
                peek = ' ';
                return Token.div;
                
            case ';':
                peek = ' ';
                return Token.semicolon;


            case '(':
                peek = ' ';
                return Token.lpt;


            case ')':
                peek = ' ';
                return Token.rpt;


            case '{':
                peek = ' ';
                return Token.lpg;        


            case '}':
                peek = ' ';
                return Token.rpg;                
    // ... gestire i casi di ||, :=, <, >, <=, >=, ==, <> ... //
            case '&':
                readch(br);
                if (peek == '&') {
                    peek = ' ';
                    return Word.and;
                } else {
                    System.err.println("Erroneous character"
                            + " after & : "  + peek );
                    return null;
                }
                
            case '|':
                readch(br);
                if (peek == '|') {
                    peek = ' ';
                    return Word.or;
                } else {
                    System.err.println("Erroneous character"
                            + " after | : "  + peek );
                    return null;
                }
                
            case ':':
                readch(br);
                if (peek == '=') {
                    peek = ' ';
                    return Word.assign;
                } else {
                    System.err.println("Erroneous character"
                            + " after : : "  + peek );
                    return null;
                }
                
            case '<':
                readch(br);
                if (peek == '=') {
                    peek = ' ';
                    return Word.le;
                } else if(peek == ' ') {
                    return Word.lt;
                } else if (peek == '>'){
                    peek = ' ';
                    return Word.ne;
                } else {
                    System.err.println("Erroneous character"
                            + " after < : "  + peek );
                    return null;
                }


            case '>':
                readch(br);
                if (peek == '=') {
                    peek = ' ';
                    return Word.ge;
                } else if(peek == ' ') {
                    return Word.gt;
                } else {
                    System.err.println("Erroneous character"
                            + " after > : "  + peek );
                    return null;
                }
        
            case '=':
                readch(br);
                if (peek == '=') {
                    peek = ' ';
                    return Word.eq;
                } else {
                    System.err.println("Erroneous character"
                            + " after = : "  + peek );
                    return null;
                }
          
            case (char)-1:
                return new Token(Tag.EOF);


            default:
                if (Character.isLetter(peek)) {


                String s = "";
                int state = 0;
                do {
                    s += peek;
                    switch (state) {
                    case 0:
                        if (peek == '_')
                            state = 1;
                        else if (Character.isLetter(peek))
                            state = 2;
                        else
                            state = -1;
                        break;
                    case 1:
                        if (peek == '_')
                            state = 1;
                        else if (Character.isLetter(peek) || Character.isDigit(peek))
                            state = 2;
                        else
                            state = -1;
                        break;
                    case 2:
                        if (peek == '_' || Character.isLetter(peek) || Character.isDigit(peek))
                            state = 2;
                        else
                            state = -1;
                        break;
                    }
                    readch(br);
                } while (Character.isDigit(peek) || Character.isLetter(peek) || peek == '_');
------->                if (state == 2){
                    
                }
                
------>                //parole chiave


                } else if (Character.isDigit(peek)) {
                int val = 0;
                    do {
                        val = val * 10 + Character.getNumericValue(peek);
                        readch(br);
                    } while (Character.isDigit(peek));
                    Number num = new Number(Tag.NUM, val);
                    return num;
                }
                if (peek == (char)-1) {
                    return new Token(Tag.EOF);
                } else {
                    System.err.println("Erroneous character: " + peek);
                    return null;
                }
         }
    }
        
    public static void main(String[] args) {
        Lexer lex = new Lexer();
        String path = "_test.txt"; // il percorso del file da leggere
        try {
            BufferedReader br = new BufferedReader(new FileReader(path));
            Token tok;
            do {
                tok = lex.lexical_scan(br);
                System.out.println("Scan: " + tok);
            } while (tok.tag != Tag.EOF);
            br.close();
        } catch (IOException e) {e.printStackTrace();}    
    }


}
Volevo chiedere consiglio su come trattare Identificatori e Parole Chiave.
Per quanto riguarda gli identificatore (prima freccia) il codice e il trattamento dei vari casi è giusto avendolo preso da un esercizio fatto in precedenza proprio sugli identificatori, il problema è come trattare lo stato finale? Non avendo un return state == 2, anche se il codice è giusto il non riconosce il carattere "_" e mi ritorna null + errore.

Nella seconda freccia invece dovrei implementare le parole chiave della consegna (if, else, read, while, print) presenti in una classe Word.java da me implementata e già utilizzata precedentemente nel codice. Il mio problema riguarda proprio la scrittura del codice, nel senso, devo riproporre i casi iniziali riguardanti i caratteri come "||", "&&", ecc in questo modo:
codice:
case 'if':                readch(br);
                if (peek == 'if') {
                    peek = ' ';
                    return Word.iftok;
                } else {
                    System.err.println("Erroneous character"
                            + " after | : "  + peek );
                    return null;
                }
oppure esistono altre vie come una serie di if, else if?

Ringrazio per un eventuale risposta e chiedo scusa se il mio linguaggio non è pertinente o se la mia richiesta risulta troppo stupida.