编译原理实验(词法分析,LL(1),LR)

词法分析:

BlockLexer.java:

package lab1;
import java.io.*;

public class BlockLexer{
	private PushbackReader in = null;
    private StringBuffer lexeme = new StringBuffer();
    private char c;
    private int line = 0;
    private int column = 0;
    
    public BlockLexer(String infile) {
        PushbackReader reader = null;
        try {
            reader = new PushbackReader(new FileReader(infile));
        } catch(IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }
        in = reader;
    }
    
    //取得下一个字符
    private void nextChar() {
        try {
            c = (char)in.read();
            lexeme.append(c);
            column++;
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
    
    //回退一个字符(多读入的)
    private void pushbackChar() {
        try {
            in.unread(lexeme.charAt(lexeme.length() - 1));
            lexeme.deleteCharAt(lexeme.length() - 1);
            column--;
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);            
        }
    }
    
    //取得词法记号,并重置状态变量
    private Token getToken(TokenType type) {
        String t = lexeme.toString();
        lexeme.setLength(0);
        return new Token(type, t, line + 1, column - t.length() + 1);
    }
    
    //扔掉一个字符(此时单词应该还未开始,只需把长度设为0即可)
    private void dropChar() {
        lexeme.setLength(0);
    }
    
    //去空格、换行、回车等
    private void removeSpace() {
    	this.nextChar();
    	 while (Character.isWhitespace(c)) {
             if (this.c == '\n') {
                 this.line++;
                 this.column = 0;
             }
             this.dropChar();
             this.nextChar();
         }
         this.pushbackChar();
     }
     
     //识别标识符
     private Token getID_or_Keywords() {
     	int s = 0;
     	while(true) {
     		switch(s) {
     		case 0:
     			nextChar();
     			if(Character.isLetterOrDigit(c) || c=='_') s = 0;
     			else s = 1;
     			break;
     		case 1:
     			this.pushbackChar();
     			String t = this.lexeme.toString();
             	if (t.equalsIgnoreCase("int")){
             		return getToken(TokenType.KEY_INT);
             	} else if(t.equalsIgnoreCase("boolean")) {
             		return getToken(TokenType.KEY_BOOLEAN);
             	} else if(t.equalsIgnoreCase("if")) {
             		return getToken(TokenType.KEY_IF);
             	} else if(t.equalsIgnoreCase("else")) {
             		return getToken(TokenType.KEY_ELSE);
             	} else if(t.equalsIgnoreCase("while")) {
             		return getToken(TokenType.KEY_WHILE);
             	} else if(t.equalsIgnoreCase("true")) {
             		return getToken(TokenType.BOOL_TRUE);
             	} else if(t.equalsIgnoreCase("false")) {
             		return getToken(TokenType.BOOL_FALSE);
             	} else {
             		return getToken(TokenType.IDENTIFIER);
             	}
     		}
     	}
     }
     
     /*****************************begin*******************************/
   //识别整形常数,可能是十进制、八进制或十六进制 
     private Token getIntConst() { 
     	 int s=1;
     	 if(this.c=='0'){
     		 this.nextChar();
     		 if(!Character.isDigit(c)&&c!='x') {
     			 this.pushbackChar();
     			 return getToken(TokenType.NUMBER_LITERAL);
     		 }else if(this.c>=0&&this.c<=7) {
     			 this.nextChar();
     			 return getToken(TokenType.NUMBER_LITERAL);
     		 }
     		 else if(!Character.isDigit(c)&&c=='x') {
     			 for(int i=0;i<4;i++) {
     				 this.nextChar();
     			 }
     			 return getToken(TokenType.NUMBER_LITERAL);
     		 }
     		 this.nextChar();
     		 this.pushbackChar();
     	 }
     	 else {
     		 this.nextChar();
     		 while(c>='0'&&c<='9') {
     			 this.nextChar();
     		 }
     		 this.pushbackChar();
     		 return getToken(TokenType.NUMBER_LITERAL);
     	 }
     	 return null;
     }
     //识别/,/= 
     //去多行注释/*     */ 
     //去单行注释//
     private Token getDivide_or_removeComment() { 
     	int s=1;
     	while(true) {
     		this.nextChar();
     		switch(s) {
     		case 1:
     			if(this.c=='/')s=2;
     			else if(this.c=='*')s=3;
     			else if(this.c=='=')return getToken(TokenType.DIVIDEEQUAL);
     			else {
     				this.pushbackChar();
     				return getToken(TokenType.DIVIDE);
     			}
     			break;
     		case 2:
     			if(this.c=='\n') {
     				this.line++;
     				this.column=0;
     				this.dropChar();
     				return null;
     			}else {
     				s=2;
     			}
     			break;
     		case 3:
     			if(this.c=='*')s=4;
     			else if(this.c=='\n') {
     				this.line++;
     				this.column=0;
     				s=3;
     			}else s=3;
     			break;
     		case 4:
     			if(this.c=='/') {
     				this.dropChar();
     				return null;
     			}else if(this.c=='\n') {
     				this.line++;
     				this.column=0;
     				s=3;
     			}else s=3;
     			break;
     		}
     	}

     }
     //识别+,++,+= 
     private Token getPlus() { 
     	this.nextChar();
     	if(c=='+') {
     		return this.getToken(TokenType.PLUSPLUS);	
     	}else if(c=='=') {
     		return this.getToken(TokenType.PLUSEQUAL);	
     	}else{
     		this.pushbackChar();
     		return this.getToken(TokenType.PLUS);
     	}
     }
     //识别-,--,-= 
     private Token getMinus() { 
     	this.nextChar();
     	if(c=='-') {
     		return this.getToken(TokenType.MINUSMINUS);
     	}else if(c=='=') {
     		return this.getToken(TokenType.MINUSEQUAL);
     	}else {
     		this.pushbackChar();
     		return this.getToken(TokenType.MINUS);
     				
     	}
     }
     //识别*,*= 
     private Token getTimes() { 
     	this.nextChar();
         if(c=='=') {
         	return this.getToken(TokenType.TIMESEQUAL);	
         }else {
         	this.pushbackChar();
         	return this.getToken(TokenType.TIMES);
         }
     }
     //识别%,%= 
     private Token getRemainder() {
     	this.nextChar();
     	if(c=='=') {
     		return this.getToken(TokenType.DIVIDEEQUAL);
     	}
     	else {
     		this.pushbackChar();
     		return this.getToken(TokenType.DIVIDE);
     	}

     }
     //识别>,>>,>= 
     private Token getGreater() { 
     	this.nextChar();
     	if(c=='>') {
     		return this.getToken(TokenType.RIGHTSHIFT);
     	}else if(c=='=') {
     		return this.getToken(TokenType.GREATER_EQUAL);
     	}else {
     		this.pushbackChar();
     		return this.getToken(TokenType.GREATER);
     	}

     }
     //识别<,<<,<= 
     private Token getLess() { 
     	this.nextChar();
     	if(c=='<') {
     		return this.getToken(TokenType.LEFTSHIFT);
     	}else if(c=='=') {
     		return this.getToken(TokenType.LESS_EQUAL);
     	}else {
     		this.pushbackChar();
     		return this.getToken(TokenType.LESS);
     	}

     }
     //识别=,== 
     private Token getAssign_or_Equal() { 
     	this.nextChar();
     	if(c=='=') {
     		return this.getToken(TokenType.EQUAL);
     	}else {
     		this.pushbackChar();
     		return this.getToken(TokenType.ASSIGN);
     	}

     }
     //识别!,!= 
     private Token getNot_or_NotEqual() { 
     	this.nextChar();
     	if(c=='=') {
     		return this.getToken(TokenType.NOT_EQUAL);
     	}else {
     		this.pushbackChar();
     		return this.getToken(TokenType.LOGICAL_NOT);
     	}
     }
     //识别&& 
     private Token getAnd() { 
     	this.nextChar();
     	if(c=='&') {
     		return this.getToken(TokenType.LOGICAL_AND);
     	}else {
     		return null;
     	}

     }
     //识别|| 
     private Token getOr() { 
     	this.nextChar();
     	if(c=='|') {
     		return this.getToken(TokenType.LOGICAL_OR);
     	}else {

     		return null; }
     }

 	/*****************************end*******************************/
     //获取下一个token
     public Token nextToken() {
     	Token token = null;
     	while(null == token) {
 	        this.removeSpace();
 	        this.nextChar();
 	        if ( Character.isDigit(c) ) {
 	        	token = this.getIntConst();
 	        } else if ( Character.isLetter(c) || c == '_'){
 	        	token = this.getID_or_Keywords();
 	        } else if ( c == '+'){
 	        	token = this.getPlus();
 	        } else if ( c == '-'){
 	        	token = this.getMinus();
 	        } else if ( c == '*'){
 	        	token = this.getTimes();
 	        } else if ( c == '/'){
 	        	token = this.getDivide_or_removeComment();
 	        } else if ( c == '%'){
 	        	token = this.getRemainder(); 
 	        } else if ( c == '!'){
 	    		token = this.getNot_or_NotEqual();
 	        } else if ( c == '&'){
 	    		token = this.getAnd();
 	        } else if ( c == '|'){
 	    		token = this.getOr();
 	        } else if ( c == '='){
 	    		token = this.getAssign_or_Equal();
 	        } else if ( c == '>'){
 	    		token = this.getGreater();
 	        } else if ( c == '<'){
 	    		token = this.getLess();
 	        } else if ( c == '('){
 	        	token = this.getToken(TokenType.LPAREN);
 	        } else if ( c == ')'){
 	        	token = this.getToken(TokenType.RPAREN);
 	        } else if ( c == '{'){
 	        	token = this.getToken(TokenType.LBRACKET);
 	        } else if ( c == '}'){
 	        	token = this.getToken(TokenType.RBRACKET);
 	        } else if ( c == ';'){
 	        	token = this.getToken(TokenType.SEMICOLON);	
 	        } else if (c == ','){
 	        	token = this.getToken(TokenType.COMMA);
 	        } else if (c == '.'){
 	        	token = this.getToken(TokenType.DOT);
 	        } else if ((c & 0xff) == 0xff) {
 	            token = this.getToken(TokenType.EOF);
 	        } else {
 	            System.out.println(" get nextToken error!");
 	            System.out.println(" find illegal character " + c);
 	            System.out.println(" at line " + (line + 1) + ",colum " + column);
 	            System.exit(1);
 	        }
     	}
         return token;
     }
 }

Main.java

package lab1;
import java.io.*;

import lab1.BlockLexer;
public class Main {
	public static void main(String args[]) { 
		BlockLexer l = new BlockLexer("test/lab1test2.txt"); 
		Token s = l.nextToken();
		while (s != null && s.getType() != TokenType.EOF) {
			System.out.println(s); s = l.nextToken(); 
			}
		}
}

Token.java:

package lab1;

public class Token { 
	private TokenType type; 
	private String token; 
	private int line; 
	private int column; 
	public Token(TokenType type, String token, int line, int column) {
		this.type = type; 
		this.token = token;
		this.line = line; 
		this.column = column;
		}
	public TokenType getType() { 
			return type; 
			}
		public int getLine(){ 
			return line;
			}
		public int getColumn(){ 
			return column; 
			}
		public String getLexeme(){
			return token; 
			}
		public String toString() { 
			return type + " " + token + " (" + line + ", " + column + ")"; 
			}
		}

TokenType.java:

package lab1;

public enum TokenType{
	/** 忽略的词法单位 **/
	IGNORE,
	
