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.