c语言实现算符优先语法分析
算符优先语法分析设计原理与实现技术实验报告
算符优先语法分析设计原理与实现技术实验报告变更说明一、实验目的:本实验的目的在于在教师的引导下以问题回朔与思维启发的方式,使学生在不断的探究过程中掌握编译程序设计和构造的基本原理和实现技术,启迪学生的抽象思维、激发学生的学习兴趣、培养学生的探究精神和专业素养,从而提高学生发现问题、分析问题和解决问题的能力。
二、实验内容:[实验项目]实现算符优先分析算法,完成以下描述算术表达式的算符优先文法的算符优先分析过程。
G[E]:E→E+T∣E-T∣TT→T*F∣T/F∣FF→(E)∣i[实验说明]终结符号i 为用户定义的简单变量,即标识符的定义。
[设计要求](1)输入串应是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。
输出为输入串是否为该文法定义的算术表达式的判断结果;(2)算符优先分析过程应能发现输入串出错;(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。
三、实验环境:操作系统:Windows 7软件:VC++6.0四、程序功能描述:●提供了文件输入方式,且输入的内容为二元式序列;●能够对输入的字符串做出正确的算符优先分析判断,并给出判断结果,判断结果输出到文件,并显示在屏幕;●能发现输入串中的错误,包含非法字符,输入不匹配等;●能够处理一些可预见性的错误,如文件不存在,输入非法等。
五、数据结构设计:六、程序结构描述:●设计方法:本程序采用从文件读取的输入方式,输入的内容需为二元式序列,然后按照算符优先分析的方法对输入的字符串进行分析判断,分析完成后输出判断结果到文件,并在屏幕显示。
程序通过对输入串的检查能够发现输入串中的错误。
程序规定的单词符号及其种别码见下表:算符优先矩阵+ - * / ( ) i #+ > > < < < > < >- > > < < < > < >* > > > > < > < >/ > > > > < > < >( < < < < < = < >) > > > > > >i > > > > > ># < < < < < < < =●算符优先分析法简介基本思路是根据既定的规则构建算符优先矩阵,然后根据算符之间的优先关系寻找输入串中的最左素短语,若找到,则寻找与最左素短语匹配的产生式进行规约;否则进行移进操作,及输入的算符进分析栈。
C语言运算符优先级
C语言运算符优先级运算符是C语言中非常重要的一个概念,它可以用来构建表达式和算式。
在C语言中,运算符可以分为算数运算符、关系运算符、位运算符、逻辑运算符和赋值运算符等等,在编写C语言程序时,运算符的使用十分普遍。
在C语言中,不同的运算符被赋予不同的优先级,这意味着当程序员利用运算符构建算式时,会优先按照运算符优先级进行求值。
C 语言中定义的运算符优先级及其意义如下:1. 一元运算符:当一元运算符出现时,它会优先于双目运算符进行求值。
例如,“+”会优先于“+”,而“!”会优先于“&&”。
2.目运算符:这是C语言中最常用的运算符,它可以对两个操作数进行求值,该类运算符优先级按从高到低分别为:(1)算术运算符:“*”,“/”,“%”;(2)关系运算符:“>”,“,“>=”,“<=”,“==”,“!=”;(3)逻辑运算符:“&&”,“||”,“^”;(4)赋值运算符:=”;(5)减号运算符:“-”;(6)加号运算符:“+”。
3. 三元运算符:其优先级介于一元运算符和双目运算符之间。
在C语言程序中,当出现多个运算符并列时,程序员需要按照运算符的优先级顺序来计算,而不是从左往右依次计算。
因此,了解C 语言运算符优先级非常重要,可以避免程序错误。
例如,假如A=3,B=4,C=5,则在C语言中,表达式A*B+C的值将是17,而不是25,因为乘号“*”优先于加号“+”。
如果程序员未按照优先级计算,则表达式的值将出错。
因此,理解C语言中运算符优先级的重要性,程序员在编写程序时应注意将算式中出现的运算符按其优先级顺序排列,以免出现错误或歧义。
此外,不止是C语言中,众多编程语言中也存在运算符优先级,程序员在开发程序时,要掌握各种编程语言运算符优先级,以便更准确地开发程序。
C语言运算符的优先级以及结合方向
C语⾔运算符的优先级以及结合⽅向1:运算符的结合⽅向在表达式中,优先级较⾼的先于优先级较低的进⾏运算。
⽽在⼀个运算量两侧的相同时,则按运算符的结合性所规定的结合⽅向处理。
C语⾔中各运算符的结合性分为两种,即左结合性(⾃左⾄右)和右结合性(⾃右⾄左)。
例如的结合性是⾃左⾄右,即先左后右。
如有表达式x-y+z则y应先与“-”号结合,执⾏x-y运算,然后再执⾏+z的运算。
这种⾃左⾄右的结合⽅向就称为“左结合性”。
⽽⾃右⾄左的结合⽅向称为“右结合性”。
最典型的右结合性运算符是。
如x=y=z,由于“=”的右结合性,应先执⾏y=z再执⾏x=(y=z)运算。
2:优先级说明:同⼀优先级的运算符,运算次序由结合⽅向所决定。
简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符(好像不对)关系运算符>逻辑运算符算术运算符>关系运算符优先级运算符名称或含义使⽤形式结合⽅向说明1[]数组下标数组名[常量表达式]左到右()圆括号(表达式)/函数名(形参表).成员选择(对象)对象.成员名->成员选择(指针)对象指针->成员名++后置⾃增运算符++变量名单⽬运算符--后置⾃减运算符--变量名单⽬运算符2-负号运算符-表达式右到左单⽬运算符(类型)强制类型转换(数据类型)表达式++前置⾃增运算符变量名++单⽬运算符--前置⾃减运算符变量名--单⽬运算符*取值运算符*指针变量单⽬运算符&取地址运算符&变量名单⽬运算符!逻辑⾮运算符!表达式单⽬运算符~按位取反运算符~表达式单⽬运算符sizeof长度运算符sizeof(表达式)3/除表达式/表达式左到右双⽬运算符*乘表达式*表达式双⽬运算符%余数(取模)整型表达式/整型表达式双⽬运算符4+加表达式+表达式左到右双⽬运算符-减表达式-表达式双⽬运算符5<<左移变量<<表达式左到右双⽬运算符>>右移变量>>表达式双⽬运算符6>⼤于表达式>表达式左到右双⽬运算符>=⼤于等于表达式>=表达式双⽬运算符<⼩于表达式<表达式双⽬运算符<=⼩于等于表达式<=表达式双⽬运算符7==等于表达式==表达式左到右双⽬运算符!=不等于表达式!= 表达式双⽬运算符8&按位与表达式&表达式左到右双⽬运算符9^按位异或表达式^表达式左到右双⽬运算符10|按位或表达式|表达式左到右双⽬运算符11&&逻辑与表达式&&表达式左到右双⽬运算符12||逻辑或表达式||表达式左到右双⽬运算符13?:条件运算符表达式1? 表达式2:表达式3右到左三⽬运算符=赋值运算符变量=表达式/=除后赋值变量/=表达式14/=除后赋值变量/=表达式右到左<<=左移后赋值变量<<=表达式>>=右移后赋值变量>>=表达式&=按位与后赋值变量&=表达式^=按位异或后赋值变量^=表达式|=按位或后赋值变量|=表达式15,逗号运算符表达式,表达式,…左到右从左向右顺序运算。
c语言 符号优先级
c语言符号优先级C语言是一种广泛应用于编程领域的高级编程语言,它具有简单易学、运行速度快、可移植性强等优点。
在C语言中,不同的运算符具有不同的优先级,这就需要我们了解符号优先级的相关知识。
一、什么是符号优先级在C语言中,不同的运算符具有不同的优先级,这就意味着当一个表达式中包含多个运算符时,需要按照一定的优先级顺序进行计算。
符号优先级是指在一个复杂表达式中,各种运算符按照一定规则计算的顺序。
二、符号优先级规则C语言中各种运算符按照一定规则进行计算。
下面我们来详细介绍各种运算符的优先级规则。
1.括号():括号内的表达式最先被计算。
2.单目正负号+、-:单目正负号+、-表示正负数,在表达式中具有最高优先级。
3.自增自减++、--:自增自减++、--表示对变量进行加1或减1操作,在表达式中具有较高优先级。
4.乘除%* /:乘除%* / 表示乘法和除法,在表达式中具有较高优先级。
5.加减符号+-:加减符号+- 表示加法和减法,在表达式中具有较低优先级。
6.移位<<、>>:移位<<、>> 表示左移和右移,在表达式中具有较低优先级。
7.关系符号<、<=、>、>=:关系符号<、<=、>、>=表示大小关系,在表达式中具有较低优先级。
8.等于!=、==:等于!=、== 表示相等和不相等,在表达式中具有较低优先级。
9.按位与&:按位与&表示二进制按位与运算,在表达式中具有较低优先级。
10.按位异或^:按位异或^表示二进制按位异或运算,在表达式中具有较低优先级。
11.按位或|:按位或|表示二进制按位或运算,在表达式中具有较低优先级。
12.逻辑与&&:逻辑与&& 表示逻辑与运算,两个操作数都为真时结果为真,否则为假,它的优先级比逻辑或||高一些。
13.逻辑或||:逻辑或|| 表示逻辑或运算,两个操作数都为假时结果为假,否则为真,它的优先级比逻辑与&&低一些。
c语言的符号的优先级
在C语言中,符号的优先级主要取决于它们的结合性和操作符的类型。
以下是一些常见操作符的优先级:
1. 结合性:
* 后缀运算符(如 `++` 和 `--`)具有最高的优先级,它们总是从右到左进行操作。
* 前缀运算符(如 `+` 和 `-`)具有较低的优先级,它们总是从左到右进行操作。
* 乘法、除法和取余运算符具有相同的优先级,它们在任何情况下都按照从左到右的顺序进行操作。
* 加法和减法运算符具有相同的优先级,但它们在乘法和除法运算符之后进行操作。
* 关系运算符(如 `<`, `<=`, `>`, `>=`)具有较低的优先级,但它们在加法和减法运算符之前进行操作。
* 逻辑运算符(如 `&&`, `||`, `!`)具有中等的优先级,但它们在所有其他运算符之前进行操作。
2. 类型和结合性决定优先级:
* 对于不同类型的运算符,具有较低类型的运算符将具有更
高的优先级。
例如,一个 `int` 操作符比一个 `float` 操作符具有更高的优先级。
* 在同一类型中,左结合性运算符(如括号、乘法、除法和取余)比右结合性运算符具有更高的优先级。
需要注意的是,C语言中的运算符优先级可以通过使用括号来改变。
括号可以明确指定运算的顺序,即使在具有不同优先级的运算符之间使用括号,也可以确保正确的运算顺序。
c语言运算法 优先级
c语言运算法优先级C语言是一种广泛使用的编程语言,它具有强大的计算能力和丰富的运算符号。
在C语言中,运算符号的优先级非常重要。
合理运用优先级可以使我们的代码更加简洁和高效,减少出错的可能性。
本文将详细介绍C语言的运算符号优先级,希望能给读者带来指导意义。
首先我们来了解一下C语言中的运算符号。
C语言中的运算符号可以分为以下几类:1.算术运算符号:+,-,*,/,%,++,--。
2.关系运算符号:==,!=,>,<,>=,<=。
3.逻辑运算符号:&&,||,!。
4.位运算符号:&,|,^,~,<<,>>。
5.赋值运算符号:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=。
6.其他运算符号:sizeof,&,*,?:,(),[],->,.,...。
接下来我们来详细了解一下这些运算符号的优先级。
1.算术运算符号的优先级算术运算符号分为一元运算符和二元运算符。
一元运算符包括++和--,而二元运算符则包括+,-,*,/和%。
一元运算符的优先级最高,其次是乘、除和取余,再次是加、减。
而对于同级别的符号,C语言遵循从左到右的计算顺序。
当一元运算符和二元运算符混在一起时,一元运算符优先级仍然最高。
2.关系运算符号的优先级关系运算符号的优先级较低,而在关系运算符号中,等于和不等于的优先级最低。
所以在编写代码时,应该避免使用==和!=作为条件表达式的最后符号,避免出现优先级问题导致的语法错误。
3.逻辑运算符号的优先级逻辑运算符号中,逻辑非(!)的优先级最高,其次是逻辑与(&&),最后是逻辑或(||)。
在逻辑符号中,&&和||具有短路功能,即如果前面的表达式已经可以判断结果,后面的表达式就不会再进行计算。
4.位运算符号的优先级位运算符号中,一元反码(~)的优先级最高,其次是左移(<<),右移(>>),位与(&),位异或(^)和位或(|)。
实验2 语法分析(算符优先分析)
实验2 语法分析(算符优先分析)一、实验任务:算术表达式的文法:E→ E+T | E-T | TT→ T*F | T/F | FF→(E)| i根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确。
二、实验时间:上机2次。
三、实验过程和指导:(一)准备:1.确定算术表达式的文法,设计出算符优先关系表;2.考虑好设计方案,设计出模块结构、测试数据;3.初步编制好程序。
(二)上机实验:上机调试,发现错误,分析错误,逐渐修改完善。
(三)程序要求:程序输入/输出示例:如参考C语言的运算符。
输入如下表达式(以分号为结束)和输出结果:(1)10输出:正确(2)1+2*(15-6)输出:正确(3)(1+2)/3+4- (11+6/7)输出:正确(4)((1-2)/3+4输出:错误,出错位置是(5)1+2-3+(*4/5)输出:错误,出错位置是注意:1.为降低难度,表达式中不含变量(只含无符号整数);2.可以直接调用此法分析程序,取得单词;3.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好,最好有详细的出错位置和出错性质说明);4.测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。
同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;5.对学有余力的同学,可增加功能:当判断一个表达式正确时,输出计算结果,计算过程用浮点表示,但要注意不要被0除。
(四)练习该实验的目的和思路:程序比较复杂,需要利用到大量的编译原理,也用到了大量编程技巧和数据结构,通过这个练习可极大提高编程能力。
程序规模大概为300行。
通过练习,掌握对表达式进行处理的一种方法。
(五)为了能设计好程序,注意以下事情:1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。
2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。
3.编程时注意编程风格:空行的使用、注释的使用、缩进的使用、变量合理命名等。
算符优先_实验报告
一、实验目的1. 理解算符优先分析法的原理和过程。
2. 掌握算符优先分析法的实现方法。
3. 通过实验加深对自底向上语法分析方法的理解。
二、实验内容1. 算符优先分析法原理介绍算符优先分析法是一种自底向上的语法分析方法,它通过比较相邻算符的优先次序来识别句型中的句柄,进而执行归约。
该方法的核心是确立文法的终结符之间的优先关系。
2. 实验步骤(1)判断文法是否为OG文法:OG文法要求所有产生式右部至少有一个终结符。
(2)判断文法是否为OPG文法:计算FIRSTVT集、LASTVT集,并构建算符优先矩阵。
(3)对句子进行分析:根据分析表判断句子是否为文法的句子。
(4)实现程序:从文件和键盘读取输入,将结果输出到指定文件和屏幕,并具有一致性。
3. 实验数据(1)文法:g[e]:e->e+t|t(2)测试句子:12+t, t+12, 12+13t, 12+t13三、实验过程1. 判断文法是否为OG文法根据给定的文法,我们可以看到所有产生式右部至少有一个终结符,因此该文法为OG文法。
2. 判断文法是否为OPG文法,并构建算符优先矩阵(1)计算FIRSTVT集FIRSTVT(e) = {t}FIRSTVT(t) = {t}(2)计算LASTVT集LASTVT(e) = {t}LASTVT(t) = {t}(3)构建算符优先矩阵| + - ( ) t e $+ > - - - > > -- > - - - > > -> > > > > > >( > > > > > > >) - - - - - - -t - - - - - - -e - - - - - - -$ - - - - - - -3. 对句子进行分析(1)分析句子“12+t”根据分析表,我们可以得到以下分析过程:12+t -> 12+t -> 12+t -> t -> t(2)分析句子“t+12”根据分析表,我们可以得到以下分析过程:t+12 -> t+12 -> t+12 -> t+12 -> t+12 -> t -> t (3)分析句子“12+13t”根据分析表,我们可以得到以下分析过程:12+13t -> 12+13t -> 12+13t -> 12+13t -> 12+13t -> t -> t(4)分析句子“12+t13”根据分析表,我们可以得到以下分析过程:12+t13 -> 12+t13 -> 12+t13 -> 12+t13 -> 12+t13 -> t13 -> t13 -> t13 -> t -> t四、实验结果1. 测试句子“12+t”分析结果:正确2. 测试句子“t+12”分析结果:正确3. 测试句子“12+13t”分析结果:正确4. 测试句子“12+t13”分析结果:正确五、实验总结通过本次实验,我们深入了解了算符优先分析法的原理和实现方法。
算符优先实验报告
算符优先分析实验报告一、程序功能实现算符优先分析算法,完成以下描述算术表达式的算符优先文法的算符优先分析过程。
G[S]:S->#E#E->E+T|TT->T*F|FF->P^F | PP->(E)|i二、主要数据结构char VT[]定义符号表;struct type{char origin; char array[5]; int length;}定义产生式类型;table[][]定义优先关系矩阵。
三、程序结构int locate(char s[],char c) 辅助函数,在一个字符串中查找某特定字符;int Find(type G[],char s[],int m,int n) 查找与已搜索出的短语对应的产生式,返回该产生式的序号;void doScan()对输入串进行分析的主控函数;void print(char s[],int k,int tag,char str[],int i,char action[])输出分析过程的函数。
在find()和doScan()中调用locate()函数,在doScan()中调用find()和print()函数,在main()中调用doScan()函数。
流程图:Y成功四、程序测试测试句子:i+i*i结果:测试句子:(i+i)*i结果:五、实验总结本实验重点解决算符优先矩阵的构造和算符优先算法的实现,我认为难点是构造优先矩阵,这个就需要掌握方法多练习,优先算法只需将PPT上的流程图一步一步地转化为代码就可以了。
总体来说,本实验比较简单。
THANKS !!!致力为企业和个人提供合同协议,策划案计划书,学习课件等等打造全网一站式需求欢迎您的下载,资料仅供参考。
算符优先分析算法(c语言)
编译原理实验一实验目的设计、编制并调试一个算符优先分析算法,加深对此分析法的理解二实验过程先在算符栈置“$”,然后开始顺序扫描表达式,若读来的单词符号是操作数,这直接进操作数栈,然后继续读下一个单词符号。
分析过程从头开始,并重复进行;若读来的是运算符θ2则将当前处于运算符栈顶的运算符θ1的入栈优先数f与θ2的比较优先函数g进行比较。
2.2 各种单词符号对应的种别码2.3 算符优先程序的功能完成一个交互式面向对象的算符优先分析程序,而一个交互式面向对象的算符优先分析程序基本功能是:(1)输入文法规则(2)对文法进行转换(3)生成每个非终结符的FirstVT和LastVT(4)生成算符优先分析表(5)再输入文法符号(6)生成移进规约步骤三设计源码算符优先分析器#include "stdio.h"#include "stdlib.h"#include "iostream.h"char data[20][20]; //算符优先关系char s[100]; //模拟符号栈schar lable[20]; //文法终极符集char input[100]; //文法输入符号串char string[20][10]; //用于输入串的分析int k;char a;int j;char q;int r; //文法规则个数int r1;int m,n,N; //转化后文法规则个数char st[10][30]; //用来存储文法规则char first[10][10]; //文法非终结符FIRSTVT集char last[10][10]; //文法非终结符LASTVT集int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出int deal(); //对输入串的分析int zhongjie(char c); //判断字符c是否是终极符int xiabiao(char c); //求字符c在算符优先关系表中的下标void out(int j,int k,char *s); //打印s栈void firstvt(char c); //求非终结符c的FIRSTVT集void lastvt(char c); //求非终结符c的LASTVT集void table(); //创建文法优先关系表void main(){int i,j,k=0;printf("请输入文法规则数:");scanf("%d",&r);printf("请输入文法规则:\n");for(i=0;i<r;i++){scanf("%s",st[i]); //存储文法规则,初始化FIRSTVT集和LASTVT集*/first[i][0]=0; /*first[i][0]和last[i][0]分别表示st[i][0]非终极符的FIRSTVT集和LASTVT集中元素的个数*/ last[i][0]=0;}for(i=0;i<r;i++) //判断文法是否合法{for(j=0;st[i][j]!='\0';j++){if(st[i][0]<'A'||st[i][0]>'Z'){printf("不是算符文法!\n");exit(-1);}if(st[i][j]>='A'&&st[i][j]<='Z'){if(st[i][j+1]>='A'&&st[i][j+1]<='Z'){printf("不是算符文法!\n");exit(-1);}}}}for(i=0;i<r;i++){for(j=0;st[i][j]!='\0';j++){if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]!='-'&&st[i][j]!='>'&&st[i][j]!='| ')lable[k++]=st[i][j];}}lable[k]='#';lable[k+1]='\0';table();printf("每个非终结符的FIRSTVT集为:\n"); //输出每个非终结符的FIRSTVT集for(i=0;i<r;i++){printf("%c: ",st[i][0]);for(j=0;j<first[i][0];j++){printf("%c ",first[i][j+1]);}printf("\n");}printf("每个非终结符的LASTVT集为:\n"); //输出每个非终结符的LASTVT集for(i=0;i<r;i++){printf("%c: ",st[i][0]);for(j=0;j<last[i][0];j++){printf("%c ",last[i][j+1]);}printf("\n");}printf("算符优先分析表如下:\n");for(i=0;lable[i]!='\0';i++)printf("\t%c",lable[i]);printf("\n");for(i=0;i<k+1;i++){printf("%c\t",lable[i]);for(j=0;j<k+1;j++){printf("%c\t",data[i][j]);}printf("\n");}printf("请输入文法输入符号串以#结束:");scanf("%s",input);deal();}void table(){char text[20][10];int i,j,k,t,l,x=0,y=0;int m,n;x=0;for(i=0;i<r;i++){firstvt(st[i][0]);lastvt(st[i][0]);}for(i=0;i<r;i++){text[x][y]=st[i][0];y++;for(j=1;st[i][j]!='\0';j++){if(st[i][j]=='|'){text[x][y]='\0';x++;y=0;text[x][y]=st[i][0];y++;text[x][y++]='-';text[x][y++]='>';}else{text[x][y]=st[i][j];y++;}}text[x][y]='\0';x++;y=0;}r1=x;printf("转化后的文法为:\n");for(i=0;i<x;i++) //输出转化后的文法规则串{printf("%s\n",text[i]);}for(i=0;i<x;i++) /*求每个终结符的推导结果(去掉"->"后的转化文法,用于最后的规约)*/ {string[i][0]=text[i][0];for(j=3,l=1;text[i][j]!='\0';j++,l++)string[i][l]=text[i][j];string[i][l]='\0';}for(i=0;i<x;i++){for(j=1;text[i][j+1]!='\0';j++){if(zhongjie(text[i][j])&&zhongjie(text[i][j+1])){m=xiabiao(text[i][j]);n=xiabiao(text[i][j+1]);data[m][n]='=';}if(text[i][j+2]!='\0'&&zhongjie(text[i][j])&&zhongjie(text[i][j+2])&&!zhongjie(text[i][j+1])){m=xiabiao(text[i][j]);n=xiabiao(text[i][j+2]);data[m][n]='=';}if(zhongjie(text[i][j])&&!zhongjie(text[i][j+1])){for(k=0;k<r;k++){if(st[k][0]==text[i][j+1])break;}m=xiabiao(text[i][j]);for(t=0;t<first[k][0];t++){n=xiabiao(first[k][t+1]);data[m][n]='<';}}if(!zhongjie(text[i][j])&&zhongjie(text[i][j+1])){for(k=0;k<r;k++){if(st[k][0]==text[i][j])break;}n=xiabiao(text[i][j+1]);for(t=0;t<last[k][0];t++){m=xiabiao(last[k][t+1]);data[m][n]='>';}}}}m=xiabiao('#');for(t=0;t<first[0][0];t++){n=xiabiao(first[0][t+1]);data[m][n]='<';}n=xiabiao('#');for(t=0;t<last[0][0];t++){m=xiabiao(last[0][t+1]);data[m][n]='>';}data[n][n]='=';}void firstvt(char c) //求FIRSTVT集{int i,j,k,m,n;for(i=0;i<r;i++){if(st[i][0]==c)break;}if(fflag[i]==0){n=first[i][0]+1;m=0;do{if(m==2||st[i][m]=='|'){if(zhongjie(st[i][m+1])){first[i][n]=st[i][m+1];n++;}else{if(zhongjie(st[i][m+2])){first[i][n]=st[i][m+2];n++;}if(st[i][m+1]!=c){firstvt(st[i][m+1]);for(j=0;j<r;j++){if(st[j][0]==st[i][m+1])break;}for(k=0;k<first[j][0];k++)int t;for(t=0;t<n;t++){if(first[i][t]==first[j][k+1])break;}if(t==n){first[i][n]=first[j][k+1];n++;}}}}}m++;}while(st[i][m]!='\0');first[i][n]='\0';first[i][0]=--n;fflag[i]=1;}}void lastvt(char c) //求LASTVT集{int i,j,k,m,n;for(i=0;i<r;i++){if(st[i][0]==c)break;}if(lflag[i]==0){n=last[i][0]+1;m=0;do{if(st[i][m+1]=='\0'||st[i][m+1]=='|'){if(zhongjie(st[i][m])){last[i][n]=st[i][m];}else{if(zhongjie(st[i][m-1])){last[i][n]=st[i][m-1];n++;}if(st[i][m]!=c){lastvt(st[i][m]);for(j=0;j<r;j++){if(st[j][0]==st[i][m])break;}for(k=0;k<last[j][0];k++){int t;for(t=0;t<n;t++){if(last[i][t]==last[j][k+1])break;}if(t==n){last[i][n]=last[j][k+1];n++;}}}}}m++;}while(st[i][m]!='\0');last[i][n]='\0';last[i][0]=--n;lflag[i]=1;}}int deal(){int i,j;int x,y;int z; //输入串的长度k=1;s[k]='#'; //栈置初值for(i=0;input[i]!='\0';i++); //计算输入串的长度z=i--;i=0;while((a=input[i])!='\0'){if(zhongjie(s[k]))j=k;elsej=k-1;x=xiabiao(s[j]);y=xiabiao(a);if(data[x][y]=='>'){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("规约\n");do{q=s[j];if(zhongjie(s[j-1]))j=j-1;else j=j-2;x=xiabiao(s[j]);y=xiabiao(q);}while(data[x][y]!='<');int m,n,N;for(m=j+1;m<=k;m++){for(N=0;N<r1;N++)for(n=1;string[N][n]!='\0';n++){if(!zhongjie(s[m])&&!zhongjie(string[N][n])){if(zhongjie(s[m+1])&&zhongjie(string[N][n+1])&&s[m+1]==string[N][n+1]){s[j+1]=string[N][0];break;}}elseif(zhongjie(s[m]))if(s[m]==string[N][n]){s[j+1]=string[N][0];break;}}}k=j+1;if(k==2&&a=='#'){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("结束\n");printf("输入串符合文法的定义!\n");return 1; //输入串符合文法的定义}}elseif(data[x][y]=='<'||data[x][y]=='='){ //移进out(1,k,s);printf("%c",a);out(i+1,z,input);printf("移进\n");k++;s[k]=a;i++;}else{printf("\nflase");return 0;}}printf("\nflase");return 0;}void out(int j,int k,char *s){int n=0;int i;for(i=j;i<=k;i++){printf("%c",s[i]);n++;}for(;n<15;n++){printf(" ");}}int xiabiao(char c) //求字符c在算符优先关系表中的下标{int i;for(i=0;lable[i]!='\0';i++){if(c==lable[i])return i;}return -1;}int zhongjie(char c) //判断字符c是否是终极符{int i;for(i=0;lable[i]!='\0';i++){if(c==lable[i])return 1;}return 0;}四实验结果。
C语言运算符优先级详解
落-逻辑,2 个: && 逻辑与 || 逻辑或
跳-条件,1 个,三目: ? :
(结合方向:自右向左)
福-赋值,11 个: = += -= *= /= %= >>= <<= &= ^= |=
(结合方向:自右向左)
豆-逗号,1 个: ,
结合方向自右向左的只有三类:赋值、单目和三目,其它的都是从左至右结合。
落-逻辑,2 个: && 逻辑与 || 逻辑或
跳-条件,1 个,三
目: ? :
(结合
方向:自右向左)
福-赋值,11 个: = += -= *= /= %= >>= <<= &= ^=
|=
(结合方向:自右向左)
豆-逗号,1 个: ,
结合方向自右向左的只有三类:赋值、单目和三目,其它的都是从左至右结合。
坛-单目,9 个: ! ~ ++ -- -负号 (类型) *指针 &取地址 sizeof 长度 (结合方向:自右向
左)
酸-算术,5 个: * / % + -减
味-位移,2 个: << >>
灌-关系,6 个: < <= > >= == 等于 != 不等于
味-位逻,3 个: & 按位与 ^ 按位异或 | 按位或
我是这样记得: 一个自称黑的初学者连编程都不会还算什么黑客,把自己关起来反思吧,逻 辑都没有条理,因为你不认真学!还找理由说因为天赋不够,真逗``
[ 2008-1-30 19:22:00 | Author: 盛方单片机 ]
C 语言运算符优先级顺口溜[转]
c语言单目运算符和双目运算符优先级
C语言中的单目运算符和双目运算符优先级是编程过程中非常重要的概念。
在本文中,我们将深入探讨这一主题并进行全面评估,以帮助读者更好地理解这些运算符的优先级和使用方法。
1. 单目运算符的优先级在C语言中,单目运算符是指只作用于一个操作数的运算符,例如取位置区域运算符&和解引用运算符*。
单目运算符的优先级是非常高的,它们通常会在其他运算符之前被执行。
这意味着,在表达式中,单目运算符的操作会先被执行,然后再执行其他运算符的操作。
在表达式`*ptr++`中,解引用运算符*会先于自增运算符++被执行。
2. 双目运算符的优先级双目运算符是指作用于两个操作数的运算符,例如加法运算符+和赋值运算符=。
在C语言中,双目运算符的优先级是根据运算符的性质来确定的,通常乘除法的优先级高于加减法,而赋值运算符的优先级低于算术运算符。
在表达式`a + b * c`中,乘法运算符*的优先级高于加法运算符+,因此会先被执行。
3. 个人观点和理解对于C语言中的单目和双目运算符的优先级,我个人认为理解运算符的优先级是非常重要的。
它能够帮助程序员编写更加清晰、精确和高效的代码,避免因为运算符优先级不当而导致的逻辑错误。
深入理解运算符的优先级也有助于提高程序员对C语言语法的掌握和应用能力,从而写出高质量的程序。
总结回顾在本文中,我们深入探讨了C语言中单目运算符和双目运算符的优先级。
通过对这些运算符的优先级进行全面评估,我们希望读者能够更好地理解这一重要概念,并在编程过程中加以应用。
笔者也共享了个人对于这一主题的观点和理解,希望能够为读者提供更多思考和交流的机会。
在我看来,理解C语言中的运算符优先级是提高编程能力的重要一环。
在实际编写代码的过程中,我们应充分利用好它们,以写出更加高效、清晰的代码。
对此主题的深入理解是至关重要的。
通过以上文章的撰写,我希望读者能更好地理解C语言的单目运算符和双目运算符的优先级,以及它们在编程过程中的重要性。
c语言运算符优先级
c语言运算符优先级c语言运算符优先级(一)Turbo C的运算符非常丰富, 主要分为三大类: 算术运算符, 关系运算符与逻辑运算符, 按位运算符。
除此之外, 还有一些用于完成特殊任务的运算符。
下面分别进行介绍。
5.1 算术运算符Turbo C的算术运算符如下:━━━━━━━━━━━━━━━━━━━━━━━━━━━━操作符作用────────────────────────────+ 加, 一目取正- 减, 一目取负* 乘/ 除% 取模-- 减1++ 加1━━━━━━━━━━━━━━━━━━━━━━━━━━━━一、一目和二目操作一目操作是指对一个操作数进行操作。
例如: -a是对a进行一目负操作。
二目操作(或多目操作)是指两个操作数(或多个操作数)进行操作。
在Turbo C中加、减、乘、除、取模的运算与其它高级语言相同。
需要注意的是除法和取模运算。
例如:15/2 是15除以2商的整数部分715%2 是15除以2的余数部分1对于取模运算符"%", 不能用于浮点数。
另外, 由于Turbo C中字符型数会自动地转换成整型数, 因此字符型数也可以参加二目运算。
例如:main(){char m, n; /*定义字符型变量*/m='c'; /*给m赋小写字母'c'*/n=m+'A'-'a'; /*将c中的小写字母变成大写字母'B'后赋给n*/...}上例中m='c'即m=98, 由于字母A和a的ASCII码值分别为65和97。
这样可以将小写字母变成大写字母, 反之, 如果要将大写字母变成小写字母, 则用c+ 'a'-'A'进行计算。
二、增量运算在Turbo C中有两个很有用的运算符, 在其它高级语言中通常没有。
这两个运算符就是增1和减1运算符"++"和"--", 运算符"++"是操作数加1, 而"--" 则是操作数减1。
C语言中的运算优先级
C语言中的运算优先级C语言是一门广泛应用于计算机编程领域的高级编程语言,掌握其运算优先级是编写高效代码的关键之一。
在本文中,我们将深入探讨C语言中的运算优先级,帮助读者理解和正确使用不同运算符的优先级规则。
一、基本运算符和优先级在C语言中,常用的基本运算符包括算术运算符、关系运算符、逻辑运算符等。
这些运算符在表达式计算时有着不同的优先级,下面将给出它们的优先级规则:1. 括号运算符:括号具有最高的优先级,用于改变表达式的计算顺序。
2. 一元运算符:一元运算符的优先级稍低于括号运算符,包括取负运算符、递增递减运算符等。
3. 乘法和除法运算符:乘法和除法运算符的优先级高于加法和减法运算符。
4. 加法和减法运算符:加法和减法运算符的优先级较低,是所有运算符中优先级最低的。
根据以上规则,我们可以写出如下表达式的计算结果:示例1:int result = 2 + 3 * 4 - 5 / 2; // 乘法和除法运算优先于加法和减法运算// result = 2 + (3 * 4) - (5 / 2) = 2 + 12 - 2 = 12示例2:int result = 5 * 2 / 4 + 3 - 1; // 乘法和除法运算优先于加法和减法运算// result = (5 * 2) / 4 + 3 - 1 = 10 / 4 + 3 - 1 = 2 + 3 - 1 = 4二、复合运算符的优先级除了基本运算符,C语言还提供了一些复合运算符,如赋值运算符、逻辑运算符等。
这些复合运算符的优先级与基本运算符相比略有不同,下面是一些常见复合运算符的优先级规则:1. 赋值运算符:赋值运算符的优先级较低,大部分运算符优先于赋值运算符。
2. 逻辑运算符:逻辑运算符中的逻辑与 `&&` 优先级高于逻辑或 `||`。
3. 条件运算符:条件运算符 `? :` 的优先级低于大部分运算符,但高于赋值运算符。
示例3:int a = 5;int b = 2;int c = 3;int result = a > b && b > c ? a : b + c; // 逻辑与 `&&` 优先级高于条件运算符 `? :`// result = (a > b) && (b > c) ? a : (b + c) = (5 > 2) && (2 > 3) ? 5 : (2 + 3) = 1 ? 5 : 5 = 5三、位运算符和优先级在C语言中,还存在一些用于位操作的运算符,如位与 `&`、位或`|`、位异或 `^` 等。
c语言中赋值运算符的和算术运算符的优先级
c语言中赋值运算符的和算术运算符的优先级一、C语言中的运算符优先级在C语言中,运算符优先级是指在进行算术运算和逻辑运算时,各种运算符执行的顺序。
运算符优先级的高低,直接决定了表达式中运算的顺序,进而影响最终结果的正确性。
理解并正确使用运算符优先级,是C语言编程中一项基本且重要的技能。
C语言中的运算符可以分为赋值运算符、算术运算符、比较运算符、逻辑运算符等几大类。
其中,算术运算符是最常用的一类,用于执行数学运算,如加、减、乘、除等。
赋值运算符则用于将一个值赋给一个变量。
在复杂的表达式中,这些运算符可能同时出现,这时就需要依据一定的优先级规则来确定它们的执行顺序。
二、赋值运算符的优先级赋值运算符在C语言中主要用于将一个值赋给一个变量。
常见的赋值运算符包括“=”、“+=”、“-=”、“*=”、“/=”和“%=”等。
在优先级上,赋值运算符的优先级是较低的。
这意味着,在一个包含赋值运算符的复杂表达式中,赋值操作通常会等到其他部分的计算完成后再进行。
三、算术运算符的优先级算术运算符用于执行基本的数学运算,如加法、减法、乘法和除法等。
在C语言中,算术运算符的优先级通常比赋值运算符要高。
这意味着,当一个表达式同时包含赋值和算术运算符时,算术运算将在赋值之前完成。
例如:int a = 5;int b = 10;int c = a + b = 20;在这个例子中,赋值运算符“=”的优先级低于算术运算符“+”。
因此,首先会执行加法运算“a + b”,得到结果25,然后再将这个结果赋给变量c。
最终,变量c的值将是25,而不是20。
四、使用括号改变运算顺序在C语言中,括号可以用来改变默认的运算顺序。
通过在括号内包含需要优先计算的表达式或语句,可以确保其按照预期的顺序进行计算。
括号内的内容将按照从左到右的顺序计算,不受其他运算符优先级的影响。
这提供了一种有效的方式来管理复杂表达式中的运算顺序。
例如:int a = 5;int b = 10;int c = (a + b)2; // 先计算括号内的加法,然后再乘法 int d = a + b2; // 先乘法再加法在第一个例子中,由于括号的使用,加法运算“a + b”会首先执行,得到结果15,然后乘以2得到最终结果30。
c逻辑运算符的优先顺序
c逻辑运算符的优先顺序C逻辑运算符的优先顺序是指在C语言中,逻辑运算符在表达式中的优先级。
在计算机编程中,逻辑运算符用于对表达式中的条件进行判断,根据判断结果返回一个布尔值。
C语言中的逻辑运算符包括与运算符(&&)、或运算符(||)和非运算符(!)。
下面将分别介绍这三种逻辑运算符的优先顺序。
1. 非运算符(!)非运算符(!)用于对表达式进行取反操作。
它的优先级最高,因此在一个表达式中,非运算符会首先被执行。
例如,对于表达式!a,会先计算出a的值,然后对其进行取反操作。
2. 与运算符(&&)与运算符(&&)用于判断多个条件是否同时满足。
它的优先级次于非运算符。
当使用多个与运算符连接在一起的条件时,会从左到右依次进行判断,直到遇到第一个条件为假,此时整个表达式的值就会为假。
如果所有条件都为真,整个表达式的值就会为真。
3. 或运算符(||)或运算符(||)用于判断多个条件是否至少有一个满足。
它的优先级最低,也就是说,当使用多个或运算符连接在一起的条件时,会从左到右依次进行判断,直到遇到第一个条件为真,此时整个表达式的值就会为真。
如果所有条件都为假,整个表达式的值就会为假。
C语言中的逻辑运算符可以用于控制程序的流程,例如在条件语句(if语句、while循环等)中判断条件是否成立,从而执行相应的代码块。
逻辑运算符的优先顺序决定了它们在表达式中的执行顺序,因此在编写代码时要注意逻辑运算符的优先级,以确保表达式的计算结果符合预期。
除了逻辑运算符的优先顺序,还有一些其他的运算符优先级也需要注意。
例如,算术运算符(+、-、*、/等)的优先级高于逻辑运算符,因此如果一个表达式中既包含算术运算符又包含逻辑运算符,那么算术运算符会先于逻辑运算符进行计算。
在实际的编程过程中,合理利用逻辑运算符的优先顺序可以简化代码,并提高代码的可读性和效率。
通过合理地组织逻辑运算符的顺序,可以减少不必要的计算,从而提高程序的执行效率。
编译原理实验4 算符优先语法分析- 解析
步骤3:构造算符优先分析表
优先关系:
设G是一个不含 产生式的算符文法,令 a、b是任意两个VT , P、Q、R ∈ VN ,则:
(1) ab 当且仅当文法G中含有形如P …ab…或P …aQb…的产生式 (2) a<b 当且仅当G中含有形如P …aR…的产生式,R而Rb… 或R Qb… (3) a>b 当且仅当G中含有形如P …Rb…的产生式,R而R…a 或R …aQ
<
i
i )#
#N*(N+ i >
)
)#
#N*(N+N >
)
)#
*i ⋖⋖ ⋗⋖ ⋗ ⋖⋖ ⋗ ⋖⋖
动作
移进
归约
移进
移进
移进
归约
移进
移进
归约
归约
()
#
⋖⋗ ⋗
⋖⋗ ⋗
⋗⋗
⋖
⋗⋗
⋖
最左素短语
i
i
i N+N
分析过程
示例:描述句子i*( i+i )的 分析过程。
栈
关系 当前符
+ +⋗ *⋗ i⋗ (⋖ )⋗ #⋖
如何识别最左素短语?
• 素短语
– 是指这样一种短语,它至少包含一个终结符,并且除 自身之外,不再包含其它更小的素短语。
• 最左素短语
– 句型最左边的那个素短语。
如何识别最左素短语?
定理:
一个OPG文法G的任何句型: #N1a1N2a2…NnanNn+1# (其中Ni可空) 的最左素短语Nj aj … Ni ai Ni+1 是满足如下三个条件的最 左子串: (1)aj-1 ⋖ aj (2)aj =·aj+1 =·… =·ai-1 =·ai (3)ai ⋗ ai+1
c语言 符号 优先级
c语言符号优先级C语言中的符号优先级指的是在表达式中出现多个运算符时,哪个运算符会先被执行。
这是因为C语言的表达式计算是按照一定的规则进行的,如果不明确指定运算符的优先级,就会按照默认的优先级顺序进行计算。
在C语言中,符号的优先级可以总结如下:1. 括号:括号具有最高的优先级,可以用括号来改变默认的计算顺序。
例如,在表达式`(3 + 4) * 5`中,括号会先被计算,结果为7,然后再乘以5,最终结果为35。
2. 后置递增/递减运算符:例如,`i++`或`i--`。
这些运算符会在其他运算符计算完毕后再执行。
例如,在表达式`i = 1; j =i++;`中,先将1赋值给i,然后再执行j的赋值操作,此时i的值递增变为2。
3. 前置递增/递减运算符:例如,`++i`或`--i`。
这些运算符的优先级高于大多数其他运算符,包括算术、关系和逻辑运算符。
例如,在表达式`i = 1; j = ++i;`中,先将i的值递增变为2,然后再执行j的赋值操作。
4. 一元运算符:例如,`+`和`-`。
这些运算符是用来表示正数和负数的。
例如,在表达式`num = -5;`中,表示将-5赋值给num。
5. 算术运算符:包括加法`+`、减法`-`、乘法`*`、除法`/`和取余`%`等。
这些运算符按照从左到右的顺序进行计算,并且优先级相同。
例如,在表达式`result = 5 + 3 * 2;`中,先计算3乘以2,得到6,然后再加上5,最终结果为11。
6. 移位运算符:包括左移`<<`和右移`>>`。
这些运算符用于将一个数的二进制位向左或向右移动指定的位数。
例如,在表达式`result = 5 << 2;`中,将5的二进制表示向左移动2位,最终结果为20。
7. 关系运算符:包括小于`<`、大于`>`、小于等于`<=`、大于等于`>=`、等于`==`和不等于`!=`。
这些运算符用于比较两个数的大小关系,并返回一个布尔值。
编译原理算符优先算法语法分析实验报告
编译原理算符优先算法语法分析实验报告实验报告:算符优先算法的语法分析一、实验目的本次实验旨在通过算符优先算法对给定的文法进行语法分析,实现对给定输入串的分析过程。
通过本次实验,我们能够了解算符优先算法的原理和实现方式,提升对编译原理的理解和应用能力。
二、实验内容1.完成对给定文法的定义和构造2.构造算符优先表3.实现算符优先分析程序三、实验原理算符优先算法是一种自底向上的语法分析方法,通过构造算符优先表来辅助分析过程。
算符优先表主要由终结符、非终结符和算符优先关系组成,其中算符优先关系用1表示优先关系,用2表示不优先关系,用0表示无关系。
算符优先分析程序的基本思路是:根据算符优先关系,依次将输入串的符号压栈,同时根据优先关系对栈内符号进行规约操作,最终判断输入串是否属于给定文法。
四、实验步骤1.定义和构造文法在本次实验中,我们假设给定文法如下:1)E->E+T,T2)T->T*F,F3)F->(E),i2.构造算符优先表根据给定文法,构造算符优先表如下:+*()i#+212112*222112(111012222122i222222#1112203.实现算符优先分析程序我们可以用C语言编写算符优先分析程序,以下是程序的基本框架:```c#include <stdio.h>//判断是否为终结符int isTerminal(char c)//判断条件//匹配符号int match(char stack, char input)//根据算符优先关系表进行匹配//算符优先分析程序void operatorPrecedence(char inputString[]) //定义栈char stack[MAX_SIZE];//初始化栈//将#和起始符号入栈//读入输入串//初始化索引指针//循环分析输入串while (index <= inputLength)//判断栈顶和输入符号的优先关系if (match(stack[top], inputString[index])) //栈顶符号规约} else//符号入栈}//计算新的栈顶}//判断是否成功分析if (stack[top] == '#' && inputString[index] == '#')printf("输入串符合给定文法!\n");} elseprintf("输入串不符合给定文法!\n");}```五、实验结果经过实验,我们成功实现了算符优先算法的语法分析。
c语言 运算符 优先级别
c语言运算符优先级别C语言是一种广泛使用的编程语言,它具有丰富的运算符,这些运算符可以用于执行各种数学和逻辑运算。
在C语言中,运算符的优先级别非常重要,因为它们决定了表达式中运算的顺序。
在本文中,我们将讨论C语言中运算符的优先级别。
1. 一元运算符一元运算符是只有一个操作数的运算符。
在C语言中,一元运算符的优先级别最高。
一元运算符包括取地址运算符(&)、取值运算符(*)、正号运算符(+)、负号运算符(-)和逻辑非运算符(!)等。
例如,以下代码中的一元运算符优先级别最高:int a = 10;int b = -a;在这个例子中,变量a的值为10,变量b的值为-10。
这是因为负号运算符是一元运算符,它的优先级别最高,所以它先被执行。
2. 乘法和除法运算符乘法和除法运算符的优先级别比一元运算符低,但比加法和减法运算符高。
乘法和除法运算符包括乘号(*)和除号(/)。
例如,以下代码中的乘法和除法运算符优先级别比一元运算符高,但比加法和减法运算符低:int a = 10;int b = 5;int c = a * b / 2;在这个例子中,变量a的值为10,变量b的值为5,变量c的值为25。
这是因为乘法和除法运算符的优先级别比加法和减法运算符低,所以它们先被执行。
3. 加法和减法运算符加法和减法运算符的优先级别比乘法和除法运算符低,但比赋值运算符高。
加法和减法运算符包括加号(+)和减号(-)。
例如,以下代码中的加法和减法运算符优先级别比乘法和除法运算符低,但比赋值运算符高:int a = 10;int b = 5;int c = a + b - 2;在这个例子中,变量a的值为10,变量b的值为5,变量c的值为13。
这是因为加法和减法运算符的优先级别比乘法和除法运算符低,但比赋值运算符高,所以它们先被执行。
4. 关系运算符关系运算符用于比较两个值的大小关系。
在C语言中,关系运算符的优先级别比加法和减法运算符低,但比赋值运算符高。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int t;
switch(ch)
{
case '+':t=0;break;
case '-':t=1;break;
case '*':t=2;break;
case '/':t=3;break;
case '(':t=4;break;
case ')':t=5;break;
case 'i':t=6;break;
case'-':zhongjian[q++]='-';break;
case'*':zhongjian[q++]='*';break;
case'/':zhongjian[q++]='/';break;
case'(':zhongjian[q++]='(';break;
case')':zhongjian[q++]=')';break;
break;
}
}
while(syn!=0);
}
void main()
{
loadch();
saomiao();
if(syn==0)
{
chu();
analyse();
printf("#E\t#\t结束\n");
if (syn==0)
{
printf("该字符串可被文法识别\n");
printf("E");
case'i':zhongjian[q++]='i';break;
case'#':zhongjian[q++]='#';syn=0;break;
default: syn=-1;break;
}
}
void saomiao()
{
p=0;q=0;
do
{
scaner();
if(syn==-1)
{
printf("输入符号有误!\n");
d=putzhong();
a=findint(zh);
b=findint(ch);
if (table[a][b]==-1)
{
push(ch);
j++;
printf("移进\n");
}
else if (table[a][b]==1)
{
for(int m=d;m>=j;m--)
{
shu[c++]=zhongjian[m];
for(int i=c;i>=0;i--)
{
printf("%c",shu[i]);
}
printf("\n");
}
else
{
printf("该字符串不可被文法识别\n");
}
}
}
{
printf("%c",zhan[i]);
}
printf("\t");
}
int putzhong()//打印;
do
{
printf("%c",zhongjian[i]);
}while(zhongjian[i++] != '#');
printf("\t");
i-=2;
return i;
shu[c++]=' ';
shu[c++]='>';
shu[c++]='-';
shu[c++]=' ';
}
else
{
syn=-1;
break;
}
zh=ding();
ch=zhongjian[j];
}
}
void loadch()//读入所有字符串
{
int i=0;
printf("请输入要进行算符优先分析的字符串:\n");
char zhan[100];//数组栈
int z,j;//z为栈顶指针,j为zhongjian数组指针
void push(char ch)//入栈
{
zhan[z++]=ch;
}
void pop()//出栈
{
z--;
}
void putzhan()//打印栈内字符
{
for(int i=0;i<z;i++)
#include<stdio.h>
char prog[100],zhongjian[100],shu[500];
char ch,zh;
int syn,p,q,a,b,c,d; //p指向prog,q指向zhongjian
int table[8][8]={
{1,1,-1,-1,-1,1,-1,1},
{1,1,-1,-1,-1,1,-1,1},
do
{
ch=getchar();
prog[i++]=ch;
}
while(ch!='#');
}
void scaner()
{
syn=1;
ch=prog[p++];
while(ch==' '||ch=='\n')
{
ch=prog[p++];
}
switch(ch)
{
case'+':zhongjian[q++]='+';break;
{1,1,1,1,-1,1,-1,1},
{1,1,1,1,-1,1,-1,1},
{-1,-1,-1,-1,-1,-1,-1,0},
{1,1,1,1,0,1,0,1},
{1,1,1,1,0,1,0,1},
{-1,-1,-1,-1,-1,0,-1,-1}};
//存储算符优先关系表,大于为1,小于或等于为-1,其它为0表示出错
}
char ding()//获取栈顶元素,无视E
{
char a;
q=z-1;
do
{
a=zhan[q--];
}while(a=='E');
return a;
}
char ding2()//获取栈顶元素
{
char a;
q=z-1;
a=zhan[q];
return a;
}
int findint(char ch) /*将字符转为数字,以得到算符优先值*/
case '#':t=7;
}
return t;
}
void chu()//初始化
{
zhan[0]='#';
z=1;
c=0;
j=0;
syn=0;
zh=ding();
ch=zhongjian[j];
}
void analyse()//分析
{
while (zh!='#'||ch!='#')
{
putzhan();
}
for(int i=z-1;i>0;i--)
{
shu[c++]=zhan[i];
}
zh=ding2();
if(zh=='i') //当前比较为i,出栈一次
pop();
else //当前比较不为i,出栈三次
{
pop();
pop();
pop();
}
push('E'); //归约到E
printf("归约\n");