Consider the Java program below, which is a recursive descent parser:
class Parens {
GetChar getChar = new GetChar();
char next;
void P() {
scan();
Q();
if (next == '#') System.out.println("Success!");
else error(1);
}
void Q() {
if (next == '(') {
scan();
}
else error(2);
R();
}
void R() {
if (next == ')') {
scan();
}
else {
Q();
R();
}
}
void scan() {
while (Character.isWhitespace(next = getChar.getNextChar()))
;
}
void error(int n) {
System.out.println("*** ERROR: " + n);
System.exit(1);
}
public static void main(String[] args) {
Parens parens = new Parens();
parens.P();
}
}
Here are three separate runs (boldface = input):
(()())# Success! ( () (( )) (() () ) () ) # Success! ( () (( ))# *** ERROR: 2