// Parser implementation // Parser is a class to represent a recursive descent parser for the PL/0 // programming language, described in Algorithms + Data Structures = programs // by Niklaus Wirth, Prentice-Hall, 1976. class SyntaxAnalyzer { protected PL0Lexer lexer; // lexical analyzer protected Token token; // current token public SyntaxAnalyzer () throws java.io.IOException { lexer = new PL0Lexer (System . in); getToken (); } private void getToken () throws java.io.IOException { token = lexer . nextToken (); } public void constDeclaration () throws java.io.IOException { if (token . symbol () == TokenClass . ID) { getToken (); if (token . symbol () == TokenClass . EQ) { getToken (); if (token . symbol () == TokenClass . INTEGER) getToken (); else ErrorMessage . print (lexer . position (), "Integer expected"); } else ErrorMessage . print (lexer . position (), "= expected"); } else ErrorMessage . print (lexer . position (), "id expected"); } public void varDeclaration () throws java.io.IOException { if (token . symbol () == TokenClass . ID) getToken (); else ErrorMessage . print (lexer . position (), "ID EXPECTED"); } public void factor () throws java.io.IOException { if (token . symbol () == TokenClass . ID) getToken (); else if (token . symbol () == TokenClass . INTEGER) getToken (); else if (token . symbol () == TokenClass . LPAREN) { getToken (); expression (); if (token . symbol () == TokenClass . RPAREN) getToken (); else ErrorMessage . print (lexer . position (), "MISSING )"); } else ErrorMessage . print (lexer . position (), "UNRECOGNIZABLE SYMBOL"); } public void term () throws java.io.IOException { factor (); while (token . symbol () == TokenClass . TIMES || token . symbol () == TokenClass . SLASH) { getToken (); factor (); } } public void expression () throws java.io.IOException { if (token . symbol () == TokenClass . PLUS || token . symbol () == TokenClass . MINUS) { getToken (); term (); } else term (); while (token . symbol () == TokenClass . PLUS || token . symbol () == TokenClass . MINUS) { getToken (); term (); } } public void condition () throws java.io.IOException { if (token . symbol () == TokenClass . ODD) { getToken (); expression (); } else { expression (); switch (token . symbol ()) { case EQ : case LT : case GT : case NE : case LE : case GE : getToken (); expression (); break; default : ErrorMessage . print (lexer . position (), "RELATIONAL OPERATOR EXPECTED"); } } } public void statement () throws java.io.IOException { switch (token . symbol ()) { case ID : getToken (); if (token . symbol () == TokenClass . ASSIGN) getToken (); else ErrorMessage . print (lexer . position (), ":= EXPECTED"); expression (); break; case CALL : getToken (); if (token . symbol () != TokenClass . ID) ErrorMessage . print (lexer . position (), "ID EXPECTED"); else { getToken (); break; } case IF : getToken (); condition (); if (token . symbol () == TokenClass . THEN) getToken (); else ErrorMessage . print (lexer . position (), "THEN EXPECTED"); statement (); break; case BEGIN : getToken (); statement (); while (token . symbol () == TokenClass . SEMICOLON) { getToken (); statement (); } if (token . symbol () == TokenClass . END) getToken (); else ErrorMessage . print (lexer . position (), "END OR ; EXPECTED"); break; case WHILE : getToken (); condition (); if (token . symbol () == TokenClass . DO) getToken (); else ErrorMessage . print (lexer . position (), "DO EXPECTED"); statement (); break; } } public void block () throws java.io.IOException { if (token . symbol () == TokenClass . CONST) { getToken (); constDeclaration (); while (token . symbol () == TokenClass . COMMA) { getToken (); constDeclaration (); } if (token . symbol () == TokenClass . SEMICOLON) getToken (); else ErrorMessage . print (lexer . position (), ", OR ; EXPECTED"); } if (token . symbol () == TokenClass . VAR) { getToken (); varDeclaration (); while (token . symbol () == TokenClass . COMMA) { getToken (); varDeclaration (); } if (token . symbol () == TokenClass . SEMICOLON) getToken (); else ErrorMessage . print (lexer . position (), ", OR ; EXPECTED"); } while (token . symbol () == TokenClass . PROC) { getToken (); if (token . symbol () == TokenClass . ID) getToken (); else ErrorMessage . print (lexer . position (), "ID EXPECTED"); if (token . symbol () == TokenClass . SEMICOLON) getToken (); else ErrorMessage . print (lexer . position (), "; EXPECTED"); block (); if (token . symbol () == TokenClass . SEMICOLON) getToken (); else ErrorMessage . print (lexer . position (), "; EXPECTED"); } statement (); } public void program () throws java.io.IOException { block (); if (token . symbol () != TokenClass . PERIOD) ErrorMessage . print (lexer . position (), ". EXPECTED"); } }