编译原理——赋值语句与简单表达式(五)

语法。

Syntax.java:

package per.eyuan.compile;

import per.eyuan.util.Action;
import per.eyuan.util.ConstantTable;
import per.eyuan.util.FourItem;
import per.eyuan.util.FourItemStack;
import per.eyuan.util.GoTo;
import per.eyuan.util.IdentifierTable;
import per.eyuan.util.MyStack;
import per.eyuan.util.TemporaryTable;
import per.eyuan.util.TwoItemStack;

public class Syntax {
	IdentifierTable idt;//标志符表
	ConstantTable cont;//常数表
	TemporaryTable tt;//临时变量表
	TwoItemStack tis;//二元式栈
	FourItemStack fis;//四元式栈
	
	MyStack msStatu=new MyStack();//状态栈,存放状态
	MyStack msSymble=new MyStack();//符号栈,存放符号
	MyStack msSmtm=new MyStack();//语义栈
	
	Action act=new Action();//Action表
	GoTo gt=new GoTo();//GoTo表
	
	String action;//动作
	boolean succ=false;//是否接受,分析成功
	String statu="";//当前动作时的状态栈内容
	String symble="";//符号栈内容
	String state="";//语句
	String semanteme="";//语义
	String syntax[]={"A->id=E;","E->E+T","E->T","T->T*F","T->F","F->(E)","F->id"};
	String synL[]={"A","E","E","T","T","F","F"};
	String synR[][]={{"id","=","E",";"},{"E","+","T"},{"T"},{"T","*","F"},{"F"},{"(","E",")"},{"id"}};
	String vnType;//非终结符的“类型”
	int til;//传递来的二元式的长度
	int Ep,E1p,Tp,T1p,Fp;//非终结符指向的标志符入口
	
	public Syntax() {
		super();
		init();
	}

