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 codiceVolevo chiedere consiglio su come trattare Identificatori e Parole Chiave.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();} } }
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:
oppure esistono altre vie come una serie di if, else if?codice:case 'if': readch(br); if (peek == 'if') { peek = ' '; return Word.iftok; } else { System.err.println("Erroneous character" + " after | : " + peek ); return null; }
Ringrazio per un eventuale risposta e chiedo scusa se il mio linguaggio non è pertinente o se la mia richiesta risulta troppo stupida.

Rispondi quotando