	/** 变量 **/
	IDENTIFIER,		//标识符
	
	/** 常量 **/
	NUMBER_LITERAL,	//整形常量
	BOOL_TRUE,		//true
	BOOL_FALSE,		//false
	
    /** 保留字 */
	KEY_INT,	//int
	KEY_BOOLEAN,//boolean
	KEY_WHILE,	//while
	KEY_IF,		//if
	KEY_ELSE,	//else
	
    /** 算术运算符 */
	PLUS,		//+
	PLUSPLUS, 	//++
	PLUSEQUAL,	//+=
    MINUS,		//-
    MINUSMINUS,	//--
    MINUSEQUAL,	//-=
    TIMES,		//*
    TIMESEQUAL,	//*=
    DIVIDE,		///
    DIVIDEEQUAL,//*=
    REMAINDER,	//%
    REMAINDEREQUAL,	//%=
    
    /** 位运算符 */
    LEFTSHIFT,		//<<
    RIGHTSHIFT,		//>>
    
    /** 关系运算符 */
    LESS,			//<
    GREATER,		//>
    LESS_EQUAL,		//<=
    GREATER_EQUAL,	//>=
    NOT_EQUAL,		//!=
    EQUAL,			//==
    
    /** 逻辑运算符 */
    LOGICAL_NOT,	//!
    LOGICAL_AND,	//&&
    LOGICAL_OR,		//||
    