	public void init(){
		//状态栈和符号栈初始化
		msStatu.push("0");//状态
		msSymble.push("#");//符号
		msSmtm.push("_");//语义
	}
	public void analyse(){
		System.out.println("状态栈\t\t符号栈\t\t语义\t\t输入串\t\t\t动作说明");
		while(!succ){
			//获取状态栈和语句栈栈顶,查询Action表
			act.setTable(msStatu.getTop(), tis.getTop().getCategory());
			//获取Action表返回的动作,并作处理
			action=act.getAction();
			perform(action);
		}
		
	}
	public void acc(){
		fis.push(new FourItem("=","T"+Ep,"_",idt.getId(Integer.parseInt(tis.getHole()[til-1].getInside())).getName()));
		int i=0;
		for(;i<cont.getCount();i++)
			if(cont.getAllConstant()[i].getValue().equals(tt.getTemp(Ep).getValue())){
				//常数表中已有该常数
				//id指向该常数
				idt.getId(Integer.parseInt(tis.getHole()[til-1].getInside())).setValue(i);
				i=cont.getCount();
			}
		if(i==cont.getCount()){
			//常数表中没有该常数
			//将常数加入常数表
			cont.addConstant("int",tt.getTemp(Ep).getValue());
			//id指向新增常数
			idt.getId(Integer.parseInt(tis.getHole()[til-1].getInside())).setValue(cont.getCount()-1);
		}
	}
	public void perform(String action){
		//出错
		String actNum="";//规约或者移进是的数字
		for(int i=1;i<action.length();i++)
			actNum+=action.charAt(i);
		
		if(action.equals("err")){
			error();
		}
			
		//接受
		else if(action.equals("acc")){
			this.succ=true;
			output(-1);
			acc();
			
		}
		//移进
		//移进时,状态入栈,符号入栈,语义入栈,二元式“出栈”
		else if(action.charAt(0)=='s'){
			int x=Integer.parseInt(actNum);
			output(x);//输出动作说明等
			msStatu.push(x+"");//状态
			msSymble.push(tis.getTop().getCategory());//符号
			if(tis.getTop().getCategory().equals("id"))
				msSmtm.push(idt.getId(Integer.parseInt(tis.getTop().getInside())).getName());
			else
				msSmtm.push("_");
			tis.pop();
			
		}
		//归约
		else if(action.charAt(0)=='r'){
			int y=Integer.parseInt(actNum);
			output(y);//输出动作说明等

			if(y==0){//A->id=E;赋值语句的语义子程序,为完成
				fis.push(new FourItem("=","T"+Ep,"_","%?%"));
				int i=0;
				for(;i<cont.getCount();i++)
					if(cont.getAllConstant()[i].getValue().equals(tt.getTemp(Ep).getValue())){
						//常数表中已有该常数
						//id指向该常数
						idt.getId(Integer.parseInt(tis.getNextTop().getInside())).setValue(i);
						i=cont.getCount();
					}
				if(i==cont.getCount()){
					//常数表中没有该常数
					//将常数加入常数表
					cont.addConstant("int",tt.getTemp(Ep).getValue());
					//id指向新增常数
					idt.getId(Integer.parseInt(tis.getNextTop().getInside())).setValue(cont.getCount());
				}
			}
			else if(y==1){
				E1p=Ep;
				System.out.println("E1p:"+tt.getTemp(E1p).getValue()+" Tp:"+tt.getTemp(Tp).getValue());
				//新增临时变量
				tt.addTemp();
				Ep=tt.getCount()-1;
				//加入四元式
				fis.push(new FourItem("+","T"+E1p,"T"+Tp,"T"+Ep));
				//执行语义子程序
				//运算结果的值(常数)
				String result=Integer.parseInt(tt.getTemp(E1p).getValue())+Integer.parseInt(tt.getTemp(Tp).getValue())+"";
				tt.getTemp(Ep).setValue(result);
			}
			else if(y==2){
				Ep=Tp;
			}
			else if(y==3){
				T1p=Tp;
				System.out.println("T1p:"+tt.getTemp(T1p).getValue()+" Fp:"+tt.getTemp(Fp).getValue());
				//新增临时变量
				tt.addTemp();
				Tp=tt.getCount()-1;
				//加入四元式
				fis.push(new FourItem("*","T"+T1p,"T"+Fp,"T"+Tp));
				//执行语义子程序
				//运算结果的值(常数)
				String result=""+Integer.parseInt(tt.getTemp(T1p).getValue())*Integer.parseInt(tt.getTemp(Fp).getValue());
				tt.getTemp(Tp).setValue(result);
			}
			else if(y==4){
				Tp=Fp;
			}else if(y==5){
				Fp=Ep;
			}else if(y==6){
				//从Id获取常数表的入口,取出常数值,填入临时变量的value中
				tt.addTemp(cont.getConstant(idt.getId(Integer.parseInt(tis.getNextTop().getInside())).getValue()).getValue());
				Fp=tt.getCount()-1;
			}
			for(int j=0;j<synR[y].length;j++){
				msStatu.pop();//状态出栈
				msSymble.pop();//符号出栈
				msSmtm.pop();//语义出栈
			}
			msSymble.push(synL[y]);//符号入栈
			gt.setTable(msStatu.getTop(), synL[y]);
			msStatu.push(gt.getGoTo());//状态如栈
			msSmtm.push("T"+tt.getCount());
		}			
	}
	//错误处理
	public void error(){
		System.out.println("error,语法错误,输入了多余的符号");
		//错误处理,简单地认为,多输入了符号
		tis.pop();
	}
	
	//输出动作
	public void output(int num){
		//输出分析过程
		statu=symble=state=semanteme="";
		for(int m=0;m<msStatu.getLength();m++)
			statu+=("|"+msStatu.getAll()[m]);
		for(int m=0;m<msSymble.getLength();m++)
			symble+=("|"+msSymble.getAll()[m]);
		for(int m=0;m<msSmtm.getLength();m++)
			semanteme+=("|"+msSmtm.getAll()[m]);
		for(int m=0;m<tis.getLength();m++)
			state+=("|"+tis.getAll()[m].getCategory());
		String actionDes=" ";//动作说明
		if(action.charAt(0)=='r'){//归约
			actionDes="用"+syntax[num]+"进行规约";
		}else if(action.equals("acc")){
			actionDes="分析成功";
		}else if(action.charAt(0)=='s'){//移进
			actionDes="状态"+num+"入状态栈";
		}System.out.println(statu+"\t\t"+symble+"\t\t"+semanteme+"\t\t"+state+"\t\t\t"+action+":"+actionDes);		
	}
	//getters and setters

	public void setIdt(IdentifierTable idt) {
		this.idt = idt;
	}

	public void setCont(ConstantTable cont) {
		this.cont = cont;
	}

	public void setTt(TemporaryTable tt) {
		this.tt = tt;
	}

	public void setTis(TwoItemStack tis) {
		this.tis = tis;
		til=tis.getLength();
	}

	public void setFis(FourItemStack fis) {
		this.fis = fis;
	}
	public void outVn(){
		System.out.println("Ep:"+Ep+" E1p:"+E1p+" Tp:"+Tp+" T1p:"+T1p+" Fp:"+Fp);
	}
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值