编译中的基于算符优先分析程序的语法制导翻译

这是一个基于Java实现的算符优先分析程序,用于进行语法制导的翻译。程序首先检查输入字符串的合法性,然后通过比较字符优先级、进栈和归约操作来处理语法结构。当遇到无法比较的优先级时,会提示输入无效。
摘要由CSDN通过智能技术生成
import java.util.*;

/**
 * @author SXH
 * @说明 基于算符优先分析方法的语法制导翻译程序
 */
public class GrammarTransiation {
	/**
	 * 源串
	 * */
	static String resourceCode;

	/**
	 * 判断是否可以继续执行
	 */
	static boolean flag = true;

	/**
	 * 栈
	 * */
	static StringBuilder stack = new StringBuilder("#");

	/**
	 * 输入缓冲区
	 * */
	static StringBuilder buffer = new StringBuilder();

	/**
	 * 步骤
	 */
	static int step = 1;

	/**
	 * 四元式序号
	 */
	static int siYianShi = 0;

	/**
	 * 存放将要被归约为N的他前面N的个数
	 */
	static int n = 0;

	/**
	 * 存放N对应的值
	 */
	static String nValue[] = new String[10];

	/**
	 * 存放结果Tn
	 */
	static int result = 1;

	/**
	 * 栈顶第一个终结符
	 */
	static int top;

	/**
	 * 字符顺序表 **暂时用/表示
	 */
	static String sequenceList = "+*/i()#";

	/**
	 * 优先关系表,其中1为高于,0为等于,-1为低于,-2为不能比
	 */
	static int relation[][] = { { 1, -1, -1, -1, -1, 1, 1 },
			{ 1, 1, -1, -1, -1, 1, 1 }, { 1, 1, -1, -1, -1, 1, 1 },
			{ 1, 1, 1, -2, -2, 1, 1 }, { -1, -1, -1, -1, -1, 0, -2 },
			{ 1, 1, 1, -2, -2, 1, 1 }, { -1, -1, -1, -1, -1, -2, 0 } };

	/**
	 * 主程序
	 */
	public static void main(String[] args) {

		System.out.print("请输入字符串:");
		Scanner s = new Scanner(System.in);
		resourceCode = s.nextLine();
		buffer.append(resourceCode);
		if (sequenceList.indexOf(buffer.charAt(0)) == -1) {// 要检测缓冲区首字符
			flag = false;
			System.err.println("\t由于包含非法字符,这不是句子!!!");
			return;
		}
		if (buffer.charAt(0) != 'i' && buffer.charAt(0) != '(') {// 不会出现第一个字符不是i和(的时候
			flag = false;
			System.err.println("\t你的语法混乱,这不是句子!!!");
			return;
		}
		for (int i = 1; i < buffer.length() - 2; i++) {
			if (buffer.charAt(i) != 'i') {
				if (buffer.charAt(i) == '(') {// 左括号后面只能接i
					if (buffer.charAt(i + 1) == ')'
							|| buffer.charAt(i + 1) == '+'
							|| buffer.charAt(i + 1) == '*'
							|| buffer.charAt(i + 1) == '/') {

						flag = false;
						System.err.println("\t你的语法混乱,这不是句子!!!");
						return;
					}
				}
			}
		}
		System.out.println("***************************************");
		System.out.println("步骤\t\t栈\t\t输入缓冲区");

		System.out.println(step++ + "\t\t" + stack + "\t\t" + buffer);
		move();
		do {
			top = stack.length() - 1;// top指向栈顶第一个非终结符
			if (buffer.charAt(0) == '#') {// 判断退出
				if (stack.charAt(stack.length() - 2) == '#'
						&& stack.charAt(stack.length() - 1) == 'N') {
					System.out.println();
					System.out.println("\t该输入串是句子,可以放心使用。");
					break;
				}
			}

			if (stack.charAt(top) == 'N') {
				top--;
			}

			if (sequenceList.indexOf(buffer.charAt(0)) == -1) {// 每次要检测缓冲区首字符
				flag = false;
				System.err.println("\t由于包含非法字符,这不是句子!!!");
				return;
			}

			compare(stack.charAt(top), buffer.charAt(0));
		} while (flag);
	}