    /** 赋值符号 */
    ASSIGN,			//=
    
    /** 括号 */
    LPAREN,		//(
    RPAREN,		//)
    LBRACKET,	//{
    RBRACKET,	//}
    
    /** 界符 */
    COMMA,		//逗号,
    SEMICOLON,	//分号;
    DOT,		//圆点.
    
    /** 文件结尾符 */
    EOF,		//end of file
    
    /** 非终结符号以及一些特殊的符号,语法分析时使用 */
    Epsilon,			//空
    Start,			//总的开始符号
    Simpleblock,		//{****}
    Sequence,		//语句序列
    assignmentStatement,//赋值语句

    Expression,			//E
    Expression_1,			//E'
    Term,				//T
    Term_1,				//T'
    Factor,				//F

	Boolexpression,		//布尔表达式
	Boolexpression_1,	
	Boolterm,
	Boolterm_1,
	Boolfactor,
	relationalExpression,	//关系表达式
	relationalOperator,	 	//关系运算符
	
	ifStatement,		 	//if语句
	OptionalElse,		 	//else语句(可选)
	whileStatement		//while语句
}

LL(1):

LabMain.java:

package lab2;


public class Lab2Main {
	public static void main(String[] args) {
		LL1 parser = new LL1();
		parser.doParse("test/lab2test2.txt");
	}
}

LL(1).java:

package lab2;

import java.util.*;
import lab1.*;

public class LL1 {
	private BlockLexer lexer = null;
	private Token lookAhead = null;
	private Stack<TokenType> stack;
	private LL1Table table = null;
	public LL1() {
		this.table = new LL1Table();
	}
	public void doParse(String filePath){
		this.stack = new Stack<TokenType>();
	    this.lexer = new BlockLexer(filePath);
	    this.parse();   
	}
	public void parse() {
		/****************begin*******************/
		StringBuffer buf=new StringBuffer();
		buf.append("步骤\t分析栈\t当前符号\t动作\n");
		int step=1;
		this.stack.push(TokenType.EOF);
		this.stack.push(TokenType.Simpleblock);
		this.lookAhead=this.lexer.nextToken();
		

		//TokenType x=this.stack.pop();
		//System.out.print(x);
	    while(true) {
	    	//System.out.print(this.lookAhead.getType());
	    	//System.out.print("\n");
			buf.append(step++ + "\t");
			buf.append(this.stack + "\t");
			buf.append(this.lookAhead.getType() + "\t");
			
			
			TokenType x=this.stack.pop();
			//System.out.print(x);
			//System.out.print("\n");
			if(this.isTerminal(x)) {
				//System.out.print(step);
				//break;
				if(this.lookAhead.getType()!=TokenType.EOF) {
					buf.append(x+"匹配");
					buf.append("\n");
					this.lookAhead=this.lexer.nextToken();
				}
				else if(this.lookAhead.getType()==TokenType.EOF) {
					buf.append("success");
					break;
				}
				
				//判断是否相等,注意是不是#
			}else {
				TokenType[] production =this.table.getItem(x, this.lookAhead.getType());
				if(null==production) {
					//报错
					///System.out.print("414");
					//System.out.print(production);
					buf.append("error");
				}else {
					//System.out.print(production.length-1);
					
					for(int i=0;i<production.length-1;i++) {
						//System.out.print(production[i]);
						//System.out.print("\n");
						buf.append(production[i]+",");
					}
					buf.append(production[production.length-1]);
					buf.append("\n");
					//逆序进栈,注意空Epsilon
                  
                	   for(int i=production.length-1;i>=0;i--) {
   						if(production[i]!=TokenType.Epsilon) {
   							this.stack.push(production[i]);
   							
   						}
   						
   					}
                   
					
				}
			}
		}
	System.out.print(buf);
		/****************end*******************/
	}

