0

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();

 }
}
Craig
  • 9
  • 1
  • You have syntax errors; what are the errors you're getting? – ChiefTwoPencils Oct 08 '17 at 21:14
  • It says Syntax error on token(s), misplaced construct(s). I'm not the best with Java so I'm not sure how to properly write the statement, so for example; in term, I don't know how to write it so that it matches with N or F or V or num() or varname or '(', without throwing me a syntax error like it does. – Craig Oct 08 '17 at 21:30
  • `else if num();` is incorrect. `else if` implies that there would be a condition that would need to be met. Even if you used the proper syntax (that you already use elsewhere) you'd still have to deal with the method having a `void` instead of `bool` return type. – ChiefTwoPencils Oct 08 '17 at 21:34
  • Correcting the else statements, how should I go about retrieving the tokens from them instead of a having it ask for a boolean response?(Overall I need it to look into that function and retrieve those token(s)). I feel like I need to use an if statement every time I deal with an || operator. It's just when I get to the more complexed grammar statements, I get lost on implementing it properly to code. – Craig Oct 08 '17 at 21:56
  • You really dont need first and follow sets to do recursive descent parsing. See my SO answer on how to build such parsers: https://stackoverflow.com/questions/2245962/is-there-an-alternative-for-flex-bison-that-is-usable-on-8-bit-embedded-systems/2336769#2336769 – Ira Baxter Oct 09 '17 at 04:10

0 Answers0