预测分析法(编译原理)
2020年奥鹏北京语言大学20春《编译原理》作业4-参考答案

【选项】:
A错误
B正确
【答案】:A
8.所谓基本块是指程序中一个顺序执行的语句序列,其中只有一个入口语句和一个出口语句。
【选项】:
A错误
B正确
【答案】:B
9.逆波兰法表示的表达式把运算对象放在运算符的后面。( )
【选项】:
B正确
【答案】:A
13.一个有限状态自动机中,有且仅有一个唯一的终态。( )
【选项】:
A错误
B正确
【答案】:A
14.递归下降法允许任一非终极符是直接左递归的。( )
【选项】:
A错误
B正确
【答案】:B
15.进行代码优化时应着重考虑循环的代码优化,这对提高目标代码的效率将起更大作用。( )
【选项】:
A错误
B正确
【答案】:A
16.递归下降分析法是自顶向下分析方法。( )
【选项】:
A错误
B正确
【答案】:B
17.正则文法其产生式为A->a,A->Bb, A,B∈VN,a、b∈VT。( )
【选项】:
A错误
B正确
【答案】:A
18.静态数组的存储空间可以在编译时确定。( )
A错误
B正确
【答案】:A
10. PL/0编译程序的语法分析采用了自顶向下的递归子程序法。
【选项】:
A错误
B正确
【答案】:B
11.有两类重要的局部等价可用于基本块,它们是保结构的变换和代数变换。
【选项】:
A错误
B正确
编译原理复习

编译原理复习编译原理复习⼀、基本概念(填空15分,选择10分,简答:15分)1、编译程序按扫描源程序的遍数分类可以分为哪两类?⼀遍扫描、多遍扫描2、⾼级语⾔的单词分类有哪些?基本字、运算符、标识符、常数、界符3、⼆义性⽂法,⼆义性语⾔的定义?⼆义性⽂法:⽂法G对某句型存在⾄少两种不同的语法树。
⼆义性语⾔:某语⾔对应的任意⼀种⽂法都是⼆义性⽂法4、DFA的定义及组成:确定的有穷⾃动机; M=(K,∑,f, S,Z)K是⼀个有穷集,它的每个元素称为⼀个状态;∑是⼀个有穷字母表,它的每个元素称为⼀个输⼊符号,所以也称∑为输⼊符号表; F是转换函数,是K×∑→K上的映像S∈K,是唯⼀的⼀个初态Z K,是⼀个终极态,终态也称为接收状态或结束状态5、最左推导、规范推导的定义:最左推导:若x和y是符号串α中有两个以上的⾮终结符号时,对推导的每⼀步坚持把α中的最左⾮终结符号进⾏替换,称为最左推导。
规范推导:通常,我们把能由最左(右)推导推出的句型称为左(右)句型。
另外,也常把最右推导称为规范推导,⽽把右句型称为规范句型。
6、确定的⾃顶向下分析⽅法通常有哪两种?采⽤确定的⾃顶向下分析的前提条件是什么?递归⼦程序法、预测分析法对每⼀个⾮终结符A的两个不同产⽣式,A→α,B→β,满⾜SELECT(A→α)∩SELECT(B→β)=?,其中αβ不同时能→ε7、词法分析的常⽤⽅法有哪两种?⾃顶向下;⾃底向上。
8、简单优先分析法、算符优先分析法属于、LR(0)分析法分别属于何种归约?规范规约、⾮规范规约、规范规约9、⾼级程序设计语⾔的翻译⽅式主要有哪两种,⼆者的根本区别在于哪⾥?⽅式:编译程序、解释程序区别:⽣不⽣成⽬标代码10、词法分析程序和语法分析程序的任务分别是什么?词法分析是编译的第⼀阶段,它的主要任务是按语⾔的词法规则,从左⾄右逐个字符地对源程序进⾏扫描,从源程序中识别出每个单词,并把每个单词转换成它们的内部表⽰,即所谓的token,同时进⾏词法检查。
编译原理预测分析法实验报告