	private String array2String(TokenType[] product) {
		String ret = "";
		for(TokenType type : product) {
			ret += type + ",";
		}
		ret = ret.substring(0, ret.length() - 1);
		return ret;
	}
	public boolean isTerminal(TokenType type) {
		if(type.compareTo(TokenType.EOF) <= 0)
			return true;
		else
			return false;
	}
}

LL1Table.java:

package lab2;

import java.util.*;
import lab1.TokenType;
public class LL1Table {
	HashMap<TokenType, HashMap<TokenType, TokenType[]>> table = null;
	public LL1Table() {
		this.table = new HashMap<TokenType, HashMap<TokenType, TokenType[]>>();
		
		//select(Simpleblock-> {Sequence}) = {{}
		TokenType[] BP1 = {TokenType.LBRACKET, TokenType.Sequence, TokenType.RBRACKET};
		this.addItem(TokenType.Simpleblock, TokenType.LBRACKET, BP1);
		
		//select(Sequence -> AssignmentStatement  Sequence) = {IDENTIFIER}
		TokenType[] SP1 = {TokenType.assignmentStatement, TokenType.Sequence};
		this.addItem(TokenType.Sequence, TokenType.IDENTIFIER, SP1);
		
		//select(Sequence -> epsilon) = {}}
		TokenType[] SP2 = {TokenType.Epsilon};
		this.addItem(TokenType.Sequence, TokenType.RBRACKET, SP2);
		
		/***********************begin***************************/
		//assignmentStatement  →  IDENTIFIER = expression
		TokenType[] AP1 = {TokenType.IDENTIFIER,TokenType.ASSIGN,TokenType.Expression,TokenType.SEMICOLON};
		this.addItem(TokenType.assignmentStatement, TokenType.IDENTIFIER, AP1);
		//Expression	→  term expression_1
		TokenType[] EP1 = {TokenType.Term,TokenType.Expression_1};
		this.addItem(TokenType.Expression, TokenType.LPAREN, EP1);
		this.addItem(TokenType.Expression, TokenType.IDENTIFIER, EP1);
		this.addItem(TokenType.Expression, TokenType.NUMBER_LITERAL, EP1);
		//Expression_1	→  + term expression_1
		TokenType[] EP2 = {TokenType.PLUS,TokenType.Term,TokenType.Expression_1};
		this.addItem(TokenType.Expression_1, TokenType.PLUS, EP2);
		//Expression_1	→  - term expression_1
		TokenType[] EP3 = {TokenType.MINUS,TokenType.Term,TokenType.Expression_1};
		this.addItem(TokenType.Expression_1, TokenType.MINUS, EP3);
		//Expression_1	→  ε
		TokenType[] EP4 = {TokenType.Epsilon};
		this.addItem(TokenType.Expression_1, TokenType.SEMICOLON, EP4);
		this.addItem(TokenType.Expression_1, TokenType.RPAREN, EP4);
		//Term	→  factor term_1
		TokenType[] TP1 = {TokenType.Factor,TokenType.Term_1};
		this.addItem(TokenType.Term, TokenType.RPAREN, TP1);
		this.addItem(TokenType.Term, TokenType.IDENTIFIER, TP1);
		this.addItem(TokenType.Term, TokenType.NUMBER_LITERAL, TP1);
		//Term_1 	→ * factor term_1
		TokenType[] TP2 = {TokenType.TIMES,TokenType.Factor,TokenType.Term_1};
		this.addItem(TokenType.Term_1, TokenType.TIMES, TP2);
		//Term_1 	→ / factor term_1
		TokenType[] TP3 = {TokenType.DIVIDE,TokenType.Factor,TokenType.Term_1};
		this.addItem(TokenType.Term_1, TokenType.DIVIDE, TP3);
		//Term_1 	→ % factor term_1
		TokenType[] TP4 = {TokenType.REMAINDER,TokenType.Factor,TokenType.Term_1};
		this.addItem(TokenType.Term_1, TokenType.REMAINDER, TP4);
		//Term_1 	→ ε
		TokenType[] TP5 = {TokenType.Epsilon};
		this.addItem(TokenType.Term_1, TokenType.PLUS, TP5);
		this.addItem(TokenType.Term_1, TokenType.MINUS, TP5);
		this.addItem(TokenType.Term_1, TokenType.SEMICOLON, TP5);
		this.addItem(TokenType.Term_1, TokenType.RPAREN, TP5);
		//Factor	→  ( expression )
		TokenType[] FP1 = {TokenType.LPAREN,TokenType.Expression,TokenType.RPAREN};
		this.addItem(TokenType.Factor, TokenType.LPAREN, FP1);
		//Factor	→  IDENTIFIER
		TokenType[] FP2 = {TokenType.IDENTIFIER};
		this.addItem(TokenType.Factor, TokenType.IDENTIFIER, FP2);
		//Factor	→  NUMBER_LITERAL
		TokenType[] FP3 = {TokenType.NUMBER_LITERAL};
		this.addItem(TokenType.Factor, TokenType.NUMBER_LITERAL, FP3);
		/***********************end***************************/
	}
	
