词法分析程序实现Word下载.docx
《词法分析程序实现Word下载.docx》由会员分享,可在线阅读,更多相关《词法分析程序实现Word下载.docx(33页珍藏版)》请在冰豆网上搜索。
//使用标准命名空间
#defineM101//定义可输入的字符个数
#defineUNSIGNEDNUMBER1//无符号数
#definePLUS2//加号
#defineSUBTRACT3//减号
#defineMULTIPLY4//乘号
#defineDIVIDE5//除号
#defineLEFTBRACKET6//左括号
#defineRIGHTBRACKET7//右括号
#defineINEFFICACIOUSLABEL8//无效字符串
charpause;
classAccidenceAnalysis//定义词法分析类
{
private:
chartestStr[M],*p;
//私有数据
public:
AccidenceAnalysis();
//构造函数
~AccidenceAnalysis();
//析构函数
voidInputStr();
//输入函数
voidOutput(inta,char*p1,char*p2);
//输出函数
intIsAcceptantCharacter(char*p);
//判断输入字符是否属于字符集
intIsOperator(char*p);
//判断字符是否是字符集[+,-,*,/,(,)]中的字符
intIsUnsignedNum(char*p);
//判断字符是否是0--9的整数
voidAbnormityExamine(chara[]);
//异常检测函数
voidIdentifyOperator(char*p);
//识别字符集[+,-,*,/,(,)]中的字符
voidAssortIdentify();
//对输入字符分类识别
voidstaticStartAccidenceAnalysis();
//开始分析函数
voidstaticStartSystem();
};
AccidenceAnalysis:
:
AccidenceAnalysis()//构造函数
inti;
for(i=0;
i<
M;
i++)
testStr[i]='
\0'
;
p=&
testStr[0];
//指针P指向字符数组首元素
}
~AccidenceAnalysis()//析构函数
voidAccidenceAnalysis:
InputStr()//输入函数
cout<
<
"
\t输入待分析单词["
M-1<
字符以内]:
charch;
inti=0;
while((ch=cin.get())!
='
\n'
)
{
testStr[i]=ch;
i++;
}
Output(inta,char*p1,char*p2)//输出函数
\t类别码:
a<
\t单词值:
while(p1<
=p2)
cout<
*p1;
p1++;
endl;
intAccidenceAnalysis:
IsOperator(char*p)//判断字符是否是字符集[+,-,*,/,(,)]中的字
charch=*p;
if(ch=='
+'
||ch=='
-'
*'
/'
('
)'
return1;
else
return0;
IsUnsignedNum(char*p)//是否是1——9的数字
if('
0'
=ch&
&
ch<
9'
IsAcceptantCharacter(char*p)//判断字符是否是字符集中的字
if(IsOperator(p)||IsUnsignedNum(p)||ch=='
E'
.'
elsereturn0;
IdentifyOperator(char*p)//对字符[+,-,*,/,(,)]分类识别
switch(ch)
case'
Output(PLUS,p,p);
break;
Output(SUBTRACT,p,p);
Output(MULTIPLY,p,p);
Output(DIVIDE,p,p);
Output(LEFTBRACKET,p,p);
Output(RIGHTBRACKET,p,p);
default:
break;
AssortIdentify()//对字符分类识别
\t单词分析结果显示:
\n"
while(*p!
if(IsOperator(p))
IdentifyOperator(p++);
continue;
elseif(IsUnsignedNum(p)||*p=='
char*p1=p;
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
if(*p=='
{
Output(UNSIGNEDNUMBER,p1,--p);
continue;
}
elseif(*p=='
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
elseif(*p=='
||*p=='
else
Output(INEFFICACIOUSLABEL,p1,--p);
while(IsUnsignedNum(p))
if(*p=='
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
continue;
}
elseif(*p=='
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
Output(UNSIGNEDNUMBER,p1,--p);
continue;
}
else
Output(INEFFICACIOUSLABEL,p1,--p);
else
Output(INEFFICACIOUSLABEL,p1,--p);
else
}
if(*p=='
p++;
if(IsUnsignedNum(p))
else
else
Output(INEFFICACIOUSLABEL,p1,--p);
elseif(*p=='
Output(INEFFICACIOUSLABEL,p,p);
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<
fstream>
stdlib.h>
string>
usingnamespacestd;
structcode_val
charcode;
constchar*p[]=
{//产生式
"
→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;
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)
Acc"
else{cout<
err"
}while
(1);
intcol(charc)//将字符+*()i#ETF分别转换为数字012345678
{
for(inti=0;
(int)strlen(TNT);
if(c==TNT[i])returni;
Errincolchar>
c<
exit(0);
//终止程序运行
四、实验感想
SLR
(1)文法有效地消除了规约和移进之间的冲突,在程序中设了两个堆栈,一个状态栈,一个符号栈。
根据LR分析表构造了一个ACTION和GOTO矩阵,再用循环的方式把堆栈中的内容显示出来。
实验三语义分析程序实现
通过设计、编制、调试一个简单的语义处理分析程序,实现对实验一和实验二所得单词和语句的语义信息简单处里,进一步掌握语义处理的内容和简单方法。
对实验一进行扩展,对识别的无符号数进行计值,并将输出形式改为(类别码,值)的二元式形式。
对实验二进行扩展,在语法分析的基础上,增加语义操作来实现语法制导翻译。
对于给定文法中的每一产生式,编写相应的语义子程序。
在语法分析过程中,每当用一产生式进行推导或归约时,语法分析程序除执行相应的语法分析动作之外,还要调用相应的语义子程序,计算并输出算术表达式的值。
将实验一与实验二的程序合并,以能对完整的输入源文件进行词法分析生成中间文件,然后进行语法制导翻译,输出最终翻译结果。
由无符号数和+,—,*,/,(,)构成的算术表达式。
如果输入单词串是合法的无符号数的算术四则运算,输出运算结果,并且给出每一步的分析过程;
如果不是无符号数的算术四则运算,输出“非法四则运算表达式”。
三、基本实验题目
对实验一中每个无符号数识别状态插入计值处理,最终获得无符号数的取值。
对实验二进行扩展,在归约(分析表中的归约动作已经反应了运算优先级)处理子程序中加入计值处理,接受子程序中加入输出算数表达式值的处理。
cmath>
#defineEndState-1
charACTION[16][8]=
{'
s'
'
e'
},{'
a'
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