编译原理课程设计
宁波大红鹰学院
信息工程学院 课程设计报告
课程名称
编译原理
基于LL(1)法的条件语实验名称 句语法语义分析程序
姓名
学号
专业
班级
地点
教师
目 录
一.系统需求分析------------------------------------------------------------------------------------
二.概念模型设计------------------------------------------------------------------------------------
三.逻辑模型设计------------------------------------------------------------------------------------
四.物理模型设计------------------------------------------------------------------------------------
五.实验结果分析------------------------------------------------------------------------------------
六.心得体会--------------------------------------------------------------------------------------------
七.源代码------------------------------------------------------------------------------------------------
一.系统需求分析
通过设计,编制,调试一个语法及语义分析程序,加深对语法及语义分析原理的理解。 IF 〈布尔表达式〉 THEN 〈赋值语句〉 ELSE 〈赋值语句〉 其中
(1)、可以选择递归下降法、LL(1)、算符优先分析法、LR法完成以上任务,中间代码选用四元式。
(2)、 写出符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。 (3)、 编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
二.概念模型设计
首先设计一个IF-THEN-ELSE的LL(1)文法。推导出该文法的预测分析表,在此基础上编写能识别该IF-THEN-ELSE的语法分析程序。
程序要求有三部分组成,即词法分析、语法分析、以及语义分析。其中词法分析部分要求完成对输入程序的关键字、标识符、常数、运算符进行识别;并分析词法分析的结果,检查程序输入的关键字是否为符合设计文法的关键字,检查标志符是否是合法标志符,识别运算符的种类。语法分析部分主要是以算符优先文法的设计思想和步骤完成对词法分析结果的的语法分析工作,判断输入的程序是否符合设计的IF-THEN-ELSE文法。在语法分析通过的基础上进行语义分析,其主要任务是完成对语法分析后的程序的语义分析,根据语法制导翻译去翻译输入的程序,从而得到程序的中间代码表示形式——四元式。
词法分析、语法分析、以及语义分析的系统流程图如下所示:
Main函数流程图:
输出单词表
语法分析程序的详细数据流图:
(1) 词法分析
A 词法分析器的功能和输出形式
输入:所给文法的源程序字符串
输出:二元组(单词种别,单词符号的属性值)构成的序列
B. 待分析的简单语言的词法
因为是模拟简单编译器, 所以就以C语言的小型子集作为模拟编译器的词法. 模拟程序语言的单词符号可分为下列五种;
关键字: { (相当于Pascal语言中的begin) , if ,else , while , }(相当于Pascal语言中的end ) 所有的关键字都是小写字母 .
运算符: + , - , * , / , = , , >= , , && ,|| , ! 界 符: 逗号 ,分号 ,左圆括号 , 右圆括号 , # 常 数: 在这里只涉及到int型常量
其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义: ID = letter(letter|digit)* NUM = digit digit *
空格由空白,制表符和换行符组成,空格一般用来分隔ID,NUM,运算符,界符和
关键字,词法分析阶段通常会被过滤掉。 C. 各种单词符号的种别码:
值得说明的是;
当种别码为22, 也就是六种运算符时, 会根据一个POS 的值(0-5)来定位到底是六种运算符中的哪一种.当pos=0 时 rop= ‘
当pos=1 时 rop= ‘=’ ; 当pos=3 时 rop= ‘> ’ ; 当pos=4 时 rop= ‘’ ; 当pos=5 时 rop= ‘==’ ;
D.词法分析的设计思想:
算法的基本任务是从字符串表示的源程序中识别出其具有独立意义的单词符号, 其基本思想是根据扫描到的单词符号的第一个字符的种类, 拼出相应的单词符号。
(2)语法分析
语法分析要处理的输入是词法分析的输出即单词序列。该部分主要用到两个栈,一个用
来保存单词标志号的状态栈另一是用来保存单词本身信息的符号栈。程序从词法分析输出的单词序列中读取一个单词,检查单词是否是合法单词,如果是合法的,则取符号栈的栈顶元素,和当前单词的标志号进行优先级比较,如果小于当前单词的优先级那么将当前单词压入符号栈,将其标志号压入状态栈;如果大于当前单词的优先级那么继续弹出状态栈的元素,和上一个符号栈弹出的元素进行比较,如果两优先级相等则继续弹,如果小于上一次弹出的元素的优先级,则弹的所有元素按先后弹的倒置顺序排列为一个句柄,查找产生式找到相应的产生式进行规约,把规约或的元素当多当前一的元素继续进行比较,直到词法分析输出结果全部遍历完。在规约的过程中记下规约的次数,和每次规约的元素,以便语义分析和中间代码生成。
(3) 语义分析
语义分析主要是将语义分析结果转化成三地址码表示的中间代码的过程。
在语法分析的过程中,在每次规约的过程中记录规约的类型和各个类型规约的次数。即当规约的语句是布尔表达式时每规约一次都将规约的语句转化成三地址码的形式保存在字符串E中并记录E中规约产生式的次数在m1.quad中;如果规约的产生式是第一个赋值语句块中的赋值语句,则将规约的产生式以三地址形式保存在字符串B1中并记录B1中规约产生式的次数在m2.quad中;如果规约的产生式是第二个赋值语句块中的赋值语句,则将规约的产生式以三地址形式保存在字符串B2中并记录B2中规约产生式的次数在 m3.quad中。最后控制将B1、B2和E中的内容输入。
三.逻辑模型设计
LL(1)文法及其属性文法
LL(1)文法分析流程图:
• 构造不带回溯的自上而下分析的文法条件 1. 文法不含左递归,
2. 对于文法中每一个非终结符A的各个产生式的候选首符集两两不相交。即,若 A→ 1| 2|„| n
则 FIRST( i)∩FIRST( j)= (ij)
3. 对文法中的每个非终结符A,若它存在某个候选首符集包含,则 FIRST(A)∩FOLLOW(A)=
如果一个文法G满足以上条件,则称该文法G为LL(1)文法。
构造预测分析表的步骤:
①对每个产生式A→1|„|n执行②,③。
②对FIRST(A)中每个终结符a, 把A→i加入到M[A,a], 其中a ∈FIRST(i) ③若ε∈FIRST(i), 则对任何属于FOLLOW(A)的终结符b,将A→ i加入M[A,b]。 ④把所有无定义的M[A,a]标记为出错。
根据算符优先文法的定义和算符优先文法的要求设计文法如下: G=(VN,VT,P,Z)VN={S,E,B,N},VT={if,then,else,>,a,b,x,=}, P由下列产生式组成: S->if E then P1 else P2 E->id1 N id2 P-> id1 N num N-> >|=|
在此文法中,a,b,x是指程序中的变量。
本次设计语法的相关属性文法可描述如下:
在上面的属性文法中我们使用了这样的假定:每当需要临时变量时,newtemp产生新的临时名字; lookup(id.name)用于根据名字的拼写检查符号表中是否存在该名字的条目。如果有,返回该条目的指针,否则lookup返回nil,以表示没有找到;E的属性place用来存放E值的变量名在符号表的登录项或一整数码(若此变量是一个临时变量);函数newtemp用来产生一个新的临时变量的名字,把该名字也存入符号表,并返回该条目的地址。过程emit将其参数写到输出文件上。emit的参数构成一个三地址语句;变量nextstat给出在输出序列中下一个三地址语句的序号,emit在产生每个三地址语句后将nextstat加1。我们给relop以属性op,用来确定该关系算符究竟代表哪个关系运算。
E.true,E.falsen和S.next都是三地址语句的标号,它们都是继承属性.。E.true和E.false分别表示E为真和为假时控制流应该转向的标号,这两个属性由E的上下文决定;S.next表示执行完S后应该执行的第一个三地址语句的标号,它也是由S的上下文决定。
四.物理模型设计
(1)语法分析方法描述
开始时,将"#"和文法开始符号放入栈底。总控程序在任何时候都是根据栈顶符号X和当前的输入符号进行工作的,它与文法无关
总控程序根据现行栈顶符号X和当前输入符号a,执行下列三种动作之一:
1. 若X=a=‘#’,则宣布分析成功,停止分析。
2. 若X=a ‘#’,则把X从STACK栈顶逐出,让指针指向下一个输入符号。 3.若X是一个非终结符,则查看分析表M。
若M[X,a]中存放着关于X的一个产生式,把X逐出STACK栈顶,把产生式的右部符号串按反序一一推进STACK栈(若右部符号为,则意味不推什么东西进栈)。在把产生式的右部符号推进栈的同时应做这个产生式相应的语义动作。
若M[X,a]中存放着“出错标志”,则调用出错诊察程序ERROR。
(2)语法分析表
计算每个非终结符的FirstVT集合和LastVT集合,结果为:
• First(S)={if}
• First(E)={ id1}
• First(P)={ id1}
• First(N)={>,=,
• FOLLOW(S)={#}
• FOLLOW(E)={then}
• FOLLOW(P)={else}
• FOLLOW(N)={num,id2}
由此可得出下面的LL(1)分析表
五.实验结果分析:
要编译的文件:
词法分析:
输出的四元式:
六.心得体会:
经过二个星期的编译原理课程设计,在老师的指导下,顺利完成该课程设计。通过该课程设计,收获颇多,对实验原理有更深的理解。通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,熟悉了编译程序总流程框图,了解了编译程序的生成过程、构造工具及其相关的技术对课本上的知识有了更深的理解,课本上的知识师机械的,表面的。通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验原理有更深的理解。
对该理论在实践中的应用有深刻的理解, 通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了该理论在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。
作系统的认识是模糊的,概念上的,现在通过自己动手做实验,从实践上认识了操作系统是如何处理命令的,如何协调计算机内部各个部件运行,对计算机编译原理的认识更加深刻。课程设计中程序比较复杂,在调试时应该仔细,在程序调试时,注意指针,将不必要的命令去除。
本次课程设计程序部分是用C语言编写的,《编译原理》,《C语言》两门门学科联系起来,把各个学科之间的知识融合起来,把课程的知识联系起来,对计算机整体的认识更加深刻。使我加深了对《编译原理》,《C语言》两门课程的认识。
七.源代码
#include
#include
#include
#include
#include
enum keyword{ $right_paren,$left_paren,$mul,$div,$add,$sub,$fenhao,
$equal,$IF,$THEN,$ELSE,$greater,$less,$id,$num,$end};//关键字的枚举 typedef struct Token { keyword type; char ch; }Token;//定义的token结构
typedef enum{JUMP,JG,JL,equal,END,add,mul,sub,div}OpKind;//操作符定义为opkind typedef struct { int label;//标号 OpKind op;//操作符 char par1,par2;//操作数 union { char result;//结果 int address;//地址 }; }Quad; //四元式入口
#define MAX_TOKEN 256//Token表大小
#define MAX_QUAD 256//四元式数组大小
Token tokentable[MAX_TOKEN];
Quad quad[MAX_QUAD];
int token_index;//token表索引
int total_len;//token表有效长度
int quad_len;//四元式表有效长度
int quad_index;//四元式索引
Token cur;
Token queue[10];
int label,k,one; //标记接口
char curchar;//存储当前待比较字符
char curtocmp;//存储当前栈顶字符
ifstream ins;
int trueadd,falseadd,end;
int table[5][8]={{1,0,0,0,0,1,0,0},
{0,1,1,0,0,0,1,1},
{1,0,0,0,0,1,0,0},
{0,1,1,1,1,0,1,1},
{1,0,0,0,0,1,0,0}}; //存储预测分析表,1为有产生式,0为没有 int i,j;
int flag;
struct Lchar
{
char char_ch;
struct Lchar *next;
}Lchar,*temp,*top,*base;
int right;//定义开关项
bool initialize(char filename[255]);//文件打开初始化 bool accidence();//词法分析
void print();//输出单词表
void backpath(int,int);//回填出口
void ERROR();
void sentence();//分析语句
void boolean();// 分析E->id id语句 bool nexttoken();//读下一单词
char newchar();
void push();//进队列
char dosome(void);//算法函数
void pushs(char pchar);//入栈函数
void pop(void);//出栈函数
void doforpush(int t);//根据数组下标计算的值产生式入栈
void changchartoint();//根据curchar,curtocmp转为数字以判断是否有产生式
void semantic();//语法语义分析
char LL1();//LL(1)文法分析
void printQuad();//输出四元式
void ERROR(char str[20]);
void AD_ADDRESS(int nlabel,OpKind nop,char npar1,char npar2,int naddress);
void AD_RESULT(int nlabel,OpKind nop,char npar1,char npar2, char nresult);
void main()
{
cout
cout
char fname[100];
cin>>fname;
if(!initialize(fname))//初始化文件
return;
if(!accidence())//词法分析
return;
char ch;
while(1)
{
if(ins.eof())//ifstream ins;文件输入串,若文件已完。则break
break;
ins>>ch;//继续读入文件内容
}
cout
print();//打印词法分析的结果
cout
cout
semantic(); //语法语义分析
cout
printQuad();//输出四元式
if(right==1)
cout
else
cout
cout
}
char newchar()
{ char p;
p=char(k); //int label,k,one; //标记接口
k++;
return p;
}
//文件打开初始化
bool initialize(char filename[100])
{
one=0;
token_index=0;//token表索引
total_len=0;//token表有效长度
quad_len=0;//四元表有效长度
quad_index=0;//四元表索引
label=0; //int label,k,one; //标记接口
end=0;// 前面定义的全局变量int trueadd,falseadd,end;
k=48;
ins.open(filename,ios::nocreate | ios::in);
if(ins.fail())
{
cout
return false;
}
return true;
}
//词法分析
bool accidence()
{
int k=0;
char buf[16];//暂存数组单元
char ch;
while(1)
{
ins>>ch;
if(ins.fail())
break;
while(ch==' ')
{ ins>>ch;}
if(ch=='I')
ins>>buf;
//对关键字分析
if(strcmp(buf,"F")==0)
tokentable[total_len++].type=$IF;
}
else if(ch=='T')
{
ins>>buf;
if(strcmp(buf,"HEN")==0)
tokentable[total_len++].type=$THEN;
}
else if(ch=='E')
{
ins>>buf;
if(strcmp(buf,"LSE")==0)
tokentable[total_len++].type=$ELSE;
}
//对关系运算符分析
else if(ch=='>')
{
tokentable[total_len++].type=$greater;
}
else if(ch=='
{
tokentable[total_len++].type=$less;
}
else if(ch=='==')
{
tokentable[total_len++].type=$equal;
}
//对字母的分析
else if((ch>='A'&& ch='a' && ch
{
tokentable[total_len].type=$id;
tokentable[total_len++].ch=ch;
}
//对数字的分析
else if(ch>='0' && ch
{ tokentable[total_len].type=$num;
tokentable[total_len++].ch =ch;
}
Else
//采用switch语句对运算符,括号分析
switch (ch)
{case '+' :
tokentable[total_len].type=$add;
tokentable[total_len++].ch =ch;
break;
case '-' :
tokentable[total_len].type=$sub;
tokentable[total_len++].ch =ch;
break;
case '/' :
tokentable[total_len].type=$div;
tokentable[total_len++].ch =ch;
break;
case '*' :
tokentable[total_len++].ch =ch;
break;
case ';' :
tokentable[total_len].type=$fenhao;
tokentable[total_len++].ch =ch;
break;
case '(' :
tokentable[total_len].type=$left_paren;
tokentable[total_len++].ch =ch;
break;
case ')' :
tokentable[total_len].type=$right_paren;
tokentable[total_len++].ch =ch;
break;
default:cout
}
}
return true;
}//词法分析结束
//语法语义分析
void semantic()
{
if(!nexttoken())
ERROR("s(0)");
cout
-> if E then S else S"
if E then p1 else P2"
a>b"
x:=a*c"
x:=b*c"
if(cur.type==$IF)
{
boolean();//分析布尔语句
if(!nexttoken())
ERROR("S(0)");
if(cur.type==$THEN)
{
backpath(trueadd,quad_len);//回填出口
sentence();//分析语句
end=quad_len;
AD_ADDRESS(quad_len,JUMP,'-','-',end); //产生跳转地址的四元式 if(cur.type==$ELSE)
{
backpath(falseadd,quad_len);
sentence();
backpath(end,quad_len);
}
else
ERROR("S(else)");
}
else
ERROR("S(then)");
}
}
else
ERROR("S(if)");
AD_RESULT(quad_len,END,0,0,'-'); //产生数值语句的四元式
}
//读下一单词
bool nexttoken()
{
if(token_index>=total_len)
return false;
if(tokentable[token_index].type==$fenhao)
token_index++;
cur.type=tokentable[token_index].type;
cur.ch=tokentable[token_index].ch;
token_index++;
return true;
}
//进队列
void push()
{ one=0;
while(tokentable[token_index].type!=$fenhao)
{
queue[one].type=tokentable[token_index].type;
queue[one].ch=tokentable[token_index].ch;
cout
token_index++;
one++;
}
queue[one].type=$end;
queue[one].ch='#';
cout
}
//队列下一个字符
void next()
{
cur.type=queue[one].type;
cur.ch =queue[one].ch ;
one++;
}
// 分析E->id id语句
void boolean()
{
char a,b;
int c;
if(!nexttoken())
ERROR("E(0)");
if(cur.type==$id||cur.type==$num)
{
a=cur.ch;
if(!nexttoken())
ERROR("E(0)");
if(cur.type==$greater||cur.type==$less)
{
c=cur.type ;
ERROR("E(0)");
if(cur.type==$id||cur.type==$num)
b=cur.ch;
else
ERROR("E(id/num)");
if(c==$greater)
{
trueadd=quad_len-1;
falseadd=quad_len;
AD_ADDRESS(quad_len,JG,a,b,trueadd);
AD_ADDRESS(quad_len,JUMP,0,0,falseadd);
}
else
{
trueadd=quad_len;
falseadd=quad_len+1;
AD_ADDRESS(quad_len,JL,a,b,trueadd);
AD_ADDRESS(quad_len,JUMP,0,0,falseadd);
}
}
else
ERROR("E(id/num)");
}
else
ERROR("E(greater/less)");
}
//分析语句
void sentence()
{ char rtn;
char c;
if(!nexttoken())
ERROR("S(0)");
if(cur.type==$id)
{
c=cur.ch;
if(!nexttoken())
ERROR("S(0)");
if(cur.type!=$equal)
ERROR("S(equal)");
push();
one=0;
rtn=LL1(); AD_RESULT(quad_len,equal,rtn,'-',c);
nexttoken();
while(cur.type==$id)
{
c=cur.ch;
if(!nexttoken())
ERROR("S(0)");
if(cur.type!=$equal)
ERROR("S(equal)");
push();
one=0;
rtn=LL1(); AD_RESULT(quad_len,equal,rtn,'-',c);
nexttoken();
}
}
//LL(1)文法分析
char LL1()
{
right=1;//开关项为1
flag=0;
char t;
base=(struct Lchar *)malloc(sizeof(Lchar));//初始化堆栈
base->next=NULL;
base->char_ch='#';
temp=(struct Lchar *)malloc(sizeof(Lchar));
temp->next=base;
temp->char_ch='E';
top=temp;//初始化堆栈
t=dosome();//开始识别
if(right)//如果开关项为1
cout
else
cout
return t;
}
//入栈函数
void pushs(char pchar)
{
temp=(struct Lchar *)malloc(sizeof(Lchar));
temp->char_ch=pchar;
temp->next=top;
top=temp;
}
//出栈函数
void pop(void)
{
curtocmp=top->char_ch;
if(top->char_ch!='#')
top=top->next;
}
//根据数组下标计算的值产生式入栈
void doforpush(int t)
{
switch(t)
{
case 0:pushs('A');pushs('T');break;
case 5:pushs('A');pushs('T');break;
case 11:pushs('A');pushs('T');pushs('+');break;
case 12:pushs('A');pushs('T');pushs('-');break;
case 20:pushs('B');pushs('F');break;
case 25:pushs('B');pushs('F');break;
case 33:pushs('B');pushs('F');pushs('*');break;
case 34:pushs('B');pushs('F');pushs('/');break;
case 40:pushs('i');break;
case 45:pushs(')');pushs('E');pushs('(');
}
}
//根据curchar,curtocmp转为数字以判断是否有产生式
void changchartoint()
{
switch(curtocmp)
{
case 'A':i=1;break;
case 'B':i=3;break;
case 'E':i=0;break;
case 'T':i=2;break;
case 'F':i=4;
}
switch(curchar)
{
case 'i':j=0;break;
case '+':j=1;break;
case '-':j=2;break;
case '*':j=3;break;
case '/':j=4;break;
case '(':j=5;break;
case ')':j=6;break;
case '#':j=7;
}
}
//算法函数
char dosome(void)
{
int t,a=0;
char bian1,bian2;
OpKind opa;
char c='$';
next();
for(;;)
{
pop();
if(cur.type!=$id && cur.type!=$num)
curchar=cur.ch;
else
curchar='i';
cout
cout
if(curtocmp=='#' && curchar=='#')
break;
if(curtocmp=='A' || curtocmp=='B' || curtocmp=='E'
|| curtocmp=='T' || curtocmp=='F')//当前字符为非终结符
{
if(curtocmp!='#')//当前比较字符不为'#'
{
changchartoint();
if(j==0)
{ a++;
flag++;
if(flag==1)
{ if(c=='$')
bian1=cur.ch;
else
bian1=c;
}
else if(flag==3)
{
bian2=cur.ch;
flag=1;
c=newchar();
AD_RESULT(quad_len,opa,bian1,bian2,c);//产生四元式
}
}
else
{
switch(j)
{
case 1:opa=add;flag++;break;
case 2:opa=sub;flag++;break;
case 3:opa=mul;flag++;break;
case 4:opa=div;flag++;
}
}
if(table[i][j]) //有产生式
{
t=10*i+j; //计算产生式在数组中的位置
doforpush(t);
continue;
}
else //没有产生式
{
right=0; //出错
break;
}
}
else //当前比较字符为'#'
if(curtocmp!=curchar)
{
right=0;//出错
break;
}
else
break; //正确
}
else //当前字符为终结符
if(curtocmp!=curchar)
{
right=0; //出错
break;
}
else
{
next(); //读取下一个字符
continue;
}
}
if(a>1)
return c;
else
return bian1;
}
//产生数值语句的四元式
void AD_RESULT(int nlabel,OpKind nop,char npar1,char npar2, char nresult)
{quad[quad_len].label=nlabel;
quad[quad_len].op=nop;
quad[quad_len].par1=npar1;
quad[quad_len].par2=npar2;
quad[quad_len].result=nresult;
quad_len++;
}
//产生跳转地址的四元式
void AD_ADDRESS(int nlabel,OpKind nop,char npar1,char npar2,int naddress)
{ quad[quad_len].label=nlabel;
quad[quad_len].op=nop;
quad[quad_len].par1=npar1;
quad[quad_len].par2=npar2;
quad[quad_len].address=naddress;
quad_len++;
}
//回填出口
void backpath(int nlabel,int addr)
{
quad[nlabel].address=addr;
}
//错误处理
void ERROR(char str[20])
{ label++;
cout
cout
}
//词法分析。输出单词表token
void print()
{
for(token_index=0;token_index
{ if(token_index%100==0)
cout
if(tokentable[token_index].type==$IF)
cout
if(tokentable[token_index].type==$ELSE)
cout
if(tokentable[token_index].type==$THEN)
cout
if(tokentable[token_index].type==$id) //字母
cout
if(tokentable[token_index].type==$num) //数字
cout
if(tokentable[token_index].type==$equal)
cout
if(tokentable[token_index].type==$greater)
cout'
if(tokentable[token_index].type==$less)
cout
if(tokentable[token_index].type==$add)
cout
if(tokentable[token_index].type==$sub)
cout
if(tokentable[token_index].type==$mul)
cout
if(tokentable[token_index].type==$div)
cout
if(tokentable[token_index].type==$fenhao)
cout
if(tokentable[token_index].type==$left_paren)
cout
if(tokentable[token_index].type==$right_paren)
cout
}
token_index=0;
}
//输出四元式
void printQuad()
{
for(int i=0;i
{
if(quad[i].label>-1)
cout
else cout
if(quad[i].op==JG)
{
cout,"
else if(quad[i].op==JL)
{
cout
else if(quad[i].op==JUMP)
{
cout
}
else if(quad[i].op==equal)
{
if(quad[i-1].result==quad[i].par1)
cout
cout
else if(quad[i].op==END)
{
cout
}
else if(quad[i].op==add)
{ if(quad[i].result>='0' && quad[i].result
cout
cout
else if(quad[i].op==sub)
{ if(quad[i].result>='0' && quad[i].result
cout
cout
else if(quad[i].op==div)
{
if(quad[i].result>='0' && quad[i].result
cout
cout
else if(quad[i].op==mul)
{ if(quad[i].result>='0' && quad[i].result
cout
cout
}
}