	private void addItem(TokenType row, TokenType column, TokenType[] list) {
		HashMap<TokenType, TokenType[]> map;
		map = this.table.get(row);
		if(map == null)	map = new HashMap<TokenType, TokenType[]>();
		map.put(column, list);
		this.table.put(row, map);
	}
	
	public TokenType[] getItem(TokenType row, TokenType column){
		HashMap<TokenType, TokenType[]> tmp = this.table.get(row);
		if(tmp == null) return null;
		TokenType[] list = tmp.get(column);
		return list;
	}
	
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		for(TokenType row : this.table.keySet()) {
			for(TokenType column : this.table.get(row).keySet()) {
				buffer.append("(" + row + "," + column + ") = " + this.getItem(row,column));
				buffer.append("\n");
			}
		}
		return buffer.toString();
	}
}

LR:

Grammar.java:

package lab3;
import java.util.*;
import lab1.TokenType;
public class Grammar {
	public static TokenType startSymbol;
	public static HashMap<Integer,Production> productions;
	static {
		startSymbol = TokenType.Expression;
		productions = new HashMap<Integer,Production>();
		
		Production p = null;
		//(0)S'->E
		TokenType[] S1 = {TokenType.Expression};
		p = new Production(TokenType.Start, S1);
		productions.put(0, p);
		
		//(1)E->E + T
		TokenType[] E1 = {TokenType.Expression, TokenType.PLUS, TokenType.Term};
		p = new Production(TokenType.Expression, E1);
		productions.put(1, p);
		
		//(2)E->T
		TokenType[] E2 = {TokenType.Term};
		p = new Production(TokenType.Expression, E2);
		productions.put(2, p);
		
		/************************begin******************************/
		//3 T -> T * F
		TokenType[] T1 = {TokenType.Term,TokenType.TIMES,TokenType.Factor};
		p = new Production(TokenType.Term,T1);
		productions.put(3, p);
		//4 T -> F
		TokenType[] T2 = {TokenType.Factor};
		p = new Production(TokenType.Term,T2);
		productions.put(4, p);

		//5 F -> (E)
		TokenType[] F1 = {TokenType.LPAREN,TokenType.Expression,TokenType.RPAREN};
		p = new Production(TokenType.Factor,F1);
		productions.put(5, p);
		//6 F -> id
		TokenType[] F2 = {TokenType.IDENTIFIER};
		p = new Production(TokenType.Factor,F2);
		productions.put(6, p);

		/************************end******************************/
		
	}
	public static Production get(int i) {
		// TODO Auto-generated method stub
		return productions.get(i);
	}
	
	
}

