⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbasic.java

📁 一个很小的语言解释器,表述了一个微型的 smallbasic语言的解释过程,可以以该语言进行简单的过程语言编程
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		catch(EmptyStackException exc){
			handleErr(NEXTWITHOUTFOR);
		}
	}
	/* 输入语句处理
	 * INPUT "提示字符串",输入变量
	 * INPUT 输入变量
	 * 
	 */
	private void input() throws InterpreterException{
		int var;
		double val = 0.0;
		String str;
		//输入缓冲区
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		getToken();
		//查看是否有提示字符串
		if(tokType == QUOTEDSTR){
			//输出提示字符串
			System.out.print(token);
			getToken();
			//句法错误,应输入逗号
			if(!token.equals(",")) handleErr(SYNTAX);
			getToken();
		}
		else{
			System.out.print("?系统提示输入: ");
			//System.out.print("? ");
		}
		//获取输入值存储变量名
		var = Character.toUpperCase(token.charAt(0)) - 'A';
		
		try{
			str = br.readLine();
			val = Double.parseDouble(str);
		}
		catch(IOException exc){
			handleErr(INPUTIOERROR);
		}
		catch(NumberFormatException exc){
			System.out.println("无效输入! 数据格式错误!");
		}
		//存储变量值
		vars[var]= val;
	}
	/* GOSUB 语句处理
	 * GOSUB 标签
	 */
	private void gosub() throws InterpreterException{
		Integer loc;
		getToken();
		//查找子程序标记地址下标
		loc = (Integer)labelTable.get(token);
		//找不到行号
		if(loc == null)
			handleErr(UNDEFLABEL);
		else{
			//保存返回地址
			gStack.push(new Integer(progIdx));
			//程序从loc开始执行 调用子程序
			progIdx = loc.intValue();
		}
	}
	/* RETURN 语句
	 * 
	 */
	private void greturn() throws InterpreterException{
		Integer t;
		try{
			//返回调用地址
			t = (Integer)gStack.pop();
			progIdx = t.intValue();
		}//没有配对 GOSUB 于 RETURN
		catch(EmptyStackException exc){
			handleErr(RETURNWITHOUTGOSUB);
		}
	}
	//******************  表达式解析器   ******************************
	/*
	 * 解析表达式入口
	 */
	private double evaluate() throws InterpreterException{
		double result = 0.0;
		getToken();
		//没有表达式错误
		if(token.equals(EOP))
			handleErr(NOEXP);
		//解析计算表达式
		result = evalExp1();
		putBack();
		return result;
	}
	/*
	 * 处理逻辑关系运算
	 */
	private double evalExp1() throws InterpreterException{
		double l_temp,r_temp,result;
		char op;
		result = evalExp2();
		//如果程序结束,返回
		if(token.equals(EOP)) return result;
		
		op = token.charAt(0);
		
		if(isRelop(op)){
			l_temp = result;
			getToken();
			r_temp = evalExp1();
			//执行关系运算
			switch(op){
			case '<':
				if(l_temp < r_temp) result = 1.0;
				else result = 0.0;
				break;
			case LE:
				if(l_temp <= r_temp) result = 1.0;
				else result = 0.0;
				break;
			case '>':
				if(l_temp > r_temp) result = 1.0;
				else result = 0.0;
				break;
			case GE:
				if(l_temp >= r_temp) result = 1.0;
				else result = 0.0;
				break;
			case '=':
				if(l_temp == r_temp) result = 1.0;
				else result = 0.0;
				break;
			case NE:
				if(l_temp != r_temp) result = 1.0;
				else result = 0.0;
				break;
			}
		}
		return result;
	}
	/*
	 * 执行加减运算
	 */
	private double evalExp2() throws InterpreterException{
		char op;
		double result;
		double partialResult;
		
		result = evalExp3();
		
		while((op = token.charAt(0))=='+' || op=='-'){
			getToken();
			partialResult = evalExp3();
			switch(op){
			case '-':
				result = result - partialResult;
				break;
			case '+':
				result = result + partialResult;
				break;
			}
		}
		return result;
	}
	/*
	 * 执行乘或除或取余两个因数
	 */
	private double evalExp3() throws InterpreterException{
		char op;
		double result;
		double partialResult;
		
		result = evalExp4();
		
		while((op=token.charAt(0))=='*' || op=='/' || op=='%' ){
			getToken();
			partialResult = evalExp4();
			switch(op){
			case '*':
				result = result * partialResult;
				break;
			case '/':
				//除零错误
				if(partialResult == 0.0) handleErr(DIVBYZERO);
				result = result / partialResult;
				break;
			case '%':
				//除零错误
				if(partialResult == 0.0) handleErr(DIVBYZERO);
				result = result % partialResult;
				break;
			}
		}
		return result;
	}
	/*
	 * 乘方运算
	 */
	private double evalExp4() throws InterpreterException{
		double result;
		double partialResult;
		double ex;
		int t;
		
		result = evalExp5();
		
		if(token.equals("^")){
			getToken();
			partialResult = evalExp4();
			ex = result;
			if(partialResult == 0.0){
				result = 1.0;
			}
			else{
				for(t=(int)partialResult-1;t>0;t--)
					result = result * ex;
			}
		}
		return result;
	}
	/*
	 * 正负号运算
	 */
	private double evalExp5() throws InterpreterException{
		double result;
		String op;
		op="";
		if((tokType == DELIMITER) && token.equals("+") || token.equals("-")){
			op = token;
			getToken();
		}
		result = evalExp6();
		if(op.equals("-")) result = -result;
		return result;
	}
	/*
	 * 括号的处理
	 */
	private double evalExp6() throws InterpreterException{
		double result;
		
		if(token.equals("(")){
			getToken();
			result = evalExp2();
			if(!token.equals(")"))
				handleErr(UNBALPARENS);
			getToken();
		}
		else{
			result = atom();
		}
		return result;
	}
	/*
	 * 获得表达式的数值
	 */
	private double atom() throws InterpreterException{
		double result = 0.0;
		switch(tokType){
		case NUMBER:
			try{
				result = Double.parseDouble(token);
			}
			catch(NumberFormatException exc){
				handleErr(SYNTAX);
			}
			getToken();
			break;
		case VARIABLE:
			result = findVar(token);
			getToken();
			break;
		default:
			handleErr(SYNTAX);
			break;
		}
		return result;
	}
	/*
	 * 返回变量的值
	 */
	private double findVar(String vname) throws InterpreterException{
		if(!Character.isLetter(vname.charAt(0))){
			handleErr(SYNTAX);
			return 0.0;
		}
		return vars[Character.toUpperCase(vname.charAt(0))-'A'];
	}
	//********************************************************************
	/*
	 * 返回一个项到输入流
	 */
	private void putBack()
	{
		if(token == EOP) return;
		for(int i=0;i<token.length();i++) progIdx--;
	}
	/*
	 * 解释器错误描述符
	 */
    private void handleErr(int error) throws InterpreterException{
    	String[] err = {
    			"程序语法错误! Synatax Error!",
				"程序括号不匹配! Unbalanced Parentheses!",
				"当前没有表达式! No Expression Present!",
				"程序发生除零错! Division by zero!",
				"赋值语句缺少等号! Equal sign expected!",
				"不是一个可识别变量! Not a variable!",
				"标识符数量超出限定! Label table full!",
				"标识符名称重复定义! Duplicate label!",
				"标识符未定义! Undefined label!",
				"程序缺少THEN! THEN expected!",
				"程序缺少TO! TO expected!",
				"NEXT超出FOR范围! NEXT without FOR!",
				"RETURN缺少GOSUB调用! RETURN without GOSUB!",
				"需要结束引号! Closing quotes needed!",
				"没有找到文件! File not found!",
				"程序载入错误! I/O error while loading file!",
				"程序输入错误! I/O error on INPUT statement!"
    	};
    	//抛出异常
    	throw new InterpreterException(err[error]);
    }
    /*
     * 获得表达式下一项
     */
    private void getToken() throws InterpreterException{
    	char ch;
    	tokType = NONE;
    	token = "";
    	kwToken = UNKNCOM;
    	
    	//检查是否是程序结束
    	if(progIdx == prog.length){
    		token = EOP;
    		return;
    	}
    	//去除空格和制表符
    	while(progIdx < prog.length && isSpaceOrTab(prog[progIdx]))
    		progIdx++;
    	//再次检查是否程序结束
    	if(progIdx == prog.length){
    		token = EOP;
    		tokType = DELIMITER;
    		return;
    	}
    	//如果为回车符,当前项为回车换行
    	if(prog[progIdx] == '\r'){
    		progIdx +=2;
    		kwToken = EOL;
    		token = "\r\n";
    		return;
    	}
    	//检查逻辑操作符
    	ch = prog[progIdx];
    	if(ch == '<' || ch == '>'){
    		if(progIdx+1 == prog.length) handleErr(SYNTAX);
    		switch(ch){
    		case '<':
    			if(prog[progIdx+1] == '>'){
    				progIdx += 2;
    				token = String.valueOf(NE);
    			}
    			else if(prog[progIdx+1] == '='){
    				progIdx += 2;
    				token = String.valueOf(LE);
    			}
    			else{
    				progIdx++;
    				token = "<";
    			}
    			break;
    		case '>':
    			if(prog[progIdx+1] == '='){
    				progIdx += 2;
    				token = String.valueOf(GE);
    			}
    			else{
    				progIdx++;
    				token = ">";
    			}
    			break;
    		}
    		tokType = DELIMITER;
    		return;
    	}
    	//如果是表达式分隔符
    	if(isDelim(prog[progIdx])){
    		//是一个操作符
    		token += prog[progIdx];
    		progIdx++;
    		tokType = DELIMITER;
    	}//如果是变量或关键字
    	else if(Character.isLetter(prog[progIdx])){
    		while(!isDelim(prog[progIdx])){
    			token += prog[progIdx];
    			progIdx++;
    			if(progIdx >= prog.length) break;
    		}
    		kwToken = loopUp(token);
    		if(kwToken == UNKNCOM) tokType = VARIABLE;
    		else tokType = COMMAND;
    	}//如果是数值
    	else if(Character.isDigit(prog[progIdx])){
    		while(!isDelim(prog[progIdx])){
    			token += prog[progIdx];
    			progIdx++;
    			if(progIdx >= prog.length) break;
    		}
    		tokType = NUMBER;
    	}//如果是引号,表示字符串
    	else if(prog[progIdx] == '"'){
    		progIdx++;
    		ch = prog[progIdx];
    		while(ch!='"' && ch!='\r'){
    			token += ch;
    			progIdx++;
    			ch = prog[progIdx];
    		}
    		if(ch == '\r') handleErr(MISSINGQUOTE);
    		progIdx++;
    		tokType = QUOTEDSTR;
    	}//不能识别字符进入程序
    	else{
    		token = EOP;
    		return;
    	}	
    }
    /*
     * 如果为分隔符,返回TRUE
     */
    private boolean isDelim(char c){
    	if((" \r,;<>+-/*%^=()".indexOf(c) != -1))
    		return true;
    	return false;
    }
    /*
     * 如果是空格或制表符,返回TRUE
     */
    private boolean isSpaceOrTab(char c){
    	if(c==' ' || c=='\t')
    		return true;
    	return false;
    }
    /*
     * 如果是逻辑操作符,返回TRUE
     */
    private boolean isRelop(char c){
    	if(relops.indexOf(c)!= -1) return true;
    	return false;
    }
    /*
     * 寻找关键字的内部表示形式
     */
    private int loopUp(String s){
    	int i;
    	//转换为小写字母
    	s = s.toLowerCase();
    	//查看是否在表中
    	for(i=0;i< kwTable.length;i++){
    		if(kwTable[i].keyword.equals(s)){
    			return kwTable[i].keywordTok;
    		}
    	}
    	return UNKNCOM;
    }
    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -