算术表达式求值问题z-数据结构与算法课程设计报告
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
表1 算符之间的优先关系
θ1 θ2 + * / (
+ > > > > <
> > > > <
* < < > > <
/ < < > > <
( < < < < <
) > > > > =
# > > > >
)
>
>
>
>
>
>
# < < < < < = 表格说明: 1、θ1 、θ2 同“*”、“/”或同为“+”、“-”,则算符θ1的优先级 高于θ2 2、θ1为“*”、“/”的优先级高于θ1为“+”、“-” 3、θ1为“+”、“-”、“*”、“/”的优先级高于θ2为“)” 4、θ1为“(”的优先级低于θ2为“+”、“-”、“*”、“/” 5、θ1、θ2同为“(”,θ1的优先级低于θ2;θ1、θ2同为“(”, θ1的优先级高于θ2 6、θ1为“(”且θ2为“)”,或者,θ1、θ2同为“#”,则θ1、θ2的 优先级相同 7、θ1为“)”、θ2为“(”,或者,θ1为“#”θ2为“)”,或者θ1 为“(”θ2为“#”,这3中情况各自之间无优先关系,表示为“ ”,因为 表达式中不允许它们相继出现,如果出现,则可以认为出现语法错误。 ③最后,确定算法的基本思想: 设置两个工作栈,一个为OPTR栈,存放运算符;另一个为OPND 栈,存放操作数或运算结果。则算法的基本思想描述如下: (1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元 素; (2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算 符则和OPTR栈的栈顶运算符比较优先级后,做如下相应操作: ①若栈顶算符θ1的优先级低于刚读入的算符θ2,则将θ2入算符栈 OPTR ②若栈顶算符θ1的优先级高于刚读入的算符θ2,则将让θ2出栈;同 时,将操作数栈OPND退栈两次,得到两个操作数x、y,对x、y运用θ2 进行运算后,再将运算结果如操作数只栈OPND ③若栈顶算符算符θ1的优先级等于刚读入的算符θ2,说明左右括号 相遇,或者是表达式的起始、结束符相遇,只需将栈顶算符(左括号或 起始符)退栈即可;当算符栈OPTR栈空时,算法结束。 二、数据结构的选择和概要设计 数据结构的选择: 本程序采用顺序存储结构存储两个栈,即操作数栈(OPND)和算符 栈(OPTR);
合肥学wenku.baidu.com 计算机科学与技术系
课程设计报告
2009~2010学年第二学期
课程 课程设计名 称 学生姓名 学号 专业班级 指导教师 数据结构与算法 算术表达式求值问题 杨松 0804012031 08计科(2) 王昆仑 张贯虹 2010年6月
题目:(算术表达式求值问题)一个算术表达式是由操作数 (operand)、运算符(operator)和界限符(delimiter)组成的。假设操作 数是正整数,运算符只含加减乘除四种运算符,界限符有左右括号和表 达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。引入表达式 起始、结束符是为了方便。编程利用“算符优先法”求算术表达式的 值。要求:(1)从键盘读入一个合法的算术表达式,输出正确的结 果。(2)显示输入序列和栈的变化过程。选作内容:操作数类型扩充
算符栈的初始化 获取算符栈的栈顶元素 算符栈的栈顶插入新的数据元素 算符栈的栈顶元素出栈
表3 操作数栈的功能函数
OPND栈
int OPND_InitStack(OPND _STACK &s) double OPND_GetTop(OPND _STACK &s) int OPND_Push(OPND_STACK &s, double e) int OPND_Pop(OPND_STACK &s, double &e)
操作数栈的初始化 获取操作数栈的栈顶元素 操作数栈的栈顶插入新的数据元 素 操作数栈的栈顶元素出栈
表4 算术表达式的相关功能函数 double Operate( double a, char theta, 两个操作数之间的四则运算函数 double b) int In(char Test, char * TestOp) int ReturnOpOrd(char op, char* TestOp)
性,包括算符的合法性和操作数的合法性,所以应设计算符合法性的判 断函数,即int In(char Test, char * TestOp),将依次读入的字符与算符数 组中的所有算符依次比较,若算符合法,则返回该算符在算符数组中的 位置m,若算符不合法,则均返回0。 在判断算符的合法性之后,则应该对相邻的两个算符的优先级进行 比较,以便于算术表达式的相关运算,所以应设计函数char Precede(char Aop, char Bop)比较两个算符Aop和Bop的优先级,返回值即为两个算符 对应在算符优先级二维数组Prior[7][7]中的值。 经过上述两个步骤,确定了的算符的合法性与否以及两个算符的优 先级,然后即要判断算术表达式的合法性与否,并同时对该算术表达式 进行一系列的计算,设计函数double EvaluateExpression (char * MyExpression)。 该函数需要的所有变量为:OPTR,为算符栈;OPND,为操作数 栈;TempData[40],为辅助字符数组,其中所有的字符均为满足合法性 的算术表达式的操作数;theta,为算符;a,b,为运算的两个操作数; Data,为两个数的运算结果;c,为当前读入的字符;Dr[2],为当前读 入的字符和结束符’\0’构成的字符串;其中变量TempData[40]和Dr[2]是 因为考虑到操作数有可能不止一位数,则Dr[2]起到字符衔接的作用, 只要读入的字符是操作数,就将该字符衔接到字符数组TempData[40] 中,则TempData[40]中除了结束符’\0’之外的所有字符就是算术表达式 中的一个完整的操作数,即TempData[40]中存放的操作数或者是一位 数,或者是多位数。 算术表达式的详细计算过程: 首先,将所需的变量初始化:初始化算符栈和操作数栈, OPTR_InitStack (OPTR),OPND_InitStack (OPND);将算术表达式的起 始字符’#’入算符栈;变量c保存当前表达式MyExpression的地址;利用 strcpy()函数将结束符’\0’衔接至数组TempData[40]中。 然后,利用while循环,开始计算。当OPTR栈的栈顶元素 OPTR_GetTop(OPTR)和当前读入的字符*c同时为’#’时,整个表达式求 值完毕;若不满足表达式结束的该条件,则进行计算。读入当前字符 *c: 若*c是操作数,则首先将*c给Dr[2],利用strcat()函数将Dr[2]衔接至 TempData[40]中,然后c++,判断下一个字符*c是否是算符,若不是,说 明当前操作数是多位数,然后再将该操作数字符衔接至TempData[40] 中,然后再c++,重复上述过程,将当前操作数的所有字符完整的保存 至TempData[40]中,利用强制转换函数atof()将TempData[40]中的字符转 换为double型的数据,同时赋给Data,则Data即为当前的完整的double
算符的判断函数 返回该算符在算符数组中的位置 的函数 两个算符的优先级的判断函数 表达式的正确性判断函数,同时 计算表达式
char Precede(char Aop, char Bop) double EvaluateExpression(char * MyExpression)
三、详细设计和编码 首先本程序定义两个顺序栈:算符栈(OPTR)和操作数栈 (OPND); OPTR栈定义如下: typedef struct{ char * base; //算符栈的栈底 char * top; //算符栈的栈顶 int stacksize; //算符栈的最大长度 }OPTR_STACK; OPND栈定义如下: typedef struct{ double * base; //操作数栈的栈底 double * top; //操作数栈的栈顶 int stacksize; //操作数栈的最大长度 }OPND_STACK; 然后是算符栈和操作数栈的相关功能函数的详细设计: (1)算符栈的相关功能函数的详细设计如下: 1、int OPTR_InitStack(OPTR_STACK &s) 为OPTR栈申请char类型的初始空间STACK_INITSIZE=100个 操作结果:构造一个空栈S,最大长度s.stacksize为100; 2、char OPTR_GetTop(OPTR_STACK &s) 初始条件:OPTR栈S已存在且非空(s.top!=s.base) 操作结果:用e= *(s.top-1)返回S的栈顶元素 3、int OPTR_Push(OPTR_STACK &s,char e) 初始条件:OPTR栈S已存在 因为考虑到原先申请的空间可能不够,即当OPTR栈的长度已经大于 s.stacksize=100,这是需要申请额外的存储空间;每次均用realloc函数申 请char类型的额外的STACKINCREMENT=10个存储单元,申请额外空 间后的OPTR栈的最大长度s.stacksize增加10; 操作结果:插入元素e为新的OPTR栈顶元素,即*s.top++=e; 4、int OPTR_Pop(OPTR_STACK &s,char &e) 初始条件:OPTR栈S已存在且非空; 操作结果:OPTR栈顶元素出栈,同时用e保存该栈顶元素,即e=*-s.top; (2)操作数栈的相关功能函数的详细设计如下:
概要设计如下: 运算符栈的相关功能函数 操作数栈的相关功能函数 算术表达式的相关功能函数 主函数
表2 运算符栈的功能函数
OPTR栈
int OPTR_InitStack(OPTR_STACK &s) char OPTR_GetTop(OPTR_STACK &s) int OPTR_Push(OPTR_STACK &s, char e) int OPTR_Pop(OPTR_STACK &s, char &e)
1、int OPND_InitStack(OPND_STACK &s) 为OPTR栈申请double类型的初始空间STACK_INITSIZE=100个 操作结果:构造一个空栈S,最大长度s.stacksize为100; 2、double OPND_GetTop(OPND_STACK &s) 初始条件:OPND栈S已存在且非空(s.top!=s.base) 操作结果:用e= *(s.top-1)返回S的栈顶元素 3、int OPND_Push(OPND_STACK &s,double e) 初始条件:OPND栈S已存在 因为考虑到原先申请的空间可能不够,即当OPND栈的长度已经大 于s.stacksize=100,这是需要申请额外的存储空间;每次均用realloc函数 申请double类型的额外的STACKINCREMENT=10个存储单元,申请额 外空间后的OPND栈的最大长度s.stacksize增加10; 操作结果:插入元素e为新的OPND栈顶元素,即*s.top++=e; 4、int OPND_Pop(OPND_STACK &s,double &e) 初始条件:OPND栈S已存在且非空; 操作结果:OPND栈顶元素出栈,同时用e保存该栈顶元素,即e=*-s.top; (3)下面实现本课程设计目标的算术表达式的相关功能函数的详细设 计过程: 首先应定义7种算符的字符数组char OPSET[OPSETSIZE]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'}; 然后是7算符的的优先级的定义: char Prior[7][7] = { '>' , '>' , '<' , '<' , '<' , '>' , '>', '>' , '>' , '<' , '<' , '<' , '>' , '>', '>' , '>' , '>' , '>' , '<' , '>' , '>', '>' , '>' , '>' , '>' , '<' , '>' , '>', '<' , '<' , '<' , '<' , '<' , '=' , ' ', '>' , '>' , '>' , '>' , ' ' , '>' , '>', '<' , '<' , '<' , '<' , '<' , ' ' , '=' }; 因为算术表达式涉及到两个数的四则运算,所以要设计一个两个数 四则运算的函数,即函数double Operate( double a, char theta, double b),定义了两个数的(加)+、(减)-、(乘)*、(除)/ 四种运算,并返回两个 数的运算结果。 然后,当依次读入算术表达式的各个字符时,要同时判断字符的合法
到实数。 一、问题分析和任务定义 要对一个含有加减乘除四则运算的合法的算术表达式进行求值, ①首先,应了解算术表达式的四则运算的规则: (1)从左向右计算 (2)先乘除,后加减 (3)先括号内,后括号外 由此可知,比如算术表达式(7+15)*(23-28/4)的计算顺序,即 为 (7+15)*(23-28/4)=22*(23-28/4)=22*(23-7) =22*16=352 ②其次,应明确“算符优先法”的内容: 算符优先法就是根据上述四则运算规则确定的优先关系来实现对表 达式的编译或解释执行的。 一个简单的四则运算表达式由操作数(operand)、运算符 (operator)和界限符(delimiter)组成,其中操作数是正整数,运算符 只含加、减、乘、除四种,界限符有左右括号和表达式起始、结束 符“#”;而且,为了统一算法的描述,将运算符和界限符通称为算 符。算符集OP={+,-,*,/,(,),#}。 根据上述3条运算规则,在具体的运算的每一步中,任意两个相继 出现的算符θ1和θ2之间的优先关系只能是如下3中关系之一: θ1<θ2 θ1的优先级低于θ2 θ1=θ2 θ1的优先级等于θ2 θ1>θ2 θ1的优先级高于θ2 下表定义了算符之间的这种优先关系。
θ1 θ2 + * / (
+ > > > > <
> > > > <
* < < > > <
/ < < > > <
( < < < < <
) > > > > =
# > > > >
)
>
>
>
>
>
>
# < < < < < = 表格说明: 1、θ1 、θ2 同“*”、“/”或同为“+”、“-”,则算符θ1的优先级 高于θ2 2、θ1为“*”、“/”的优先级高于θ1为“+”、“-” 3、θ1为“+”、“-”、“*”、“/”的优先级高于θ2为“)” 4、θ1为“(”的优先级低于θ2为“+”、“-”、“*”、“/” 5、θ1、θ2同为“(”,θ1的优先级低于θ2;θ1、θ2同为“(”, θ1的优先级高于θ2 6、θ1为“(”且θ2为“)”,或者,θ1、θ2同为“#”,则θ1、θ2的 优先级相同 7、θ1为“)”、θ2为“(”,或者,θ1为“#”θ2为“)”,或者θ1 为“(”θ2为“#”,这3中情况各自之间无优先关系,表示为“ ”,因为 表达式中不允许它们相继出现,如果出现,则可以认为出现语法错误。 ③最后,确定算法的基本思想: 设置两个工作栈,一个为OPTR栈,存放运算符;另一个为OPND 栈,存放操作数或运算结果。则算法的基本思想描述如下: (1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元 素; (2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算 符则和OPTR栈的栈顶运算符比较优先级后,做如下相应操作: ①若栈顶算符θ1的优先级低于刚读入的算符θ2,则将θ2入算符栈 OPTR ②若栈顶算符θ1的优先级高于刚读入的算符θ2,则将让θ2出栈;同 时,将操作数栈OPND退栈两次,得到两个操作数x、y,对x、y运用θ2 进行运算后,再将运算结果如操作数只栈OPND ③若栈顶算符算符θ1的优先级等于刚读入的算符θ2,说明左右括号 相遇,或者是表达式的起始、结束符相遇,只需将栈顶算符(左括号或 起始符)退栈即可;当算符栈OPTR栈空时,算法结束。 二、数据结构的选择和概要设计 数据结构的选择: 本程序采用顺序存储结构存储两个栈,即操作数栈(OPND)和算符 栈(OPTR);
合肥学wenku.baidu.com 计算机科学与技术系
课程设计报告
2009~2010学年第二学期
课程 课程设计名 称 学生姓名 学号 专业班级 指导教师 数据结构与算法 算术表达式求值问题 杨松 0804012031 08计科(2) 王昆仑 张贯虹 2010年6月
题目:(算术表达式求值问题)一个算术表达式是由操作数 (operand)、运算符(operator)和界限符(delimiter)组成的。假设操作 数是正整数,运算符只含加减乘除四种运算符,界限符有左右括号和表 达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。引入表达式 起始、结束符是为了方便。编程利用“算符优先法”求算术表达式的 值。要求:(1)从键盘读入一个合法的算术表达式,输出正确的结 果。(2)显示输入序列和栈的变化过程。选作内容:操作数类型扩充
算符栈的初始化 获取算符栈的栈顶元素 算符栈的栈顶插入新的数据元素 算符栈的栈顶元素出栈
表3 操作数栈的功能函数
OPND栈
int OPND_InitStack(OPND _STACK &s) double OPND_GetTop(OPND _STACK &s) int OPND_Push(OPND_STACK &s, double e) int OPND_Pop(OPND_STACK &s, double &e)
操作数栈的初始化 获取操作数栈的栈顶元素 操作数栈的栈顶插入新的数据元 素 操作数栈的栈顶元素出栈
表4 算术表达式的相关功能函数 double Operate( double a, char theta, 两个操作数之间的四则运算函数 double b) int In(char Test, char * TestOp) int ReturnOpOrd(char op, char* TestOp)
性,包括算符的合法性和操作数的合法性,所以应设计算符合法性的判 断函数,即int In(char Test, char * TestOp),将依次读入的字符与算符数 组中的所有算符依次比较,若算符合法,则返回该算符在算符数组中的 位置m,若算符不合法,则均返回0。 在判断算符的合法性之后,则应该对相邻的两个算符的优先级进行 比较,以便于算术表达式的相关运算,所以应设计函数char Precede(char Aop, char Bop)比较两个算符Aop和Bop的优先级,返回值即为两个算符 对应在算符优先级二维数组Prior[7][7]中的值。 经过上述两个步骤,确定了的算符的合法性与否以及两个算符的优 先级,然后即要判断算术表达式的合法性与否,并同时对该算术表达式 进行一系列的计算,设计函数double EvaluateExpression (char * MyExpression)。 该函数需要的所有变量为:OPTR,为算符栈;OPND,为操作数 栈;TempData[40],为辅助字符数组,其中所有的字符均为满足合法性 的算术表达式的操作数;theta,为算符;a,b,为运算的两个操作数; Data,为两个数的运算结果;c,为当前读入的字符;Dr[2],为当前读 入的字符和结束符’\0’构成的字符串;其中变量TempData[40]和Dr[2]是 因为考虑到操作数有可能不止一位数,则Dr[2]起到字符衔接的作用, 只要读入的字符是操作数,就将该字符衔接到字符数组TempData[40] 中,则TempData[40]中除了结束符’\0’之外的所有字符就是算术表达式 中的一个完整的操作数,即TempData[40]中存放的操作数或者是一位 数,或者是多位数。 算术表达式的详细计算过程: 首先,将所需的变量初始化:初始化算符栈和操作数栈, OPTR_InitStack (OPTR),OPND_InitStack (OPND);将算术表达式的起 始字符’#’入算符栈;变量c保存当前表达式MyExpression的地址;利用 strcpy()函数将结束符’\0’衔接至数组TempData[40]中。 然后,利用while循环,开始计算。当OPTR栈的栈顶元素 OPTR_GetTop(OPTR)和当前读入的字符*c同时为’#’时,整个表达式求 值完毕;若不满足表达式结束的该条件,则进行计算。读入当前字符 *c: 若*c是操作数,则首先将*c给Dr[2],利用strcat()函数将Dr[2]衔接至 TempData[40]中,然后c++,判断下一个字符*c是否是算符,若不是,说 明当前操作数是多位数,然后再将该操作数字符衔接至TempData[40] 中,然后再c++,重复上述过程,将当前操作数的所有字符完整的保存 至TempData[40]中,利用强制转换函数atof()将TempData[40]中的字符转 换为double型的数据,同时赋给Data,则Data即为当前的完整的double
算符的判断函数 返回该算符在算符数组中的位置 的函数 两个算符的优先级的判断函数 表达式的正确性判断函数,同时 计算表达式
char Precede(char Aop, char Bop) double EvaluateExpression(char * MyExpression)
三、详细设计和编码 首先本程序定义两个顺序栈:算符栈(OPTR)和操作数栈 (OPND); OPTR栈定义如下: typedef struct{ char * base; //算符栈的栈底 char * top; //算符栈的栈顶 int stacksize; //算符栈的最大长度 }OPTR_STACK; OPND栈定义如下: typedef struct{ double * base; //操作数栈的栈底 double * top; //操作数栈的栈顶 int stacksize; //操作数栈的最大长度 }OPND_STACK; 然后是算符栈和操作数栈的相关功能函数的详细设计: (1)算符栈的相关功能函数的详细设计如下: 1、int OPTR_InitStack(OPTR_STACK &s) 为OPTR栈申请char类型的初始空间STACK_INITSIZE=100个 操作结果:构造一个空栈S,最大长度s.stacksize为100; 2、char OPTR_GetTop(OPTR_STACK &s) 初始条件:OPTR栈S已存在且非空(s.top!=s.base) 操作结果:用e= *(s.top-1)返回S的栈顶元素 3、int OPTR_Push(OPTR_STACK &s,char e) 初始条件:OPTR栈S已存在 因为考虑到原先申请的空间可能不够,即当OPTR栈的长度已经大于 s.stacksize=100,这是需要申请额外的存储空间;每次均用realloc函数申 请char类型的额外的STACKINCREMENT=10个存储单元,申请额外空 间后的OPTR栈的最大长度s.stacksize增加10; 操作结果:插入元素e为新的OPTR栈顶元素,即*s.top++=e; 4、int OPTR_Pop(OPTR_STACK &s,char &e) 初始条件:OPTR栈S已存在且非空; 操作结果:OPTR栈顶元素出栈,同时用e保存该栈顶元素,即e=*-s.top; (2)操作数栈的相关功能函数的详细设计如下:
概要设计如下: 运算符栈的相关功能函数 操作数栈的相关功能函数 算术表达式的相关功能函数 主函数
表2 运算符栈的功能函数
OPTR栈
int OPTR_InitStack(OPTR_STACK &s) char OPTR_GetTop(OPTR_STACK &s) int OPTR_Push(OPTR_STACK &s, char e) int OPTR_Pop(OPTR_STACK &s, char &e)
1、int OPND_InitStack(OPND_STACK &s) 为OPTR栈申请double类型的初始空间STACK_INITSIZE=100个 操作结果:构造一个空栈S,最大长度s.stacksize为100; 2、double OPND_GetTop(OPND_STACK &s) 初始条件:OPND栈S已存在且非空(s.top!=s.base) 操作结果:用e= *(s.top-1)返回S的栈顶元素 3、int OPND_Push(OPND_STACK &s,double e) 初始条件:OPND栈S已存在 因为考虑到原先申请的空间可能不够,即当OPND栈的长度已经大 于s.stacksize=100,这是需要申请额外的存储空间;每次均用realloc函数 申请double类型的额外的STACKINCREMENT=10个存储单元,申请额 外空间后的OPND栈的最大长度s.stacksize增加10; 操作结果:插入元素e为新的OPND栈顶元素,即*s.top++=e; 4、int OPND_Pop(OPND_STACK &s,double &e) 初始条件:OPND栈S已存在且非空; 操作结果:OPND栈顶元素出栈,同时用e保存该栈顶元素,即e=*-s.top; (3)下面实现本课程设计目标的算术表达式的相关功能函数的详细设 计过程: 首先应定义7种算符的字符数组char OPSET[OPSETSIZE]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'}; 然后是7算符的的优先级的定义: char Prior[7][7] = { '>' , '>' , '<' , '<' , '<' , '>' , '>', '>' , '>' , '<' , '<' , '<' , '>' , '>', '>' , '>' , '>' , '>' , '<' , '>' , '>', '>' , '>' , '>' , '>' , '<' , '>' , '>', '<' , '<' , '<' , '<' , '<' , '=' , ' ', '>' , '>' , '>' , '>' , ' ' , '>' , '>', '<' , '<' , '<' , '<' , '<' , ' ' , '=' }; 因为算术表达式涉及到两个数的四则运算,所以要设计一个两个数 四则运算的函数,即函数double Operate( double a, char theta, double b),定义了两个数的(加)+、(减)-、(乘)*、(除)/ 四种运算,并返回两个 数的运算结果。 然后,当依次读入算术表达式的各个字符时,要同时判断字符的合法
到实数。 一、问题分析和任务定义 要对一个含有加减乘除四则运算的合法的算术表达式进行求值, ①首先,应了解算术表达式的四则运算的规则: (1)从左向右计算 (2)先乘除,后加减 (3)先括号内,后括号外 由此可知,比如算术表达式(7+15)*(23-28/4)的计算顺序,即 为 (7+15)*(23-28/4)=22*(23-28/4)=22*(23-7) =22*16=352 ②其次,应明确“算符优先法”的内容: 算符优先法就是根据上述四则运算规则确定的优先关系来实现对表 达式的编译或解释执行的。 一个简单的四则运算表达式由操作数(operand)、运算符 (operator)和界限符(delimiter)组成,其中操作数是正整数,运算符 只含加、减、乘、除四种,界限符有左右括号和表达式起始、结束 符“#”;而且,为了统一算法的描述,将运算符和界限符通称为算 符。算符集OP={+,-,*,/,(,),#}。 根据上述3条运算规则,在具体的运算的每一步中,任意两个相继 出现的算符θ1和θ2之间的优先关系只能是如下3中关系之一: θ1<θ2 θ1的优先级低于θ2 θ1=θ2 θ1的优先级等于θ2 θ1>θ2 θ1的优先级高于θ2 下表定义了算符之间的这种优先关系。