Lab3Main.java:

package lab3;


public class Lab3Main {
	public static void main(String[] args) {
		LR parser = new LR();
		parser.doParse("test/lab3test1.txt");
	}
}

LR.java:

package lab3;
import java.util.*;
import lab1.*;
public class LR {
	private BlockLexer lexer = null;
	private Token lookAhead = null;
	private Stack<Integer> stateStack;
	private Stack<TokenType> symbolStack;
	private int length1;
	
	
	public void doParse(String filePath){
		this.stateStack = new Stack<Integer>();
		this.symbolStack = new Stack<TokenType>();
	    this.lexer = new BlockLexer(filePath);
	    this.parse();
	}
	
	public void parse() {
	/****************begin*******************/
		/*Grammar.productions.get(0);
		StringBuffer buf=new StringBuffer();
		buf.append((TokenType[])Grammar.productions.get(0).getRight());
		System.out.print(buf);*/
		this.stateStack.push(0);
		length1++;
		this.symbolStack.push(TokenType.EOF);
		
		this.lookAhead=this.lexer.nextToken();
		int step=1;
		StringBuffer buf=new StringBuffer();
		buf.append("步骤\t状态栈\t符号栈\t当前符号\tAction\tGoto\n");
		while(true) {
			buf.append(step++ + "\t");
			buf.append(this.stateStack + "\t");
			buf.append(this.symbolStack + "\t");
			buf.append(this.lookAhead.getType() + "\t");
			
			int state=this.stateStack.peek();
			LRTableEntry entry=LRTable.get(state, this.lookAhead.getType());
			if(entry==null) {
				buf.append("error");
				break;
			}
			if(entry.getAction()=='a') {
				buf.append("acc");
				break;
			}
			if(entry.getAction()=='s') {
				buf.append(entry.toString());
				buf.append('\n');
				this.stateStack.push(entry.getState());
				length1++;
				this.symbolStack.push(this.lookAhead.getType());
				
				this.lookAhead=this.lexer.nextToken();
			}
			if(entry.getAction()=='r') {
				buf.append(entry.toString());
				buf.append('\t');
				Integer[] state1=new Integer[10];
				TokenType[] symbol1=new TokenType[10];
				for(int i=0;i<length1;i++) {
					state1[i]=this.stateStack.pop();
					
				}
				for(int i=length1-1;i>=0;i--) {
					this.stateStack.push(state1[i]);
				}
				/*for(int i=0;i<length2;i++) {
					symbol1[i]=this.symbolStack.pop();
					System.out.print(symbol1[i]);
				}*/
				TokenType[] right=Grammar.productions.get(entry.getState()).getRight();
				
				int length3=right.length;
				for(int i=0;i<length3;i++) {
					this.symbolStack.pop();
				}
					Integer count=0;
					int flag=0;
					int count2=0;
				this.symbolStack.push(Grammar.productions.get(entry.getState()).getLeft());
				for(int k=0;k<length1;k++) {
					LRTableEntry entry1=LRTable.get(state1[k],Grammar.productions.get(entry.getState()).getLeft());
					if(entry1!=null) {
						count=entry1.getState();
						
						break;
					}
				}
				for(int i=0;i<length1;i++) {
					if(state1[i]==count) {
						flag=1;
						count2=i;
						
						
					}
				}
				if(flag==1) {
					for(int i=1;i<=count2;i++) {
						this.stateStack.pop();
						length1--;
					}
				}
				else {
					this.stateStack.pop();
					this.stateStack.push(count);
				}
					
				
				
				buf.append(count);
				buf.append('\n');
				
				
			}
		}
	
		System.out.print(buf);
	/****************end*********************/
	}
	
}

