在上一篇文章中,我们已经得到了LL(1)文法,现在,我们使用java编写递归向下的语法分析程序开建立语法分析树。
当一个文法满足LL(1)条件时,我们就可以为它构造一不带回溯的自上而下的分析程序,这个分析程序时由一组递归过程组成的,每个过程对应文法的一个非终结符。
程序实现代码:
Main
public class Main {
public static void main(String[] args) {
Parser par = new Parser();
Node root;
root=par.parseTree();
root.treePrint();
}
}
Node
import java.util.LinkedList;
public class Node
{
public Token tok;
private LinkedList cldList = new LinkedList();
public Node(Token tok)
{ this.tok = tok; }//leaf
public void addCld(Node nd)
{
cldList.add(nd);
}
public void treePrint()
{
treePrintLevel(this, 0);
return;
}
private void treePrintLevel(Node nd, int level)
{
int i;
if(nd!=null) //root
{
for(i=0;i<4*level;i++)
System.out.print("-");
nd.tok.emitToken();
}
if(nd.cldList.isEmpty()==false) //recursive
{
for (Node currNd: nd.cldList) {
treePrintLevel(currNd, level+1);
}
}
}
}
Parser
public class Parser
{
private Scanner scnr;
private Token currentToken;
public Parser()
{
scnr = new Scanner();
}
public Node parseTree(){
Node root;
currentToken=scnr.getNextToken();
root=program();
if(currentToken.matchToken(Tag.END))
return root;
else
{
System.out.println("syntax error: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node program()
{
Node nProg=new Node(new Token(Tag.PRO));
Node nBlock=block();
nProg.addCld(nBlock);
return nProg;
}
private Node block()
{
Node nLB, nDecls, nStmts, nRB, nBlock;
nBlock=new Node(new Token(Tag.BLO));
if(currentToken.matchToken(Tag.LB))
{
nLB=new Node(currentToken);
currentToken=scnr.getNextToken();
nDecls=decls();
nStmts=stmts();
if(currentToken.matchToken(Tag.RB))
{
nRB=new Node(currentToken);
currentToken=scnr.getNextToken();
nBlock.addCld(nLB);
nBlock.addCld(nDecls);
nBlock.addCld(nStmts);
nBlock.addCld(nRB);
return nBlock;
}
else
{
System.out.println("expecting }, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting {, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node decls()
{
Node nDecls, nDecl, nDeclsCld, nEps;
nDecls=new Node(new Token(Tag.DECLS));
if(currentToken.matchToken(Tag.INT) || currentToken.matchToken(Tag.BOOL))
{
nDecl=decl();
nDeclsCld=decls();
nDecls.addCld(nDecl);
nDecls.addCld(nDeclsCld);
return nDecls;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nDecls.addCld(nEps);
return nDecls;
}
}
private Node decl()
{
Node nDecl, nType, nId, nSc;
nDecl=new Node(new Token(Tag.DECL));
if(currentToken.matchToken(Tag.INT) || currentToken.matchToken(Tag.BOOL))
{
nType=type();
if(currentToken.matchToken(Tag.ID))
{
nId=new Node(currentToken);
currentToken=scnr.getNextToken();
if(currentToken.matchToken(Tag.SC))
{
nSc=new Node(currentToken);
currentToken=scnr.getNextToken();
nDecl.addCld(nType);
nDecl.addCld(nId);
nDecl.addCld(nSc);
return nDecl;
}
else
{
System.out.println("expecting ;, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting type int or bool, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node type()
{
Node nType, nBasic, nTypep;
nType = new Node(new Token(Tag.TYP));
if(currentToken.matchToken(Tag.INT) || currentToken.matchToken(Tag.BOOL))
{
nBasic=basic();
nTypep=typep();
nType.addCld(nBasic);
nType.addCld(nTypep);
return nType;
}
else
{
System.out.println("expecting type int or bool, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node typep()
{
Node nTypep, nLsb, nNum, nRsb, nTypepCld, nEps;
nTypep=new Node(new Token(Tag.TYPP));
if(currentToken.matchToken(Tag.LSB))
{
nLsb=new Node(currentToken);
currentToken=scnr.getNextToken();
if(currentToken.matchToken(Tag.NUM))
{
nNum=new Node(currentToken);
currentToken=scnr.getNextToken();
if(currentToken.matchToken(Tag.RSB))
{
currentToken=scnr.getNextToken();
nRsb=new Node(currentToken);
nTypepCld=typep();
nTypep.addCld(nLsb);
nTypep.addCld(nNum);
nTypep.addCld(nRsb);
nTypep.addCld(nTypepCld);
return nTypep;
}
else
{
System.out.println("expecting ], unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting integer number, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nTypep.addCld(nEps);
return nTypep;
}
}
private Node basic()
{
Node nBasic;
nBasic = new Node(new Token(Tag.BASIC));
if(currentToken.matchToken(Tag.INT) || currentToken.matchToken(Tag.BOOL))
{
nBasic.addCld(new Node(currentToken));
currentToken=scnr.getNextToken();
return nBasic;
}
else
{
System.out.println("expecting type int or bool, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node stmts()
{
Node nStmts, nStmt, nStmtsCld, nEps;
nStmts=new Node(new Token(Tag.STMTS));
if(currentToken.matchToken(Tag.IF) ||
currentToken.matchToken(Tag.WHILE) ||
currentToken.matchToken(Tag.DO) ||
currentToken.matchToken(Tag.BREAK) ||
currentToken.matchToken(Tag.LB) ||
currentToken.matchToken(Tag.ID) )
{
nStmt=stmt();
nStmtsCld=stmts();
nStmts.addCld(nStmt);
nStmts.addCld(nStmtsCld);
return nStmts;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nStmts.addCld(nEps);
return nStmts;
}
}
private Node stmt()
{
Node nStmt, nLoc, nSet, nBexpr, nIf, nLp, nRp, nStmtCld, nWhile, nDo, nBreak, nBlock, nSc;
nStmt=new Node(new Token(Tag.STMT));
if(currentToken.matchToken(Tag.IF))
{
nIf=new Node(currentToken);
currentToken=scnr.getNextToken();
if(currentToken.matchToken(Tag.LP))
{
nLp=new Node(currentToken);
currentToken=scnr.getNextToken();
nBexpr=bexpr();
if(currentToken.matchToken(Tag.RP))
{
nRp=new Node(currentToken);
currentToken=scnr.getNextToken();
nStmtCld=stmt();
nStmt.addCld(nIf);
nStmt.addCld(nLp);
nStmt.addCld(nBexpr);
nStmt.addCld(nRp);
nStmt.addCld(nStmtCld);
return nStmt;
}
else
{
System.out.println("expecting ), unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting (, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else if(currentToken.matchToken(Tag.WHILE))
{
nWhile=new Node(currentToken);
currentToken=scnr.getNextToken();
if(currentToken.matchToken(Tag.LP))
{
nLp=new Node(currentToken);
currentToken=scnr.getNextToken();
nBexpr=bexpr();
if(currentToken.matchToken(Tag.RP))
{
nRp=new Node(currentToken);
currentToken=scnr.getNextToken();
nStmtCld=stmt();
nStmt.addCld(nWhile);
nStmt.addCld(nLp);
nStmt.addCld(nBexpr);
nStmt.addCld(nRp);
nStmt.addCld(nStmtCld);
return nStmt;
}
else
{
System.out.println("expecting ), unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting (, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else if(currentToken.matchToken(Tag.DO))
{
nDo=new Node(currentToken);
currentToken=scnr.getNextToken();
nStmtCld=stmt();
if(currentToken.matchToken(Tag.WHILE))
{
nWhile=new Node(currentToken);
currentToken=scnr.getNextToken();
if(currentToken.matchToken(Tag.LP))
{
nLp=new Node(currentToken);
currentToken=scnr.getNextToken();
nBexpr=bexpr();
if(currentToken.matchToken(Tag.RP))
{
nRp=new Node(currentToken);
currentToken=scnr.getNextToken();
if(currentToken.matchToken(Tag.SC))
{
nSc=new Node(currentToken);
currentToken=scnr.getNextToken();
nStmt.addCld(nDo);
nStmt.addCld(nStmtCld);
nStmt.addCld(nWhile);
nStmt.addCld(nLp);
nStmt.addCld(nBexpr);
nStmt.addCld(nRp);
nStmt.addCld(nSc);
return nStmt;
}
else
{
System.out.println("expecting ;, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting ), unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting (, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting while, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else if(currentToken.matchToken(Tag.BREAK))
{
nBreak=new Node(currentToken);
currentToken=scnr.getNextToken();
if(currentToken.matchToken(Tag.SC))
{
nSc=new Node(currentToken);
currentToken=scnr.getNextToken();
nStmt.addCld(nBreak);
nStmt.addCld(nSc);
return nStmt;
}
else
{
System.out.println("expecting ;, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else if(currentToken.matchToken(Tag.LB))
{
nBlock=new Node(new Token(Tag.BLO));
nBlock=block();
nStmt.addCld(nBlock);
return nStmt;
}
else if(currentToken.matchToken(Tag.ID))
{
nLoc=loc();
if(currentToken.matchToken(Tag.SET))
{
nSet=new Node(currentToken);
currentToken=scnr.getNextToken();
nBexpr=bexpr();
if(currentToken.matchToken(Tag.SC))
{
nSc=new Node(currentToken);
currentToken=scnr.getNextToken();
nStmt.addCld(nLoc);
nStmt.addCld(nSet);
nStmt.addCld(nBexpr);
nStmt.addCld(nSc);
return nStmt;
}
else
{
System.out.println("expecting ;, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting =, unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
System.out.println("expecting one of if, while, do, break, { or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node loc()
{
Node nLoc, nId, nLocp;
nLoc=new Node(new Token(Tag.LOC));
if(currentToken.matchToken(Tag.ID))
{
nId=new Node(currentToken);
currentToken = scnr.getNextToken();
nLocp=locp();
nLoc.addCld(nId);
nLoc.addCld(nLocp);
return nLoc;
}
else
{
System.out.println("expecting identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node locp()
{
Node nLocp, nLsb, nAexpr, nRsb, nLocpCld, nEps;
nLocp=new Node(new Token(Tag.LOCP));
if(currentToken.matchToken(Tag.LSB))
{
nLsb=new Node(currentToken);
currentToken=scnr.getNextToken();
nAexpr=aexpr();
if(currentToken.matchToken(Tag.RSB))
{
nRsb=new Node(currentToken);
currentToken=scnr.getNextToken();
nLocpCld=locp();
nLocp.addCld(nLsb);
nLocp.addCld(nAexpr);
nLocp.addCld(nRsb);
nLocp.addCld(nLocpCld);
return nLocp;
}
else
{
System.out.println("expecting ], unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else
{
nEps=new Node(new Token(Tag.EPS));
nLocp.addCld(nEps);
return nLocp;
}
return null;
}
private Node bexpr()
{
Node nBexpr, nJoin, nBexprp;
nBexpr=new Node(new Token(Tag.BEXP));
if(currentToken.matchToken(Tag.NOT) ||
currentToken.matchToken(Tag.SUB) ||
currentToken.matchToken(Tag.LP) ||
currentToken.matchToken(Tag.TRUE) ||
currentToken.matchToken(Tag.FALSE) ||
currentToken.matchToken(Tag.NUM) ||
currentToken.matchToken(Tag.ID) )
{
nJoin=join();
nBexprp=bexprp();
nBexpr.addCld(nJoin);
nBexpr.addCld(nBexprp);
return nBexpr;
}
else
{
System.out.println("expecting one of !, -, (, true, false, number or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node bexprp()
{
Node nBexprp, nOr, nJoin, nBexprpCld, nEps;
nBexprp=new Node(new Token(Tag.BEXPP));
if(currentToken.matchToken(Tag.OR))
{
nOr=new Node(currentToken);
currentToken=scnr.getNextToken();
nJoin=join();
nBexprpCld=bexprp();
nBexprp.addCld(nOr);
nBexprp.addCld(nJoin);
nBexprp.addCld(nBexprpCld);
return nBexprp;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nBexprp.addCld(nEps);
return nBexprp;
}
}
private Node join()
{
Node nJoin, nEqu, nJoinp;
nJoin=new Node(new Token(Tag.JOIN));
if(currentToken.matchToken(Tag.NOT) ||
currentToken.matchToken(Tag.SUB) ||
currentToken.matchToken(Tag.LP) ||
currentToken.matchToken(Tag.TRUE) ||
currentToken.matchToken(Tag.FALSE) ||
currentToken.matchToken(Tag.NUM) ||
currentToken.matchToken(Tag.ID) )
{
nEqu=equality();
nJoinp=joinp();
nJoin.addCld(nEqu);
nJoin.addCld(nJoinp);
return nJoin;
}
else
{
System.out.println("expecting one of !, -, (, true, false, number or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node joinp()
{
Node nJoinp, nAnd, nEqu, nJoinpCld, nEps;
nJoinp=new Node(new Token(Tag.JOINP));
if(currentToken.matchToken(Tag.AND))
{
nAnd=new Node(currentToken);
currentToken=scnr.getNextToken();
nEqu=equality();
nJoinpCld=joinp();
nJoinp.addCld(nAnd);
nJoinp.addCld(nEqu);
nJoinp.addCld(nJoinpCld);
return nJoinp;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nJoinp.addCld(nEps);
return nJoinp;
}
}
private Node equality()
{
Node nEqu, nRel, nEqup;
nEqu=new Node(new Token(Tag.EQU));
if(currentToken.matchToken(Tag.NOT) ||
currentToken.matchToken(Tag.SUB) ||
currentToken.matchToken(Tag.LP) ||
currentToken.matchToken(Tag.TRUE) ||
currentToken.matchToken(Tag.FALSE) ||
currentToken.matchToken(Tag.NUM) ||
currentToken.matchToken(Tag.ID) )
{
nRel=rel();
nEqup=equalityp();
nEqu.addCld(nRel);
nEqu.addCld(nEqup);
return nEqu;
}
else
{
System.out.println("expecting one of !, -, (, true, false, number or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node equalityp()
{
Node nEqup, nEq, nNe, nRel, nEqupCld, nEps;
nEqup=new Node(new Token(Tag.EQUP));
if(currentToken.matchToken(Tag.EQ))
{
nEq=new Node(currentToken);
currentToken=scnr.getNextToken();
nRel=rel();
nEqupCld=equalityp();
nEqup.addCld(nEq);
nEqup.addCld(nRel);
nEqup.addCld(nEqupCld);
return nEqup;
}
else if(currentToken.matchToken(Tag.NE))
{
nNe=new Node(currentToken);
currentToken=scnr.getNextToken();
nRel=rel();
nEqupCld=equalityp();
nEqup.addCld(nNe);
nEqup.addCld(nRel);
nEqup.addCld(nEqupCld);
return nEqup;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nEqup.addCld(nEps);
return nEqup;
}
}
private Node rel()
{
Node nRel, nAexpr, nRelp;
nRel=new Node(new Token(Tag.REL));
if(currentToken.matchToken(Tag.NOT) ||
currentToken.matchToken(Tag.SUB) ||
currentToken.matchToken(Tag.LP) ||
currentToken.matchToken(Tag.TRUE) ||
currentToken.matchToken(Tag.FALSE) ||
currentToken.matchToken(Tag.NUM) ||
currentToken.matchToken(Tag.ID) )
{
nAexpr=aexpr();
nRelp=relp();
nRel.addCld(nAexpr);
nRel.addCld(nRelp);
return nRel;
}
else
{
System.out.println("expecting one of !, -, (, true, false, number or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node relp()
{
Node nRelp, nLt, nLe, nGt, nGe, nAexpr, nEps;
nRelp=new Node(new Token(Tag.RELP));
if(currentToken.matchToken(Tag.LT))
{
nLt=new Node(currentToken);
currentToken=scnr.getNextToken();
nAexpr=aexpr();
nRelp.addCld(nLt);
nRelp.addCld(nAexpr);
return nRelp;
}
else if(currentToken.matchToken(Tag.LE))
{
nLe=new Node(currentToken);
currentToken=scnr.getNextToken();
nAexpr=aexpr();
nRelp.addCld(nLe);
nRelp.addCld(nAexpr);
return nRelp;
}
else if(currentToken.matchToken(Tag.GT))
{
nGt=new Node(currentToken);
currentToken=scnr.getNextToken();
nAexpr=aexpr();
nRelp.addCld(nGt);
nRelp.addCld(nAexpr);
return nRelp;
}
else if(currentToken.matchToken(Tag.GE))
{
nGe=new Node(currentToken);
currentToken=scnr.getNextToken();
nAexpr=aexpr();
nRelp.addCld(nGe);
nRelp.addCld(nAexpr);
return nRelp;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nRelp.addCld(nEps);
return nRelp;
}
}
private Node aexpr()
{
Node nAexpr, nTerm, nAexprp;
nAexpr=new Node(new Token(Tag.AEXP));
if(currentToken.matchToken(Tag.NOT) ||
currentToken.matchToken(Tag.SUB) ||
currentToken.matchToken(Tag.LP) ||
currentToken.matchToken(Tag.TRUE) ||
currentToken.matchToken(Tag.FALSE) ||
currentToken.matchToken(Tag.NUM) ||
currentToken.matchToken(Tag.ID) )
{
nTerm=term();
nAexprp=aexprp();
nAexpr.addCld(nTerm);
nAexpr.addCld(nAexprp);
return nAexpr;
}
else
{
System.out.println("expecting one of !, -, (, true, false, number or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node aexprp()
{
Node nAexprp, nAexprpCld, nAdd, nSub, nTerm, nEps;
nAexprp=new Node(new Token(Tag.AEXPP));
if(currentToken.matchToken(Tag.ADD))
{
nAdd=new Node(currentToken);
currentToken=scnr.getNextToken();
nTerm=term();
nAexprpCld=aexprp();
nAexprp.addCld(nAdd);
nAexprp.addCld(nTerm);
nAexprp.addCld(nAexprpCld);
return nAexprp;
}
else if(currentToken.matchToken(Tag.SUB))
{
nSub=new Node(currentToken);
currentToken=scnr.getNextToken();
nTerm=term();
nAexprpCld=aexprp();
nAexprp.addCld(nSub);
nAexprp.addCld(nTerm);
nAexprp.addCld(nAexprpCld);
return nAexprp;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nAexprp.addCld(nEps);
return nAexprp;
}
}
private Node term()
{
Node nTerm, nUnary, nTermp;
nTerm = new Node(new Token(Tag.TERM));
if(currentToken.matchToken(Tag.NOT) ||
currentToken.matchToken(Tag.SUB) ||
currentToken.matchToken(Tag.LP) ||
currentToken.matchToken(Tag.TRUE) ||
currentToken.matchToken(Tag.FALSE) ||
currentToken.matchToken(Tag.NUM) ||
currentToken.matchToken(Tag.ID) )
{
nUnary=unary();
nTermp=termp();
nTerm.addCld(nUnary);
nTerm.addCld(nTermp);
return nTerm;
}
else
{
System.out.println("expecting one of !, -, (, true, false, number or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node termp()
{
Node nTermp, nTermpCld, nMul, nDiv, nUnary, nEps;
nTermp = new Node(new Token(Tag.TERMP));
if(currentToken.matchToken(Tag.MUL))
{
nMul=new Node(currentToken);
currentToken=scnr.getNextToken();
nUnary=unary();
nTermpCld=termp();
nTermp.addCld(nMul);
nTermp.addCld(nUnary);
nTermp.addCld(nTermpCld);
return nTermp;
}
else if(currentToken.matchToken(Tag.DIV))
{
nDiv=new Node(currentToken);
currentToken=scnr.getNextToken();
nUnary=unary();
nTermpCld=termp();
nTermp.addCld(nDiv);
nTermp.addCld(nUnary);
nTermp.addCld(nTermpCld);
return nTermp;
}
else
{
nEps=new Node(new Token(Tag.EPS));
nTermp.addCld(nEps);
return nTermp;
}
}
private Node unary()
{
Node nUnary, nNot, nSub, nUnaryCld, nFac;
nUnary = new Node(new Token(Tag.UNY));
if(currentToken.matchToken(Tag.NOT))
{
nNot=new Node(currentToken);
currentToken=scnr.getNextToken();
nUnaryCld=unary();
nUnary.addCld(nNot);
nUnary.addCld(nUnaryCld);
return nUnary;
}
else if(currentToken.matchToken(Tag.SUB))
{
nSub=new Node(currentToken);
currentToken=scnr.getNextToken();
nUnaryCld=unary();
nUnary.addCld(nSub);
nUnary.addCld(nUnaryCld);
return nUnary;
}
else if(currentToken.matchToken(Tag.LP) ||
currentToken.matchToken(Tag.TRUE) ||
currentToken.matchToken(Tag.FALSE) ||
currentToken.matchToken(Tag.NUM) ||
currentToken.matchToken(Tag.ID) )
{
nFac=factor();
nUnary.addCld(nFac);
return nUnary;
}
else
{
System.out.println("expecting one of !, -, (, true, false, number or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
private Node factor()
{
Node nFac, nLp, nRp, nBexpr, nLoc, nNum, nTrue, nFalse;
nFac=new Node(new Token(Tag.FAC));
if(currentToken.matchToken(Tag.LP))
{
nLp=new Node(currentToken);
currentToken=scnr.getNextToken();
nBexpr=bexpr();
if(currentToken.matchToken(Tag.RP))
{
nRp=new Node(currentToken);
currentToken=scnr.getNextToken();
nFac.addCld(nLp);
nFac.addCld(nBexpr);
nFac.addCld(nRp);
return nFac;
}
else
{
System.out.println("expecting ), unmatched: line " + scnr.line); //error
System.exit(-1);
}
}
else if(currentToken.matchToken(Tag.ID))
{
nLoc=loc();
nFac.addCld(nLoc);
return nFac;
}
else if(currentToken.matchToken(Tag.NUM))
{
nNum=new Node(currentToken);
currentToken=scnr.getNextToken();
nFac.addCld(nNum);
return nFac;
}
else if(currentToken.matchToken(Tag.TRUE))
{
nTrue=new Node(currentToken);
currentToken=scnr.getNextToken();
nFac.addCld(nTrue);
return nFac;
}
else if(currentToken.matchToken(Tag.FALSE))
{
nFalse=new Node(currentToken);
currentToken=scnr.getNextToken();
nFac.addCld(nFalse);
return nFac;
}
else
{
System.out.println("expecting one of (, true, false, number or identifier, unmatched: line " + scnr.line); //error
System.exit(-1);
}
return null;
}
}
Scanner
public class Scanner
{
public int line=1;
private char ch;
private int asc;
private boolean getNext=true;
private SymTable tbl;
public Scanner()
{
tbl = new SymTable(); //initialize symbol table
}
private void getNextChar()
{
try{
asc=System.in.read();
}
catch(Exception ex)
{}
ch=(char)asc;
}
public Token getNextToken()
{
if(getNext)
getNextChar();
else
getNext=true;
while(ch==' ' || ch=='\t' || ch=='\r' || ch=='\n')
{
if(ch=='\n')
line++;
getNextChar();
}
if(ch=='&')
{
getNextChar();
if(ch=='&') //match &&
return (new Token(Tag.AND));
else
{
System.out.println("missing &: line" + line); //error
System.exit(-1);
}
}
else if(ch=='|')
{
getNextChar();
if(ch=='|') //match ||
return (new Token(Tag.OR));
else
{
System.out.println("missing |: line " + line); //error
System.exit(-1);
}
}
else if(ch=='=')
{
getNextChar(); //look ahead
if(ch=='=') //match ==
return (new Token(Tag.EQ));
else
{
getNext=false;
return (new Token(Tag.SET));
}
}
else if(ch=='!')
{
getNextChar(); //look ahead
if(ch=='=') //match !=
return (new Token(Tag.NE));
else
{
getNext=false;
return (new Token(Tag.NOT));
}
}
else if(ch=='<')
{
getNextChar(); //look ahead
if(ch=='=') //match <=
return (new Token(Tag.LE));
else
{
getNext=false;
return (new Token(Tag.LT));
}
}
else if(ch=='>')
{
getNextChar(); //look ahead
if(ch=='=') //match >=
return (new Token(Tag.GE));
else
{
getNext=false;
return (new Token(Tag.GT));
}
}
else if(ch=='+')
return (new Token(Tag.ADD));
else if(ch=='-')
return (new Token(Tag.SUB));
else if(ch=='*')
return (new Token(Tag.MUL));
else if(ch=='/')
return (new Token(Tag.DIV));
else if(ch=='(')
return (new Token(Tag.LP));
else if(ch==')')
return (new Token(Tag.RP));
else if(ch=='{')
return (new Token(Tag.LB));
else if(ch=='}')
return (new Token(Tag.RB));
else if(ch=='[')
return (new Token(Tag.LSB));
else if(ch==']')
return (new Token(Tag.RSB));
else if(ch==';')
return (new Token(Tag.SC));
else if(ch=='$')
return (new Token(Tag.END));
else if( Character.isDigit(ch) ) {
int v = 0;
do {
v = 10*v + Character.digit(ch, 10);
getNextChar();
} while( Character.isDigit(ch) );
getNext=false;
return (new Token(Tag.NUM, Integer.toString(v)));
}
else if( Character.isLetter(ch) ) {
StringBuffer b = new StringBuffer(); //string buffer
do {
b.append(ch);
getNextChar();
} while( Character.isLetterOrDigit(ch) );
getNext=false;
String s = b.toString();
int tag=tbl.find(s);
if(tag<0)
{
tbl.reserve(s, Tag.ID); //insert to symbol table
return (new Token(Tag.ID, s));
}
else if(tag==Tag.ID)
return (new Token(Tag.ID, s));
else
return (new Token(tag));
}
else
{
System.out.println("Lexical error: line "+line+", "+ch);
System.exit(-1);
}
return null;
}//end-of-getToken
}
SymTable
import java.util.Hashtable;
public class SymTable
{//symbol table
private Hashtable stbl;
public void reserve(String key, int value)
{ stbl.put(key, value); }
public SymTable()
{
stbl = new Hashtable();
reserve("if", Tag.IF);
reserve("else", Tag.ELSE);
reserve("while", Tag.WHILE);
reserve("do", Tag.DO);
reserve("break", Tag.BREAK);
reserve("true", Tag.TRUE);
reserve("false", Tag.FALSE);
reserve("int", Tag.INT);
reserve("bool", Tag.BOOL);
}
public Integer find(String s)
{
if(stbl.get(s)==null)
return -1;
else
return stbl.get(s);
}
}
Tag
public class Tag {
public final static int
IF=256, ELSE=257, WHILE=258, DO=259, BREAK=260, //keyword
TRUE=261, FALSE=262, //boolean constant
INT=263, BOOL=264, //type
AND=265, OR=266, NOT=267, //boolean operator
EQ=268, NE=269, GT=270, GE=271, LT=272, LE=273, //relational operator
SET=274, //assignment
ADD=275, SUB=276, MUL=277, DIV=278, //arithmetic operator
SC=279, LP=280, RP=281, LB=282, RB=283, //delimiter
LSB=284, RSB=285, //delimiter
ID=286, //identifier
NUM=287, //integer-number
PRO=300, //program
BLO=301, //block
DECLS=302, //declarations
DECL=303, //declaration
TYP=304, //type
TYPP=305, //type'
BASIC=306, //basic
STMTS=307, //statements
STMT=308, //statement
LOC=309, //location
LOCP=310, //location'
BEXP=311, //boolean expression
BEXPP=312, //boolean'
JOIN=313, //join
JOINP=314, //join'
EQU=315, //equality
EQUP=316, //equality'
REL=317, //relation
RELP=318, //relation'
AEXP=319, //arithmetic
AEXPP=320, //arithmetic'
TERM=321, //term
TERMP=322, //term'
UNY=323, //unary
FAC=324, //factor
EPS=325, //epsilon
END=326; //$
}
Token
public class Token
{
public final int tag;
public String value;
public Token(int t){tag=t; value="";}
public Token(int t, String v) { tag = t; value = v;}
public boolean matchToken(int tag)
{
if(this.tag==tag)
return true;
else
return false;
}
public void emitToken()
{ System.out.println("<" + tag + ", " + value + ">"); }
}