so as part of an assignment I need to implement a recursive descent parser for the following grammar;
piece ::= {stmnt ; } [lststmnt ; ]
block ::= piece
stmnt ::= assignst | whilst | ifst | forst
assignst ::= varlist = explst
whilst ::= W expr D block E
ifst ::= I expr T block [S block] E
forst ::= P varname = expr , expr [ , expr] D block E
lststmnt ::= R [explst] | K
varlist ::= varname { , varname}
explst ::= expr , {expr ,}
expr ::= term [ binop expr ] | unop expr
term ::= N | F | V | num | varname | ( expr )
binop ::= + | - | * | / | < | > | A | O
unop ::= - | & | #
varname ::= letter { letter | digit }
num ::= digit { digit }
letter ::= U | X | Y
digit ::= 0 | 1 | 2 | 3 | 4 | 5
Further information about the grammar includes that... 1. The tokens (which are bolded in the grammar) are: E F R W I D T S P K N U V X A O Y 0 1 2 3 4 5 and, in quotes, ; , = # & ( ) < > - + * / 2. The terminal ‘,’ has been quoted to distinguish it from the meta language symbol. 3. Non-terminals are shown as lowercase words. 4. Note that the following characters are NOT tokens (they are EBNF meta-symbols): [ ] | { }
My Issue
Currently my code is flagging errors on my lstsmnt, expr, and term functions. I can't figure out a way to express these parts in the correct manner. This code is being built off a very basic model given to me in the assignment that I have expanded off on. If someone who knows about grammar and recursive descent parsing could help me and show me what I'm doing wrong in my code, it would be greatly appreciated.
Implementation
I have already created this FIRST and FOLLOW's which are listed here down below;
FIRST
piece ::= FIRST(stmnt) = FIRST(assignst) = FIRST(varlist) = FIRST(varname) =
FIRST(letter) ∪ FIRST(digit) ∪ FIRST(whilst) ∪ FIRST(ifst) ∪ FIRST(forst) =
{U, X, Y, 0, 1, 2, 3, 4, 5, W, I, P}
block ::= FIRST(piece) = { { }
stmnt::= FIRST(assignst) = FIRST(varlist) = FIRST(varname) = FIRST(letter) ∪
FIRST(digit) ∪ FIRST(whilst) ∪ FIRST(ifst) ∪ FIRST(forst) = {U, X, Y, 0, 1,
2, 3, 4, 5, W, I, P}
assignst::= FIRST(varlist) = FIRST(varname) = FIRST(letter) ∪ FIRST(digit) =
{U, X, Y, 0, 1, 2, 3, 4, 5}
whilst ::= {W}
ifst ::= {I}
forst ::= {P}
lststmnt ::= {R, K}
varlist::=FIRST(varname) = FIRST(letter) ∪ FIRST(digit) = {U, X, Y, 0, 1, 2,
3, 4, 5}
explst::= FIRST(expr) = N, F, V, ∪ FIRST(term) ∩ FIRST(num) = FIRST(digit) ∪
FIRST(varname) = FIRST(letter) = {U, X, Y} ∪ FIRST(digit) ∪ '(' ∪
FIRST(unop) = {N, F, V, 0, 1, 2, 3, 4, 5, U, X, Y, -, &, #, ( }
expr::= N, F, V, ∪ FIRST(term) ∩ FIRST(num) = FIRST(digit) ∪ {FIRST(varname)
= FIRST(letter) ∪ FIRST(digit) ∪ '(' ∪ FIRST(unop) = {N, F, V, 0, 1, 2, 3,
4, 5, U, X, Y, -, &, #, ( }
term ::= N, F, V, ∪ FIRST(num) = FIRST(digit) ∪ FIRST(varname) =
FIRST(letter) ∪ FIRST(digit) ∪ '(' = {N, F, V, 0, 1, 2, 3, 4, 5, U, X, Y, (
}
binop ::= {+, -, *, /, <, >, A, O}
unop ::= {-, &, #}
varname ::= FIRST(letter) ∪ FIRST(digit) = {U, X, Y, 0, 1, 2, 3, 4, 5}
num ::= FIRST(digit) = {0, 1, 2, 3, 4, 5}
letter ::= {U, X, Y}
digit ::= {0, 1, 2, 3, 4, 5}
FOLLOW
piece ::= {$} ∪ FOLLOW(block) = { E, S }
block ::= { E, S }
stmnt ::= { ; }
assignst ::= FOLLOW(stmnt) = { ; }
whilst ::= FOLLOW(stmnt) = { ; }
ifst ::= FOLLOW(stmnt) = { ; }
forst ::= FOLLOW(stmnt) = { ; }
lststmnt ::= { ; }
varlist ::= { = }
explst ::= { = , R }
expr ::= { ), ',' D, T }
term ::= FIRST(binop) = { +, -, *, /, <, >, A, O} ∪ FOLLOW(expr) = { ), ','
D, T }
binop ::= FIRST(expr) = { N, F, V, 0, 1, 2, 3, 4, 5, U, X, Y, -, &, #, ( }
unop ::= FIRST(expr) = { N, F, V, 0, 1, 2, 3, 4, 5, U, X, Y, -, &, #, ( }
varname { = }
num ::= FOLLOW(term) = { (, ), }
letter ::= { = }
digit ::= FIRST(digit) = {0, 1, 2, 3, 4, 5}
CODE
To begin with, the program being coded is designed to prompt a user for an input stream (e.g. a file). Then a user inputs a stream of legal tokens, followed by a $. The program should output "legal" or "errors found" (not both).
import java.io.*;
import java.util.Scanner;
//--------------------------------------------
public class Recognizer
{
static String inputString;
static int index = 0;
static int errorflag = 0;
private char token()
{ return(inputString.charAt(index)); }
private void advancePtr()
{ if (index < (inputString.length()-1)) index++; }
private void match(char T)
{ if (T == token()) advancePtr(); else error(); }
private void error()
{
System.out.println("error at position: " + index);
errorflag = 1;
advancePtr();
}
//----------------------
private void piece()
{ stmnt();
match(';');
lststmnt(); }
private void block()
{ piece(); }
private void stmnt()
{ if ((token() == 'U')
|| (token() == 'X')
|| (token() == 'Y')) assignst();
else if ((token() == 'W')) whilst();
else if ((token() == 'I')) ifst();
else if ((token() == 'P')) forst(); }
private void assignst()
{ varlist();
match('=');
explst(); }
private void whilst()
{ match('W');
expr();
match('D');
block();
match('E'); }
private void ifst()
{ match('I');
expr();
match('T');
block();
match('S');
match('E'); }
private void forst()
{ match('P');
varname();
match('=');
expr();
match(',');
match('D');
block();
match('E'); }
private void lststmnt()
{ if (match('R')
explst()) {
;
} else {
match('K');
} }
private void varlist()
{ varname();
match(','); }
private void explst() ******ISSUE*********
{ expr();
match(','); }
private void expr() ******ISSUE*********
{ if (
term();
binop();
expr());
else if
(unop();
expr()); }
private void term() *******ISSUE*******
{ if ((token() == 'N')
|| (token() == 'F')
|| (token() == 'V'))
match(token());
else if num();
else if varname();
else if(token() == ('('))
match(token()); }
private void binop()
{ if ((token() == '+')
|| (token() == '-')
|| (token() == '*')
|| (token() == '/')
|| (token() == '<')
|| (token() == '>')
|| (token() == 'A')
|| (token() == 'O'))
match(token()); else error(); }
private void unop()
{ if ((token() == '-')
|| (token() == '&')
|| (token() == '#'))
match(token()); else error(); }
private void varname()
{ if ((token() == 'U')
|| (token() == 'X')
|| (token() == 'Y')) letter();
else digit(); }
private void num()
{ while ((token() == '0')
|| (token() == '1')
|| (token() == '2')
|| (token() == '3')
|| (token() == '4')
|| (token() == '5')) digit(); }
private void letter()
{ if ((token() == 'U')
|| (token() == 'X')
|| (token() == 'Y'))
match(token()); else error(); }
private void digit()
{ if ((token() == '0')
|| (token() == '1')
|| (token() == '2')
|| (token() == '3')
|| (token() == '4')
|| (token() == '5'))
match(token()); else error(); }
//----------------------
private void start()
{
expr();
match('$');
if (errorflag == 0)
System.out.println("legal." + "\n");
else
System.out.println("errors found." + "\n");
}
//----------------------
public static void main (String[] args) throws IOException
{
Recognizer rec = new Recognizer();
Scanner input = new Scanner(System.in);
System.out.print("\n" + "enter an expression: ");
inputString = input.nextLine();
rec.start();
}
}