LRTable.java:

package lab3;


import java.util.*;
import lab1.TokenType;

public class LRTable {
	private static HashMap<Integer, HashMap<TokenType, LRTableEntry>> table = null;
	
	static {
		table = new HashMap<Integer, HashMap<TokenType, LRTableEntry>>();
		
		addItem(0, TokenType.IDENTIFIER, new LRTableEntry('s',5));
		addItem(0, TokenType.LPAREN, new LRTableEntry('s',4));
		addItem(0, TokenType.Expression, new LRTableEntry('g',1));
		addItem(0, TokenType.Term, new LRTableEntry('g',2));
		addItem(0, TokenType.Factor, new LRTableEntry('g',3));
		
		addItem(1, TokenType.PLUS, new LRTableEntry('s',6));
		addItem(1, TokenType.EOF, new LRTableEntry('a',0));
		
		addItem(2, TokenType.TIMES, new LRTableEntry('s',7));
		addItem(2, TokenType.PLUS, new LRTableEntry('r',2));
		addItem(2, TokenType.RPAREN, new LRTableEntry('r',2));
		addItem(2, TokenType.EOF, new LRTableEntry('r',2));
		
		/************************begin******************************/
		addItem(3, TokenType.PLUS, new LRTableEntry('r', 4));
		addItem(3, TokenType.TIMES, new LRTableEntry('r', 4));
		addItem(3, TokenType.RPAREN, new LRTableEntry('r', 4));
		addItem(3, TokenType.EOF, new LRTableEntry('r', 4));

		addItem(4, TokenType.IDENTIFIER, new LRTableEntry('s', 5));
		addItem(4, TokenType.LPAREN, new LRTableEntry('s', 4));
		addItem(4, TokenType.Expression, new LRTableEntry('g', 8));
		addItem(4, TokenType.Term, new LRTableEntry('g', 2));
		addItem(4, TokenType.Factor, new LRTableEntry('g', 3));

		addItem(5, TokenType.PLUS, new LRTableEntry('r', 6));
		addItem(5, TokenType.TIMES, new LRTableEntry('r', 6));
		addItem(5, TokenType.RPAREN, new LRTableEntry('r', 6));
		addItem(5, TokenType.EOF, new LRTableEntry('r', 6));

		addItem(6, TokenType.IDENTIFIER, new LRTableEntry('s', 5));
		addItem(6, TokenType.LPAREN, new LRTableEntry('s', 4));
		addItem(6, TokenType.Term, new LRTableEntry('g', 9));
		addItem(6, TokenType.Factor, new LRTableEntry('g', 3));

		addItem(7, TokenType.IDENTIFIER, new LRTableEntry('s', 5));
		addItem(7, TokenType.LPAREN, new LRTableEntry('s', 4));
		addItem(7, TokenType.Factor, new LRTableEntry('g', 10));

		addItem(8, TokenType.PLUS, new LRTableEntry('s', 6));
		addItem(8, TokenType.RPAREN, new LRTableEntry('s', 11));

		addItem(9, TokenType.PLUS, new LRTableEntry('r', 1));
		addItem(9, TokenType.TIMES, new LRTableEntry('s', 7));
		addItem(9, TokenType.RPAREN, new LRTableEntry('r', 1));
		addItem(9, TokenType.EOF, new LRTableEntry('r', 1));

		addItem(10, TokenType.PLUS, new LRTableEntry('r', 3));
		addItem(10, TokenType.TIMES, new LRTableEntry('r', 3));
		addItem(10, TokenType.RPAREN, new LRTableEntry('r', 3));
		addItem(10, TokenType.EOF, new LRTableEntry('r', 3));

		addItem(11, TokenType.PLUS, new LRTableEntry('r', 5));
		addItem(11, TokenType.TIMES, new LRTableEntry('r', 5));
		addItem(11, TokenType.RPAREN, new LRTableEntry('r', 5));
		addItem(11, TokenType.EOF, new LRTableEntry('r', 5));

		/************************end******************************/
	}
	