	/**
	 * 字符优先级比较、进栈、归约
	 * */
	static void compare(char a, char b) {

		int i = sequenceList.indexOf(a);// 行
		int j = sequenceList.indexOf(b);// 列
		// System.out.println(i+"       "+j);
		switch (relation[i][j]) {
		case 1:// a>b,从栈顶找第二个终结符,准备归约
			int second;
			for (second = top - 1; stack.charAt(second) == 'N'; second--) {
				continue;
			}

			n = 0;
			for (int m = 0; m < top; m++) {// 找到这个字符前面有几个N
				if (stack.charAt(m) == 'N') {
					n++;
				}
			}
			// System.out.println(n);

			i = sequenceList.indexOf(stack.charAt(top));
			j = sequenceList.indexOf(stack.charAt(second));
			if (relation[j][i] == 0) {// 栈顶首终结符和第二终结符优先级相等
				stack.replace(second, top + 1, "N");// 从第二终结符到首终结符都除去,用N替换

			} else if (relation[j][i] == -1) {// 栈顶首终结符优先级高
				if (stack.charAt(top - 1) == 'N') {// 如果左边有N,则右边也有,和两边的N一起归约

					System.out.println("\t四元式" + ++siYianShi + "("
							+ stack.charAt(top) + "," + nValue[n - 1] + ","
							+ nValue[n] + "," + "T" + result + ")");// 输出四元式
					nValue[n - 1] = "T" + result++;// 将结果Tn保存,与此N对应上
					stack.delete(top, top + 2);// 删除掉从start到end-1的字符

				} else {
					nValue[n] = Character.toString((stack.charAt(top)));// 将他与N对应上
					stack.deleteCharAt(top);// 只归约它自己,他处于栈顶
					stack.append('N');
				}
			}
			System.out.println(step++ + "\t\t" + stack + "\t\t" + buffer);

			break;
		case 0:// a=b,b入栈

			// break;
		case -1:// a<b,b入栈

			move();
			break;
		default:// 不能比较
			System.err.println("   " + a + "与" + b + "此时不能比较优先级,这个输入串不是句子!!!");
			flag = false;
		}

		return;
	}

	/**
	 * 将缓冲区首字符移到栈顶
	 */
	static void move() {
		stack.append(buffer.charAt(0));
		buffer.deleteCharAt(0);
		System.out.println(step++ + "\t\t" + stack + "\t\t" + buffer);
	}
}

算符优先分析法 C++ 编译原理 运行环境:Visual Studio 2005 #include "SStack.h" #include <iostream> #include <string> using namespace std; class Functor { private : char ** table; string ** production; string prog;//待分析字符串 int p;//字符指针 int num;//终结符个数 int num1;//产生式个数 SStack <char> stack; public: Functor(int m,int n,char ** T,string **prod,string pr) { num=m; num1=n; table=T; production=prod; prog=pr; p=0; stack.push('$'); } void traversal() { while(p<(prog.length())) { stack.display(); cout<<prog.substr(p)<<" "; char ch; if(Getnum(stack.gettop())) { ch=stack.gettop(); } else { ch=stack.getsecond(); } switch(compare(ch,prog[p])) { case 1: case 2:stack.push(prog[p]);p++;cout<<"移入"<<endl;break; case 3:reduct();cout<<"归约"<<endl;break; } } cout<<"分析成功!"<<endl; } int Getnum(char ch) { for(int i=1;i<num;i++) { if(ch==table[i][0]) { return i; } } return 0; } int compare(char col,char row) { int c=Getnum(col); int r=Getnum(row); switch( table[c][r]) { case '>': return 3;break; case '<': return 2;break; case '=': return 1;break; default:cout<<endl<<"输入串有误,程序将终止!"<<endl;system("pause");exit(0);break; } } void reduct() { //待定 string token=""; int temp; string str=""; if(!Getnum(stack.gettop())) { token+=stack.gettop(); stack.pop(); } char ch=stack.gettop(); str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); bool Nover=true; while(Nover) { if(Getnum(stack.gettop())) { if(compare(stack.gettop(),ch)==2) { Nover=false; } else { ch=stack.gettop(); str=""; str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); } } else { token+=stack.gettop(); stack.pop(); } } string token2=""; //cout<<token<<" "; for(int i=token.length()-1;i>=0;i--) { token2+=token[i]; } //cout<<token2<<endl; if(Haven(token2)!= -1) { stack.push(production[Haven(token2)][0][0]); } else { cout<<"输入串有误!分析终止!"<<endl; system("pause"); exit(0); } } int Haven(string temp) { for(int i=0;i<num1;i++) { int j=1; while(production[i][j]!="") { if(temp==production[i][j]) { return i; } j++; } } return -1; } public: ~Functor(void) { } };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值