算术表达式语法分析

/*****************************************************************程序功能:* 用递归下降子程序法判断算术表达式的语法是否正确*作者:* 张帅 东北大学2013级计算机学院*用时:* 8h*完成日期:* 2015.12.24 20:40:06*算术表达式文法:* E->T E1* E1->w0 T E1|ε* T->F T1* T1->w1 F T1|ε* F->I|(E)*其中:* w0:+ -* w1:* /*程序说明:* 输入算术表达式(以'#'结尾)如:x*(high+low)/(y-3)#* 输出"语法分析完成,符合算术表达式文法^_^"* 输入有错则输出相应错误提示。*****************************************************************/#include #include#include//函数声明void recursion();void E();void E1();void T();void T1();void F();int ISw0();int ISw1();int ISI();char *getword();char w[36];char ch;//主程序void recursion(){ ch=' '; printf("请输入表达式:\n"); strcpy(w,getword()); E(); if(strcmp(w,"#")==0) { printf("语法分析完成,符合算术表达式文法^_^\n"); } else { printf("错误! (←_←)\n"); exit(1); }}void E(){ T(); E1();}void E1(){ if(ISw0()) { strcpy(w,getword()); T(); E1(); } else return;}void T(){ F(); T1();}void T1(){ if(ISw1()) { strcpy(w,getword()); F(); T1(); } else return;}void F(){ if(ISI()) { strcpy(w,getword()); } else if(strcmp(w,"(")==0) { strcpy(w,getword()); E(); if(strcmp(w,")")==0) { strcpy(w,getword()); } else { printf("错误,少写了')' (←_←)\n"); exit(1); } } else { printf("错误! (←_←)\n"); exit(1); }}//判断是否为+或—int ISw0(){ if(strcmp(w,"+")==0||strcmp(w,"-")==0) return 1; else return 0;}//判断是否为*或/int ISw1(){ if(strcmp(w,"*")==0||strcmp(w,"/")==0) return 1; else return 0;}//判断是否为变量或常数int ISI(){ if(strcmp(w,"+")!=0&&strcmp(w,"-")!=0&&strcmp(w,"*")!=0&&strcmp(w,"/")!=0&&strcmp(w,"#")!=0&&strcmp(w,"(")!=0&&strcmp(w,")")!=0) return 1; else return 0;}//读取一个单词char *getword(){ int m; char bw[30]; m=0; while(ch==' ') { ch=getchar(); } switch(ch) { case '+':bw[m++]='+';bw[m]='\0';ch=getchar();break; case '-':bw[m++]='-';bw[m]='\0';ch=getchar();break; case '*':bw[m++]='*';bw[m]='\0';ch=getchar();break; case '/':bw[m++]='/';bw[m]='\0';ch=getchar();break; case '#':bw[m++]='#';bw[m]='\0';ch=getchar();break; case '(':bw[m++]='(';bw[m]='\0';ch=getchar();break; case ')':bw[m++]=')';bw[m]='\0';ch=getchar();break; default: while(ch!='+'&&ch!='-'&&ch!='*'&&ch!='/'&&ch!='#'&&ch!='('&&ch!=')'&&ch!=' ') { bw[m++]=ch; ch=getchar(); } bw[m]='\0'; break; } return bw;}int main(){ recursion(); return 0;}
毕业论文引言 随着计算机技术的发展与普及,计算机已经成为各行业最基本的工具之一,迅速进入千家万户。因此,掌握计算机应用的基本技能成为新世纪人才不可缺少的基本素质之一。为使计算机能正常工作, 除了构成计算机各个组成部分的物理设备外, 一般说来, 还必须要有指挥计算机“做什么”和“如何做”的“程序”。程序及其有关文档构成计算机软件, 其中用以书写计算机软件的语言称为计算机程序设计语言。 1 计算机程序设计语言简介 计算机程序设计语言是计算机可以识别的语言,用于描述解决问题的方法,供计算机阅读和执行,通常简称为编程语言,是一组用来定义计算机程序的语法规则。它是一种被标准化的交流技巧,用来向计算机发出指令。一种计算机语言让程序员能够准确地定义计算机所需要使用的数据,并精确地定义在不同情况下所应当采取的行动。使用程序设计语言往往使程序员能够比使用机器语言更准确地表达他们所想表达的目的。对那些从事计算机科学的人来说,懂得程序设计语言是十分重要的,因为所有的程序都需要程序设计语言才能完成,而计算机的工作是用程序来控制的,离开了程序,计算机将一事无成。 2 开发背景及意义 现有计算器不能计算表达式,这是一个缺陷,为此,开发了一个能直接计算表达式的计算器,这为计算提高了更大的方便,可以大幅度提高计算效率。 第章 第三章 第一节 递归下降法的描述 3.1.1实现思想 它的主要原理是,对每个非终极符按其产生式结构构造相应语法分析子程序,其中终极符产生匹配命令,而非终极符则产生过程调用命令。因为文法递归相应子程序递归,所以称这种方法为递归子程序下降法或递归下降法。其中子程序的结构与产生式结构几乎是一致的。文法中每个非终结符对应一个递归过程(子程序),每个过程的功能是识别由该非终结符推出的串,当某非终结符的产生式有多个候选式时能够按LL(1)形式可唯一地确定选择某个候选式进行推导。 3.1.2算法的特点 递归下降法是语法分析中最易懂的一种方法。递归下降法要满足的条件:假设A的全部产生式为Aα1|α2|……|αn ,则必须满足如下条件才能保证可以唯一的选择合适的产生式 predict(Aαi)∩predict(Aαj)=Φ,当i≠j. 3.1.3构造递归下降语法分析程序 采用了递归子程序方法进行语法分析,对文法中的每个非终极符号按其产生式结构产生相应的语法分析子程序,完成相应的识别任务。其中终结符产生匹配命令,非终结符则产生调用命令。每次进入子程序之前都预先读入一个单词。因为使用了递归下降方法,所以程序结构和层次清晰明了,易于手工实现,且时空效率较高。实际的语法分析工作,从调用总程序的分析子程序开始,根据产生式进行递归调用各个分析子程序。 第
一个简单的算术表达式语法分析器可以通过递归下降分析法实现。下面是一个例子: ``` class SyntaxParser: def __init__(self, expression): self.expression = expression self.index = 0 def parse(self): return self.parse_expression() def parse_expression(self): left_operand = self.parse_term() while self.index < len(self.expression): operator = self.expression[self.index] if operator not in ['+', '-']: break self.index += 1 right_operand = self.parse_term() if operator == '+': left_operand += right_operand else: left_operand -= right_operand return left_operand def parse_term(self): left_operand = self.parse_factor() while self.index < len(self.expression): operator = self.expression[self.index] if operator not in ['*', '/']: break self.index += 1 right_operand = self.parse_factor() if operator == '*': left_operand *= right_operand else: left_operand /= right_operand return left_operand def parse_factor(self): if self.expression[self.index] == '(': self.index += 1 value = self.parse_expression() self.index += 1 return value else: start = self.index while self.index < len(self.expression) and self.expression[self.index].isdigit(): self.index += 1 return int(self.expression[start:self.index]) ``` 在这个例子中,我们定义了一个 `SyntaxParser` 类来解析算术表达式。我们传入要解析的表达式作为构造函数参数,并且定义了三个方法来分别解析表达式、项和因子。 在 `parse_expression` 方法中,我们首先调用 `parse_term` 方法来解析左操作数,并进入一个循环,直到我们到达表达式的末尾或者遇到一个不是加号或减号的运算符。如果是加号,我们解析右操作数并将左右操作数相加,否则将左操作数减去右操作数。最后返回左操作数的值。 在 `parse_term` 方法中,我们首先调用 `parse_factor` 方法来解析左操作数,并进入一个循环,直到我们到达表达式的末尾或者遇到一个不是乘号或除号的运算符。如果是乘号,我们解析右操作数并将左右操作数相乘,否则将左操作数除以右操作数。最后返回左操作数的值。 在 `parse_factor` 方法中,我们首先检查当前字符是否为左括号,如果是,我们解析括号内的表达式并返回其值。否则,我们解析数字并返回其值。 例如,如果我们有一个表达式 `2 + 3 * (4 - 1)`,我们可以这样使用 `SyntaxParser` 类来解析它: ``` parser = SyntaxParser("2 + 3 * (4 - 1)") result = parser.parse() print(result) ``` 这将输出 `11`,也就是表达式的计算结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值