import java.io.IOException;
public class RdCalcParser implements CalcParser {
private CalcLexer lexer;
public RdCalcParser() {
this.lexer = new DFACalcLexer();
}
private void error(String rule) throws IOException {
throw new IOException("Parse error in %s on token %s"
.formatted(rule, lexer.peek()));
}
@Override
public void prog() throws IOException {
switch (lexer.peek().getType()) {
case NUM:
case LP:
stmt();
prog();
break;
case EOF:
break;
default:
error("prog");
}
}
void stmt() throws IOException {
exp();
lexer.match(CalcToken.Type.STOP);
}
void exp() throws IOException {
term();
exptail();
}
void exptail() throws IOException {
switch (lexer.peek().getType()) {
case OPA:
lexer.match(CalcToken.Type.OPA);
term();
exptail();
break;
case RP:
case STOP:
break;
default:
error("exptail");
}
}
void term() throws IOException {
factor();
termtail();
}
void termtail() throws IOException {
switch (lexer.peek().getType()) {
case OPM:
lexer.match(CalcToken.Type.OPM);
factor();
termtail();
break;
case RP:
case STOP:
case OPA:
break;
default:
error("termtail");
}
}
void factor() throws IOException {
switch (lexer.peek().getType()) {
case NUM:
lexer.match(CalcToken.Type.NUM);
break;
case LP:
lexer.match(CalcToken.Type.LP);
exp();
lexer.match(CalcToken.Type.RP);
break;
default:
error("factor");
}
}
}