编译原理实验预测分析法姓名**学号**班级**完成日期**1.实验目的加深对语法分析器工作过程的理解;加强对预测分析法实现语法分析程序的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法翻译。
2.实验要求1.对语法规则有明确的定义;2.编写的分析程序能够对实验一的结果进行正确的语法分析;3. 3.对于遇到的语法错误, 能够做出简单的错误处理, 给出简单的错误提示, 保证顺利完成语法分析过程;4. 4.实验报告要求用文法的形式对语法定义做出详细说明, 说明语法分析程序的工作过程, 说明错误处理的实现。
5.实验原理对文法G进行语法分析, 文法G如下所示:*0. S→a */*1. S→.*2. S→(T)*3. T→SW **4..W→,S.*5. W→ε;6.软件设计与编程#include <stdio.h>#include <stdlib.h>#include <string.h>char str[100]; //存储待分析的句子const char T[ ] = "a^(),#"; //终结符, 分析表的列符const char NT[ ] = "STW"; //非终结符, 分析表的行符/*指向产生式右部符号串*/const char *p[] = {/*0. S→a */ "a",/*1.. S→. *. "^",/*2. S→(T) */ "(T)",/*3. T→SW */ "SW",/*4.. W→,S. */ ",SW",/*5. W→ε; */ ""};//设M[i][j]=x, 通过p[M[i][j]]=p[x]获取右部符号串。
const int M[][6] = {/* a ^ ( ) , # *//*S*/ { 0, 1, 2, -1, -1, -1 },/*T*/ { 3, 3, 3, -1, -1, -1 },/*W*/ { -1, -1,-1, 5, 4, -1 }};void init()//输入待分析的句子{printf("请输入待分析的句子(以$结束): \n");scanf("%s",str);}int lin(char c);//非终结符转换为行号int col(char c);//终结转换为列号bool isNT(char c);//isNT判断是否是非终结符bool isT(char c);//isT判断是否是终结符。
编译原理复习题

一、判断题1.SLR(1)分析法是一种规范归约分析法。
()2.算符优先文法可以是二义性文法。
()3.每个短语都是某规则的右部。
()4.语法分析时必须先消除文法中的左递归。
()5.如果两个正规式是等价的,则它们所表示的正规集相同。
()()1.编译程序的输入是高级语言程序,输出是机器语言程序。
()2.文法G[S]:S→iSeS|iS|i是二义文法。
()3.若一个语言的句子有无穷多个,则对应的文法必定是递归的。
()4.上下文无关文法可以产生语言L={a n b n a m b m | n,m≥0}。
()5.设文法G[N]:N→ND|D,D→0|1|2|3|4|5|6|7,则句子3247的最右推导为:N=>ND=>N4=>ND4=>N74=>ND74=>N274=>D274=>3274。
()6.每一个NFA都对应有唯一的一个最小化的DFA。
()7.文法G[S]:S→(S)S|ε不是LL(1)文法。
()8.若文法任一产生式的右部不含两个相继的非终结符(…QR…),则称该文法为算符文法。
()9.优先函数是唯一的,有的优先关系矩阵不存在对应的优先函数。
()10.在LR(1)分析法中,搜索符仅对规约项目才有意义。
1、文法规则的左部就是非终结符号。
2、乔姆斯基定义1型文法对规则的限制比2型文法对规则的限制要多一些。
3、LR(K)分析法能彻底解决冲突。
4、一个程序是正确的是指该程序的语法是完全正确的。
5、每一个编译程序都由完成词法分析、语法分析、语义分析、代码优化和代码生成工作的五部分程序组成。
6、多遍扫描的编译程序优于单遍扫描的编译程序。
7、每个句子都有规范推导;每个句型都有规范推导。
8、存在这样一些语言,它们能被确定有限自动机(DFA)识别,但不能用正规表达式表示。
9、每一个NFA都对应有唯一的一个最小化的DFA。
10、若给定文法G和某个固定的k,则G是否是LR(k)文法是可判定的。
软件工程 编译原理 第五章 自顶向下的语法分析方法

