编译原理:递归向下分析程序建立语法分析树的Java实现(二)


在上一篇文章中,我们已经得到了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 + ">"); }
}

运行截图:

编译原理:递归向下分析程序建立语法分析树的Java实现(二)_第1张图片

编译原理:递归向下分析程序建立语法分析树的Java实现(二)_第2张图片





你可能感兴趣的:(编译原理,语法分析树的建立,递归向下分析程序)