`
metaphy
  • 浏览: 344618 次
  • 性别: Icon_minigender_1
  • 来自: 大西洋底
社区版块
存档分类
最新评论

算术表达式求值

阅读更多
词法分析
package compile;
/**
 * 词法分析:返回数字和操作符号的序列
 * @author metaphy
 * 2007-6-14
 */
public class Lexer {
	public static final String EOS = " " ; 	/*token之间的分隔符*/
	public static final String DONE ="=" ;	/*token结束的标记*/
	private StringBuffer tokens = new StringBuffer();
	private String expression = null;
	
	public Lexer(String expression) {
		super();
		this.expression = expression;
	}
	
	/*判断在是否数字*/
	private boolean isDigit(char c){
		return c>='0' && c<='9' ;
	}
	/*判断是否操作符*/
	private boolean isOperator(char c){
		return c=='+' ||c=='-' ||c=='*' ||c=='/'|| c=='('|| c==')' ||c=='%' || c=='^'; 
	}
	/*判断是否字母*/
	private  boolean isAlpha(char c){
		return c>='a' && c<= 'z' || c>='A' && c<='Z' ;
	}
	
	/*以EOS为分隔符将单词分隔*/
	public String lexan(){
		String str ="" ;	/*数字序列*/
		for (int i=0 ;i< expression.length(); i++){	
			char ch = expression.charAt(i) ;
			if( (isOperator(ch) || isAlpha(ch)) && !str.equals("")){
				tokens.append(str.trim()) ;
				tokens.append(EOS) ;
				str="" ;
			}
			if(ch ==' ' || ch== '\t'){
				;
			}else if(isDigit(ch)){		//数字
				if (!(str.equals("") && ch=='0')){
					str += String.valueOf(ch) ;
				}
			}else if(isOperator(ch)){	//操作符
				str = "" ;
				tokens.append(ch) ;
				tokens.append(EOS) ;
			}else{						//其他符号未处理

			}
			if((i==expression.length() -1) && !str.trim().equals("")) {
				tokens.append(str.trim()) ;
				tokens.append(EOS) ;
			}
		}
		tokens.append(DONE) ;
		return tokens.toString().trim();
	}
}

语法分析和翻译
package compile;

import java.util.ArrayList;
import java.util.Stack;

/**
 * 语法分析和翻译:算术表达式求值。非负整数的加、减、乘、除、取模和幂操作,
 * 优先级顺序为:幂=>乘、除、模=>加、减,同级求值顺序从左向右,小括号可以改变优先级。
 * BNF定义:
 * digit -> 0|1|2|3|4|5|6|7|8|9|digit 
 * factor -> digit | ( exp ) 
 * power -> factor | power ^ factor 
 * term -> power | term * power | term / power | term % power
 * exp -> term | exp + term | exp - term 
 * 
 * @author metaphy
 * 2007-6-14
 */

public class Parser {
//	String s = "2 000*(33%10)+	12/ (9-3) * (6-2+ 11) + 2^3 " ;
//	String s = " 3 3 * (008 % 6)" ;
//	String s = "1+1";
//	String s = "3^(1+1)";
	String s = "(100-95)*3^(1+1)";
	private Lexer lex = new Lexer(s) ;
	
	private ArrayList tokenList ;
	private String lookahead;
	private int pointer ;
	Stack stack = new Stack() ;		//后缀表达式计算堆栈
	
	private void init(){
		tokenList = new ArrayList() ;
		String tokenString = lex.lexan() ;
		System.out.print (tokenString);
		String[] strs = tokenString.split(Lexer.EOS) ;
		lookahead = strs[0].trim() ;
		pointer = 0 ;
		for (int i=0 ;i< strs.length; i++){
			if(strs[i]==null) {
				error();
				return ;
			}
			tokenList.add(strs[i].trim());
		}
	}
	/*判断在是否整数*/
	private boolean isDigit(String str){
		try{
			Long.parseLong(str);
			return true ;
		}catch(Exception e){
			return false ;
		}
	}
	/*往下匹配*/
	private void matchNext(String t){
		if(lookahead.equals(t)){
			pointer ++ ;
			lookahead = (String)tokenList.get(pointer) ;
		}else {
			error() ;
		}
	}
	/*出错信息*/
	private void error(){
		System.out.println("error occurs, current obj: "+ lookahead);
		System.exit(1) ;
	}
	
	/*因子:带小括号表达式或数字,第1优先级*/
	private void factor(){
		if(lookahead.equals("(")){
			matchNext("(") ;
			expr() ;
			matchNext(")") ;
		}else if(isDigit(lookahead)){
			emit(lookahead) ;
			matchNext(lookahead) ;
		}else {
			error() ;
		}
	}
	
	/*乘幂操作,第2优先级*/
	private void power(){
		factor();
		while(true){
			if(lookahead.equals("^")){
				String tmp = lookahead ;
				matchNext(lookahead) ;
				factor() ;
				emit(tmp) ;
				continue ;
			}else{
				return ;
			}
		}
	}
	
	/*乘、除、取模操作*/
	private void term(){
		power();
		while(true){
			if(lookahead.equals("*")||lookahead.equals("/")||lookahead.equals("%")){
				String tmp = lookahead; 
				matchNext(lookahead) ;
				power();
				emit(tmp) ;
				continue ;
			}else{
				return ;
			}
		}
	}
	
	/*表达式:term的+ - 操作*/
	private void expr(){
		term() ;
		while(true){
			if(lookahead.equals("+")||lookahead.equals("-")){
				String tmp = lookahead ;
				matchNext(lookahead);
				term();
				emit(tmp) ;
				continue ;
			}else{
				return ;
			}
		}
	}
	
	/*生成后缀表达式,利用堆栈计算*/
	private void emit(String some){
//		System.out.println (some) ;
		if(isDigit(some)){
			stack.push(some) ;
		}else{
			long right =Long.parseLong((String) stack.pop()) ;
			long left =Long.parseLong((String) stack.pop()) ;
			long result =1 ;
			if(some.equals("+")){
				result = left + right; 
			}else if(some.equals("-")){
				result = left - right;
			}else if(some.equals("*")){
				result = left * right;
			}else if(some.equals("/")){
				try{
					result = left / right;
				}catch(Exception e){
					System.err.println("除以0错误") ;
					error() ;
				}
			}else if(some.equals("%")){
				result = left % right;
			}else if(some.equals("^")){
				for(int j = 1 ;j<= right ;j ++)
					result *= left ;
			}else{
			}
			stack.push(String.valueOf(result));
		}
	}
	private String getValue (){
		if (stack==null || stack.firstElement() ==null ){
			error ();
		}
		return (String)stack.pop() ;
	}
	
	/*begin*/
	private void parse(){
		while(! lookahead.equals(Lexer.DONE)){
			expr();
		}
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Parser parser = new Parser() ;
		parser.init();
		parser.parse();
		System.out.println(parser.getValue()) ;
	}
}
运行结果:
( 100 - 95 ) * 3 ^ ( 1 + 1 ) =45

1
0
分享到:
评论
2 楼 metaphy 2009-08-07  
没考虑负数和小数
1 楼 chenxf84 2008-12-30  
负数和小数呢?

相关推荐

    栈的应用----算术表达式求值程序

    栈的应用广泛,其中之一就是用于解决算术表达式的求值问题。本文将深入探讨如何利用栈来实现一个算术表达式求值的程序。 首先,我们要理解算术表达式的构成。一个基本的算术表达式可能包含数字、运算符(如加号"+...

    java算术表达式求值

    Java算术表达式求值是程序设计中一个常见的任务,特别是在动态计算或用户输入解析的场景下。在Java中,处理这种需求通常涉及到解析和计算字符串形式的数学表达式。这个压缩包文件包含了多种资源,可以帮助我们理解并...

    数据结构算术表达式求值实验报告

    《数据结构算术表达式求值实验报告》 在计算机科学中,算术表达式的求值是一项基础且关键的任务。本实验报告将详细介绍如何利用数据结构来处理和求解不含变量的整数算术表达式。以下是实验的核心知识点: 1. **...

    设计一个程序,演示用算符优先法对算术表达式求值的过程

    ### 设计一个程序,演示用算符优先法对算术表达式求值的过程 #### 一、背景介绍 算术表达式的求值是计算机科学中的一个基础问题,它不仅是编程语言实现的重要组成部分,也是理解数据结构(如栈)的关键应用案例之...

    数据结构C语言版算术表达式求值

    采用栈的数据结构编写算术表达式求值,定义了字符栈和数据栈

    算术表达式求值演示1

    在IT领域,算术表达式的求值是一项基础且重要的任务,尤其在编程语言如C和C++中。本文将深入探讨算术表达式求值的原理、方法以及相关的编程实践,以"算术表达式求值演示1"为例,解析其中涉及到的知识点。 首先,...

    基于栈的算术表达式求值算法

    基于栈的算术表达式求值算法是一种常见的计算方法,主要应用于解决逆波兰表示法(Reverse Polish Notation,RPN)或中缀表达式的求值问题。本实验旨在让学生掌握栈这种数据结构的定义和实现,并能利用栈解决实际问题...

    算术表达式求值(数据结构课设)

    数据结构的算术表达式求值,能计算正实数的基本运算,并有相应的纠错功能

    数据结构课程设计—算术表达式求值

    算术表达式求值:一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符,如:引入表达式...

    栈实现算术表达式求值和队列实现舞伴配对

    1.通过修改完善课件案例 3.3 的算法,利用栈来实现算术表达式求值的算法。对算法中调 用的几个函数要给出其实现过程: (1) 函数 In(c):判断 c 是否为运算符; (2) 函数 Precede(t1,t2):判断运算符 t1 和 t2 的...

    算术表达式求值演示

    本示例中的“算术表达式求值演示”聚焦于如何利用数据结构来解决计算复杂算术表达式的问题。在这个过程中,我们将探讨栈这一重要的数据结构,以及它是如何在计算过程中起到关键作用的。 栈是一种后进先出(LIFO)的...

    数据结构实验-算术表达式求值

    ### 数据结构实验——算术表达式求值 #### 实验目的 本次实验旨在实现一个能够对包含浮点数的算术表达式进行求值的程序。通过本实验,学生能够进一步掌握栈的基本操作及其在实际问题中的应用,并理解并实现中缀...

    【数据结构】算术表达式求值演示

    本文将深入探讨一个特定的主题——"算术表达式求值",这是数据结构应用的一个实例,主要涉及编译原理、解析器设计以及C++编程语言。 算术表达式求值是指对包含加、减、乘、除等运算符的数学表达式的计算过程。在...

    算术表达式求值完整课程设计报告-对于基本的算术表达式,以字符序列的形式从终端进行输入,要求语法正确的,不含变量,按照算术运算优先级顺序,实现基本算术表达式的运算过程。

    本课程设计报告主要探讨了如何实现一个简单的算术表达式求值系统,该系统能够处理不含变量的、基于字符序列的算术表达式,并按照运算优先级顺序进行运算。以下是详细的知识点说明: 1. **输入与输出**: - 用户...

Global site tag (gtag.js) - Google Analytics