	private static void addItem(int row, TokenType column, LRTableEntry entry) {
		HashMap<TokenType, LRTableEntry> tmp = null;
		tmp = table.get(row);
		if(tmp == null) tmp = new HashMap<TokenType, LRTableEntry>();
		tmp.put(column, entry);
		table.put(row, tmp);
	}
	
	public static LRTableEntry get(int row, TokenType column) {
		HashMap<TokenType, LRTableEntry> tmp = null;
		tmp = table.get(row);
		if(tmp == null) return null;
		return tmp.get(column);
	}
}

LRTableEntry.java:

package lab3;

public class LRTableEntry {
	private char action;	//'s', shift;  'r',reduce;	'g',goto;  'a',acc
					//if action = acc, state will be ignored
	private int state;	//state for shift and goto, product No. for reduce
	public LRTableEntry(char action, int state) {
		this.action = action;
		this.state = state;
	}
	public char getAction() {
		return this.action;
	}
	public int getState() {
		return this.state;
	}
	public String toString() {
		if('a' == this.action) return "acc";
		if('g' == this.action) return this.state + "";
		return this.action + "" + this.state;
	}
}

Production.java:

package lab3;
import lab1.TokenType;

public class Production {
	TokenType left;
	TokenType[] right;
	public Production(TokenType left, TokenType[] right) {
		this.left = left;
		this.right = right;
	}
	public TokenType getLeft() {
		return this.left;
	}
	public TokenType[] getRight() {
		return this.right;
	}
} 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_45787472

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值