例:文法G(E):
E→TE E→+TE | T→FT PROCEDURE F; T→*FT | IF SYM=‘i’ THEN ADVANCE F→(E) | i ELSE 对应的递归下降子程序为: IF SYM=‘(’ THEN
其中不以P开头。
可以把P的规则等价地改写为如下的非直接左递归 形式: 左递归变 P→P 右递归 P→P|
一般而言,假定P关于的全部产生式是 P→P1 | P2 | … | Pm | 1 | 2|…|n 其中,每个都不等于,每个都不以P开头 那么,消除P的直接左递归性就是把这些规则改写 成:
第5章 自顶向下的语法分析方法
语法分析的作用是识别由词法分析给出 的单词符号序列是否是给定文法的正确句 子(程序)。 目前语法分析常用的方法有: 1、自顶向下(自上而下)分析 2、自底向上(自下而上)分析
5.3非LL(1)文法到LL(1)文法的等价转换
确定的自顶向下分析要求给定语言的文法必
须是 LL(1)形式。然而,不一定每个语言都是 LL(1)文法,对一个语言的非LL(1)文法是否能变
换为等价的LL(1)形式以及如何变换是我们讨论
的主要问题。由LL(1)文法的定义可知若文法中 含有左递归或含有左公共因子,则该文法肯定不 是LL(1)文法,因而,我们设法消除文法中的左 递归,提取左公共因子对文法进行等价变换。
1、提取公共左因子
若文法中含有形如:A→αβ|αγ的产生式,这导 致了对相同左部的产生式其右部的FIRST集相交, 也就是 SELECT(A→αβ)∩SELECT(A→αγ) ≠ φ ,不满足 LL(1)文法的充分必要条件。
编译原理考题与答案

《编译原理》考题与答案(总16页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--[试题分类]:专升本《编译原理》_08033150[题型]:单选[分数]:21.文法所描述的语言是()的集合。
A.文法的字汇表V中终结符号组成的符号串B.文法的字汇表V中符号组成的符号串C.由文法开始符推导的终结符号串D.由文法开始符推导的符号串答案:C2.设识别文法G[S]的LR(0)活前缀的DFA中,存在一个LR(0)项目集,其中X和A为非终结符,b为终结符,则该项目集含有()冲突。
A.归约——归约B.移进——接受C.移进——待约D.移进——归约答案:D3.已知文法,()是句型PaFaFbP的最左素短语。
答案:C4.已知文法()。
A.{A,B}B.{S,A,B}C.{S}D.{S,A}答案:C5.已知字母表,下列选项中()不是字母表∑上的正规式。
A.B.C.D.答案:B6.文法产生的语言是()。
A.B.C.D.答案:D7.算符优先分析方法是总是对当前句型的()进行归约的。
A.最左素短语B.句柄C.素短语D.简单短语答案:A8.设是任意符号串,则下列为恒等式的是()。
A.B.C.D.答案:C9.局部优化指是在程序的()范围内的优化。
A.循环体B.函数体C.基本块D.全部代码段答案:C10.语言学家Chomsky将文法和语言分为四大类,其中1型文法又称为()。
A.上下文无关文法B.上下文有关文法C.短语文法D.正规文法答案:B11.词法分析器的输出结果是()。
A.单词的种别编码B.单词的种别编码和自身值C.单词在符号表中的位置D.单词自身值答案:B12.编译程序的编译方式有()种。
A. 1B. 3C. 4D. 2答案:D13.表达式:X:=(X+Y)/ Z的四元式是()。
A.(+,Y,X,T1),(/,Z,T1,T2), (:=,T2,,X)B.C.D.答案:C14.已知文法,()是该文法的句子。
编译原理-课程简介
编译原理中的程序分析技术可以 用于逆向工程中的程序分析,帮
助理解程序的结构和功能。
代码重构
在逆向工程中,编译原理可以帮助 对代码进行重构,提高代码的可读 性和可维护性。
病毒分析和防治
编译原理可以帮助分析和防治计算 机病毒,保护计算机系统的安全。
计算机体系结构相关应用
指令集设计
编译原理可以指导计算机指令集 的设计,提高处理器的性能。
• 向量化技术的实现方法:向量化技术的实现方法包括自动向量化和手动向量化 两种。自动向量化是指编译器自动将程序中的循环结构转换为向量运算;而手 动向量化则需要程序员手动编写向量运算的代码。在实现向量化技术时,需要 注意处理器的向量长度、数据对齐等问题。
04
CATALOGUE
运行时环境支持
存储管理策略及实现
定义不同类型的异常,如语法错误、 运行时错误等,以便程序能够识别并 处理异常情况。
控制异常在程序中的传播范围,避免异常对 程序其他部分的影响,同时提供异常恢复机 制,使程序能够从异常情况中恢复执行。
异常捕获与处理
在程序中设置异常捕获机制,当异常发 生时能够捕获异常并执行相应的处理代 码,保证程序的稳定性和可靠性。
自顶向下语法分析
从文法的开始符号出发,根据产生式 规则推导出输入符号串的过程。
自底向上语法分析
从输入符号串出发,逐步归约到文法 的开始符号的过程。
LL(1)语法分析方法
一种预测分析方法,根据当前输入符 号和上下文信息预测下一个要产生的 非终结符。
LR(1)语法分析方法
一种规范归约分析方法,根据当前输 入符号和栈顶信息确定句柄并进行归 约。
01
02
03
静态存储分配
编译原理(3)语法_4(自顶向下语法分析:LL(1)分析法)
课本例题3.8 第二步:计算非终结符的FOLLOW集合
G[E]: E→TE' E'→ + TE' | ε T→FT' T'→*FT' | ε F→(E) | i ③由E→TE' 知FOLLOW(E) ⊂ FOLLOW(E' ), 即FOLLOW(E' ) = {),#}; 由E→TE ' 且E ' → ε知FOLLOW(E)FOLLOW(T),即 FOLLOW(T) = {+,),#};
特别是当Y1~Yk均含有ε产生式时,应把ε也加到FIRST(X)中。
课本例题3.8 第一步:计算非终结符的FIRST集合 例3.8 试构造表达式文法G[E]的LL(1)分析表,其中: G[E]: E→TE' E'→ + TE' | ε T→FT' T'→*FT' | ε F→(E) | i
[解答] 首先构造FIRST集,步骤如下: ① FIRST(E') = {+, ε}; FIRST(T') = {*, ε}; FIRST(F) = {(, i}; ② T→F… 和E→T…知:FIRST(F) ⊂ FIRST(T) ⊂ FIRST(E) 即有FIRST(F) = FIRST(T) = FIRST(E) = {(,i}。
编译原理中LL(1)文法的源代码汇总
一. 实验目的1.掌握LL(1分析法的基本原理2.掌握LL(1分析表的构造方法3.掌握LL(1驱动程序的构造方法二. 实验内容及要求根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对预测分析LL(1)分析法的理解。
例:对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E(8)F->i输出的格式如下:(1LL(1)分析程序,编制人:姓名,学号,班级(2输入一以#结束的符号串(包括+—*/()i#:在此位置输入符号串(3输出过程如下:步骤分析栈剩余输入串所用产生式1 E i+i*i# E->TG(4输入符号串为非法符号串(或者为合法符号串备注:(1在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。
(2 在此位置输入符号串为用户自行输入的符号串。
(3上述描述的输出过程只是其中一部分的。
注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);3.对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。
同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;4.可采用的其它的文法。
三. 实验过程LL(1分析法的实验源程序代码如下:#include#include#include#includechar A[20];/*分析栈*/char B[20];/*剩余串*/char v1[20]={'i','+','*','(','','#'};/*终结符 */char v2[20]={'E','G','T','S','F'};/*非终结符 */int j=0,b=0,top=0,l;/*L为输入串长度 */typedef struct type/*产生式类型定义 */{char origin;/*大写字符 */char array[5];/*产生式右边字符 */int length;/*字符个数 */}type;type e,t,g,g1,s,s1,f,f1;/*结构体变量 */ type C[10][10];/*预测分析表 */void print(/*输出分析栈 */{int a;/*指针*/for(a=0;a<=top+1;a++printf("%c",A[a];printf("\t\t";}/*print*/void print1(/*输出剩余串*/{int j;for(j=0;j 输出对齐符 */printf(" ";for(j=b;j<=l;j++printf("%c",B[j];printf("\t\t\t";}/*print1*/void main({int m,n,k=0,flag=0,finish=0;char ch,x;type cha;/*用来接受C[m][n]*/ /*把文法产生式赋值结构体*/ e.origin='E';strcpy(e.array,"TG";e.length=2;t.origin='T';strcpy(t.array,"FS";t.length=2;g.origin='G';strcpy(g.array,"+TG";g.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,"*FS";s.length=3;s1.origin='S';s1.array[0]='^';s1.length=1;f.origin='F';strcpy(f.array,"(E";f.length=3;f1.origin='F';f1.array[0]='i';f1.length=1;for(m=0;m<=4;m++/*初始化分析表*/for(n=0;n<=5;n++C[m][n].origin='N';/*全部赋为空*//*填充分析表*/C[0][0]=e;C[0][3]=e;C[1][1]=g;C[1][4]=g1;C[1][5]=g1;C[2][0]=t;C[2][3]=t;C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;C[4][0]=f1;C[4][3]=f;printf("提示:本程序只能对由'i','+','*','(',''构成的以'#'结束的字符串进行分析,\n"; printf("请输入要分析的字符串:";do/*读入分析串*/{scanf("%c",&ch;if ((ch!='i' &&(ch!='+' &&(ch!='*'&&(ch!='('&&(ch!=''&&(ch!='#'{printf("输入串中有非法字符\n";exit(1;}B[j]=ch;j++;}while(ch!='#';l=j;/*分析串长度*/ch=B[0];/*当前分析字符*/A[top]='#'; A[++top]='E';/*'#','E'进栈*/printf("步骤\t\t分析栈 \t\t剩余字符 \t\t所用产生式 \n"; do{x=A[top--];/*x为当前栈顶字符*/printf("%d",k++;printf("\t\t";for(j=0;j<=5;j++/*判断是否为终结符*/if(x==v1[j]{flag=1;break;}if(flag==1/*如果是终结符*/{if(x=='#'{finish=1;/*结束标记*/printf("acc!\n";/*接受 */getchar(;getchar(;exit(1;}/*if*/if(x==ch{print(;print1(;printf("%c匹配\n",ch;ch=B[++b];/*下一个输入字符*/flag=0;/*恢复标记*/}/*if*/else/*出错处理*/{print(;print1(;printf("%c出错\n",ch;/*输出出错终结符*/ exit(1;}/*else*/}/*if*/else/*非终结符处理*/{for(j=0;j<=4;j++if(x==v2[j]{m=j;/*行号*/break;}for(j=0;j<=5;j++if(ch==v1[j]{n=j;/*列号*/break;}cha=C[m][n];if(cha.origin!='N'/*判断是否为空*/{print(;print1(;printf("%c->",cha.origin;/*输出产生式*/for(j=0;jprintf("%c",cha.array[j];printf("\n";for(j=(cha.length-1;j>=0;j--/*产生式逆序入栈*/ A[++top]=cha.array[j];if(A[top]=='^'/*为空则不进栈*/top--;}/*if*/else/*出错处理*/{print(;print1(;printf("%c出错\n",x;/*输出出错非终结符*/exit(1;}/*else*/}/*else*/}while(finish==0;}/*main*/程序的运行结果如下:四. 实验心得经过这个实验的练习,通过对程序的分析,让我进一步了解LL(1)算法的思想以及它的进一步程序实现,让我对它的了解从简单的理论上升到程序实现的级别,有理论上升到实际,让我更清楚它的用途。
编译原理_第5章(清华大学)
学习目标: ➢掌握:LL(1)文法的判别,预测分析
法,递归子程序的构造方法 ➢理解:LL(1)文法 ➢了解:不确定的自顶向下分析
语法分析的作用是识别由词法分析给出的单词序 列是否是给定文法的正确句子
分类:
语法分析
自顶向下分析 自底向上分析
确定的
不确定的 算法优先分析(第六章)
进行推导,类似地LL(k)文法需要向前看K个符号才 可以确定选用哪个产生式。
例 有文法G[S]为:
S→aAS
SELECT(S→aAS)= {a}
S→b
SELECT(S→b)= {b}
A→bA
SELECT(A→bA)= {b}
A→ε
SELECT(A→ε)=Follow(A)= {a,b}
Hale Waihona Puke 由于SELECT(A→bA)∩SELECT(A→ε)={b}≠Φ,
此外若可能导出空串,A自动获得匹配,输入符a 有可能与A后的一个符号匹配,所以当a应属于 Follow(A)时,选择产生式A→也是可以的。
直观上说某产生式A→α的选择集合是指遇到哪些输 入符号(包括#)时选用该产生式向下推导。
例 G3[S]: 若α≠>*ε,则SELECT(A→α)=FIRST(α) S→aA 若α=>*ε, 则SELECT(A→α)
例文法G2[S]: S→Ap FIRST(Ap)={a,c}
S→Bq FIRST(Bq)={b,d}
A→a
FIRST(a)={a }
A→cA FIRST(cA)={c}
B→b
FIRST(b)={b}
B→dB FIRST(dB)={d}
由于同一非终结符的两个产生式的右部推导出来的 开始符号集不相交,因此可根据当前输入符属于哪 个产生式右部的开始符号集而决定选哪个产生式进 行推导,可以进行确定的自顶向下分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二基于预测方法的语法分析程序的设计
一、实验目的
了解预测分析器的基本构成及用自顶向下的预测法对表达式进行语法分析的方法,掌握预测语法分析程序的手工构造方法。
二、实验内容
1、了解编译程序的基于预测方法的语法分析过程。
2、根据预测分析原理设计一个基于预测方法的语法分析程序。
三、实验要求
对给定文法G[S]:
S->AT A->BU T->+AT|$ U->*BU|$ B->(S)|m
其中,$表示空串。
1、判断上述文法G[S]是否LL(1)文法,若不是,将其转变为LL(1)文法;
2、对转变后的LL(1)文法建立预测分析表;
3、根据清华大学出版编译原理教材教材第五章P94的图5.11手工构造预测分析程序;
4、用预测分析程序对任意给定的键盘输入串m+m*m#进行语法分析,并根据栈的变化状态输出给定串的具体分析过程。
四、运行结果
从任意给定的键盘输入串:
m+m*m#;
输出:
本实验重点有两个:一是如何用适当的数据结构实现预测分析表存储和使用;二是如何实现各规则右部串的逆序入栈处理。
建议:使用结构体数组。
六、分析与讨论
1、若输入串不是指定文法的句子,会出现什么情况?
2、总结预测语法分析程序的设计和实现的一般方法。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
struct stack1
{
char stack[10];
}sta[][7]=
{
"\0","+","*","(",")","m","#",
"S","\0","\0","AT","\0","AT","\0",
"A","\0","\0","BU","\0","BU","\0",
"T","+AT","\0","\0","$","\0","$",
"B","\0","\0","(S)","\0","m","\0",
"U","$","*BU","\0","$","\0","$"
};
//struct stack *head;
char stack_1[10]={'\0'},stack_2[10]={'\0'},stack_3[10]={'\0'}; int i,j,k,len_1,len_2,len_3,mark=0;
void main()
{
// void c_stack();
void analyze_stack();
void surplus_str();
int rules();
// printf("%s\t",sta[0][1].stack);
// printf("\n");
while(1)
{
// system("cls");
mark=0;
printf("请输入串:\n");
gets(stack_3);
if(stack_3[0]=='0')
break;
stack_1[0]='S';
len_3=strlen(stack_3);
if(stack_3[len_3-1]!='#')
{
printf("字符串输入错误,字符串不以#号结束!\n");
continue;
}
printf("分析栈\t\t剩余串\t\t\t\t\t\t规则\n");
for(i=0;i<=100;i++)
{
analyze_stack();
surplus_str();
rules();
if(mark==1)
break;
if(stack_1[0]=='\0'&&stack_3[0]=='#')
{
printf("#\t\t#\t\t\t\t\t\t成功接受\n");
break;
}
}
}
}
void analyze_stack()//分析栈
{
printf("#%-15s",stack_1);
len_1=strlen(stack_1);
}
void surplus_str()//剩余串//注意拼写的正确性,写成surlpus_str()报错,unresolved sxternal symbol_surplus_str;
{
printf("%-48s",stack_3);
}
int rules()//所用规则
{
int p,q,h;
char temp;
// printf("%d",len_1);
if(stack_1[len_1-1]==stack_3[0])
{
printf("%c匹配\n",stack_3[0]);
stack_1[len_1-1]='\0';
for(h=1;h<=len_3-1;h++)
stack_3[h-1]=stack_3[h];
stack_3[len_3-1]='\0';
}
else if(stack_1[len_1-1]<'A'||stack_1[len_1-1]>'Z') {
printf("报错\n");
mark=1;
return 0;
}
else if(stack_1[len_1-1]>='A'&&stack_1[len_1-1]<='Z') {
for(j=1;j<=5;j++)
{
if(stack_1[len_1-1]==sta[j][0].stack[0])
{
p=j;
break;
}
}
if(j>=6)
{
printf("报错\n");
mark=1;
return 0;
}
for(k=1;k<=6;k++)
{
if(stack_3[0]==sta[0][k].stack[0])
{
q=k;
break;
}
}
if(k>=7)
{
printf("报错\n");
mark=1;
return 0;
}
if(sta[p][q].stack[0]=='\0')
{
printf("报错\n");
mark=1;
return 0;
}
strcpy(stack_2,sta[p][q].stack);
len_2=strlen(stack_2);
printf("%c->%s\n",stack_1[len_1-1],stack_2); stack_1[len_1-1]='\0';
if(stack_2[0]=='$')
{
}
else
{
for(h=0;h<len_2/2;h++)
{
temp=stack_2[h];
stack_2[h]=stack_2[len_2-1-h];
stack_2[len_2-1-h]=temp;
}
strcat(stack_1,stack_2);
}
}
return 0;
}。