}
intAccidenceAnalysis:
:
IsOperator(char*p)//判断字符是否是字符集[+,-,*,/,(,)]中的字
{
charch=*p;
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')')
return1;
else
return0;
}
intAccidenceAnalysis:
:
IsUnsignedNum(char*p)//是否是1——9的数字
{
charch=*p;
if('0'<=ch&&ch<='9')
return1;
else
return0;
}
intAccidenceAnalysis:
:
IsAcceptantCharacter(char*p)//判断字符是否是字符集中的字
{
charch=*p;
if(IsOperator(p)||IsUnsignedNum(p)||ch=='E'||ch=='.')
return1;
elsereturn0;
}
voidAccidenceAnalysis:
:
IdentifyOperator(char*p)//对字符[+,-,*,/,(,)]分类识别
{
charch=*p;
switch(ch)
{
case'+':
Output(PLUS,p,p);break;
case'-':
Output(SUBTRACT,p,p);break;
case'*':
Output(MULTIPLY,p,p);break;
case'/':
Output(DIVIDE,p,p);break;
case'(':
Output(LEFTBRACKET,p,p);break;
case')':
Output(RIGHTBRACKET,p,p);break;
default:
break;
}
}
voidAccidenceAnalysis:
:
AssortIdentify()//对字符分类识别
{
cout<<"\t单词分析结果显示:
\n"<while(*p!
='\0')
{
if(IsOperator(p))
{
IdentifyOperator(p++);
continue;
}
elseif(IsUnsignedNum(p)||*p=='.')
{
char*p1=p;
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
if(*p=='\0')
{
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
elseif(*p=='E')
{
p++;
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
elseif(*p=='+'||*p=='-')
{
p++;
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
else
{
Output(INEFFICACIOUSLABEL,p1,--p);
p++;
continue;
}
}
elseif(*p=='.')
{
p++;
while(IsUnsignedNum(p))
p++;
if(*p=='\0')
{
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
elseif(*p=='E')
{
p++;
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
elseif(*p=='+'||*p=='-')
{
p++;
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
else
{
Output(INEFFICACIOUSLABEL,p1,--p);
p++;
continue;
}
}
else
{
Output(INEFFICACIOUSLABEL,p1,--p);
p++;
continue;
}
}
else
{
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
}
else
{
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
}
if(*p=='.')
{
p++;
if(IsUnsignedNum(p))
{
p++;
while(IsUnsignedNum(p))
p++;
if(*p=='\0')
{
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
elseif(*p=='E')
{
p++;
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
elseif(*p=='+'||*p=='-')
{
p++;
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
}
else
{
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
}
else
{
Output(INEFFICACIOUSLABEL,p1,--p);
p++;
continue;
}
}
}
elseif(*p=='E')
{
Output(INEFFICACIOUSLABEL,p,p);
p++;
continue;
}
}
}
voidAccidenceAnalysis:
:
StartAccidenceAnalysis()//开始分析函数
{
AccidenceAnalysisaccidenceanalysis;
accidenceanalysis.InputStr();
accidenceanalysis.AssortIdentify();
}
intmain()
{
AccidenceAnalysis:
:
StartAccidenceAnalysis();
return0;
}
五、实验感想
通过此次实验,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,根据识别语言单词的状态转换图,使用某种高级语言直接编写此法分析程序。
另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。
实验二语法分析程序实现
一、实验目的与要求
通过设计、编制、调试典型的SLR
(1)语法分析程序,实现对实验一所得词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
二、实验内容
选择对各种常见高级程序设计语言都较为通用的语法结构无符号数的算术四则运算作为分析对象,给出其文法描述(注意应与所采用的语法分析方法比较贴近),设计并实现一个完整的语法分析程序。
输入:
由实验一输出的单词类别串,如1,3,1。
输出:
对于所输入的源程序,如果输入符号串是给定文法定义的合法句子,则输出“RIGHT”,并且给出每一步归约的过程;如果不是句子,即输入串有错误,则输出“ERROR”,并且显示已经归约出的各个文法符号,以及必要的出错说明信息。
三、实现方法与环境
1、首先根据算术四则运算的语法定义,构造SLR
(1)分析表。
无符号数的算术四则运算的语法可表示为:
E->E+T|E-T|T
T->T*F|T/F|F
F->(E)|i
2、语法分析程序编写
设置输入缓冲区、状态栈、符号栈,并根据SLR
(1)分析表利用某种语言(C语言或JAVA语言)直接编写移进、归约、接受子程序,编写语法分析程序。
3、语法分析程序测试
用于测试的实例源文件中应有语法正确的,也应有语法错误的符号串,以对照的形式将分析结果信息在输出文件中表示出来。
四、实验程序
#include
#include
#include
#include
usingnamespacestd;
structcode_val
{
charcode;
};
constchar*p[]=
{//产生式
"E'→E","E→E+T","E→E-T","E→T","T→T*F","T→T/F","T→F","F→(E)","F→i"
};
constcharTNT[]="+-*/()i#ETF";//LR分析表列的字符
constintM[][11]={
{0,0,0,0,5,0,4,0,1,2,3},
{7,6,0,0,0,0,0,17},
{-3,-3,10,12,0,-3,0,-3},
{-6,-6,-6,-6,0,-6,0,-6},
{-8,-8,-8,-8,0,-8,0,-8},
{0,0,0,0,5,0,4,0,14,2,3},
{0,0,0,0,5,0,4,0,0,8,3},
{0,0,0,0,5,0,4,0,0,9,3},
{-2,-2,10,12,0,-2,0,-2},
{-1,-1,10,12,0,-1,0,-1},
{0,0,0,0,0,0,4,0,0,0,11},
{-4,-4,-4,-4,0,-4,0,-4},
{0,0,0,0,0,0,0,4,0,0,13},
{-5,-5,-5,-5,0,-5,0,-5},
{7,6,0,0,0,15,0,0},
{-7,-7,-7,-7,0,-7,0,-7}
};
intcol(char);//列定位函数原型
voidmain()
{
intstate[50]={0};//状态栈初值
inttop=0;//栈顶指针初值
ifstreamcin("E:
\lex_r.txt");
structcode_valt;//结构变量,存放单词。
cin>>t.code;
do{//读一单词
intaction;
action=M[state[top]][col(t.code)];
if(action>0&&action!
=17)
{//移进
state[++top]=action;
cin>>t.code;
}
elseif(action<0)
{//归约
top=top-(strlen(p[-action])-3);//"→"为汉字,占2字节故减3
state[top+1]=M[state[top]][col(p[-action][0])];//产生式左部符号
top=top+1;
}
elseif(action==17)
{
cout<<"Acc";break;}
else{cout<<"err";break;
}
}while
(1);
}
intcol(charc)//将字符+*()i#ETF分别转换为数字012345678
{
for(inti=0;i<(int)strlen(TNT);i++)
if(c==TNT[i])returni;
cout<<"Errincolchar>"<exit(0);//终止程序运行
}
四、实验感想
SLR
(1)文法有效地消除了规约和移进之间的冲突,在程序中设了两个堆栈,一个状态栈,一个符号栈。
根据LR分析表构造了一个ACTION和GOTO矩阵,再用循环的方式把堆栈中的内容显示出来。
实验三语义分析程序实现
一、实验目的与要求
通过设计、编制、调试一个简单的语义处理分析程序,实现对实验一和实验二所得单词和语句的语义信息简单处里,进一步掌握语义处理的内容和简单方法。
二、实验内容
对实验一进行扩展,对识别的无符号数进行计值,并将输出形式改为(类别码,值)的二元式形式。
对实验二进行扩展,在语法分析的基础上,增加语义操作来实现语法制导翻译。
对于给定文法中的每一产生式,编写相应的语义子程序。
在语法分析过程中,每当用一产生式进行推导或归约时,语法分析程序除执行相应的语法分析动作之外,还要调用相应的语义子程序,计算并输出算术表达式的值。
将实验一与实验二的程序合并,以能对完整的输入源文件进行词法分析生成中间文件,然后进行语法制导翻译,输出最终翻译结果。
输入:
由无符号数和+,—,*,/,(,)构成的算术表达式。
输出:
如果输入单词串是合法的无符号数的算术四则运算,输出运算结果,并且给出每一步的分析过程;如果不是无符号数的算术四则运算,输出“非法四则运算表达式”。
三、基本实验题目
对实验一中每个无符号数识别状态插入计值处理,最终获得无符号数的取值。
对实验二进行扩展,在归约(分析表中的归约动作已经反应了运算优先级)处理子程序中加入计值处理,接受子程序中加入输出算数表达式值的处理。
四、实验程序
#include
#include
#include
#include
usingnamespacestd;
#defineEndState-1
charACTION[16][8]=
{
{'s','e','e','e','e','s','e','e'},{'e','s','s','e','e','e','e','a'},{'e','r','r','s','s','e','r','r'},
{'e','r','r','r','r','e','r','r'},{'s','e','e','e','e','s','e','e'},{'e','r','r','r','r','e','r','r'},
{'s','e','e','e','e','s','e','e'},{'s','e','e','e','e','s','e','e'},{'s','e','e','e','e','s','e','e'},
{'s','e','e','e','e','s','e','e'},{'e','s','s','e','e','e','s','e'},{'e','r','r','s','s','e','r','r'},
{'e','r','r','s','s','e','r','r'},{'e','r','r','r','r','e','r','r'},{'e','r','r','r','r','e','r','r'},
{'e','r','r','r','r','e','r','r'}
};
intGOTO[16][11]=
{
{5,0,0,0,0,4,0,0,1,2,3},{0,6,7,0,0,0,0,0,0,0,0},{0,2,2,8,9,0,2,2,0,0,0},
{0,5,5,5,5,0,5,5,0,0,0},{5,0,0,0,0,4,0,0,10,2,3},{0,8,8,8,8,0,8,8,0,0,0},
{5,0,0,0,0,4,0,0