当前位置:文档之家› 编译原理实验报告

编译原理实验报告

int IsUnsignedNum(char *p);//判断字符是否是0--9的整数
void AbnormityExamine(char a[]);
void IdentifyOperator(char *p);//识别字符集[+,-,*,/,(,)]中的字符
void AssortIdentify();//对输入字符分类识别
char ch;
int i=0;
while((ch=cin.get())!='\n')
{
testStr[i]=ch;
i++;
}
AbnormityExamine(testStr);
}
void AccidenceAnalysis::AbnormityExamine(char a[])
{
int j=0;
char *ptr1,*ptr2;
{
*ptr1=*ptr2;
ptr1++;
ptr2++;
}
}
while(ptr1<=ptr2)
{
*ptr1='\0';
ptr1++;
}
}
void AccidenceAnalysis::Output(int a,char *p1,char *p2)
{
cout<<"\t类别码:"<<a<<"单词值:";
while(p1<=p2)
{
char ch=*p;
if(IsOperator(p)||IsUnsignedNum(p)||ch=='E'||ch=='.')
return 1;
else return 0;
}
void AccidenceAnalysis::IdentifyOperator(char *p)
{
char ch=*p;
{
p++;
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
}
else if(*p=='.')
{
p++;
while(IsUnsignedNum(p))
p++;
if(*p=='\0')
{
Output(UNSIGNEDNUMBER,p1,--p);
ptr1=a;
ptr2=a;
while(*ptr2!='\0')
{
j++;
if(!IsAcceptantCharacter(ptr2))
{
cout<<"\t您输入的第"<<j<<"个字符"<<*ptr2<<"不可以被此程序识别!"\
<<"将被跳过."<<endl;
ptr2++;
continue;
}
else
p++;
continue;
}
else if(*p=='E')
{
p++;
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
else if(*p=='+'||*p=='-')
{
p++;
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
}
else
};
AccidenceAnalysis::AccidenceAnalysis()
{
int i;
for(i=0;i<M;i++)
testStr[i]=ቤተ መጻሕፍቲ ባይዱ\0';
p=&testStr[0]; //指针P指向字符数组首元素
}
void AccidenceAnalysis::InputStr()
{
cout<<"\t请按要求输入您要分析的语句,所输字符应在要求范围(不超过"<<M<<")之内,并按回车键运行:";
单词符号
类别编码
类别码的助记符
单词值
begin
1
BEGIN
end
2
END
if
3
IF
then
4
THEN
else
5
ELSE
标识符
6
ID
字母打头的字母数字串
整常数
7
INT
数字串
<
8
LT
<=
9
LE
=
10
EQ
<>
11
NE
>
12
GT
>=
13
GE
:=
14
IS
+
15
PL
-
16
MI
*
17
MU
/
18
DI
处理过程:在此为了使词法分析程序结构比较清晰,且尽量避免某些枝节问题的纠缠,假定要编译的语言中,全部关键字都是保留字,程序员不得将它们作为源程序中的标识符;在源程序的输入文本中,关键字、标识符、整常数之间,若未出现关系和算术运算符以及赋值符,则至少须用一个空白字符加以分隔。作了这些限制以后,就可以把关键字和标识符的识别统一进行处理。即每当开始识别一个单词时,若扫视到的第一个字符为字母,则把后续输入的字母或数字字符依次进行拼接,直至扫视到非字母、数字字符为止,以期获得一个尽可能长的字母数字字符串,然后以此字符串查所谓保留字表(此保留字表已事先造好),若查到此字符串,则取出相应的类别码;反之,则表明该字符串应为一标识符。采用上述策略后,针对表2中部分单词可以构造一个如图2所示的有限自动机(以状态转换图表示)。在图2中添加了当进行状态转移时,词法分析程序应执行的语义动作。根据图2,可用C语言编写出符合以上几项要求的一个相应的扫描器程序,如程序一所示。
#define DIVIDE 5//除号
#define LEFTBRACKET 6//左括号
#define RIGHTBRACKET 7//右括号
class AccidenceAnalysis //定义词法分析器类
{
private:
char testStr[M],*p;//私有数据
public:
AccidenceAnalysis();//构造函数
图2识别表I所列语言中的部分单词的DFA及相关函数
图2所出现的变量及函数的含义和功能说明如下:
函数GETCHAR:每调用一次,就把扫描指示器当前所指示的源程序字符送入字符变量ch,然后把扫描指示器前推一个字符位置。
字符数组TOKEN:用来依次存放一个单词词文中的各个字符。
函数CAT:每调用一次,就把当前ch中的字符拼接于TOKEN中所存字符串的右边。
四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢线至一个新的终态即可。根据自己的习惯,也可以将其转换为状态矩阵形式。
2、词法分析程序编写
根据描述语言中各类单词的文法状态转换图或状态矩阵,利用某种语言(C语言或JAVA语言)直接编写词法分析程序。
3、词法分析程序测试
用于测试扫描器的实例源文件中应有词法正确的,也应有错误的字符串,对于输入的测试用例的源程序文件,以对照的形式将扫描器的分析结果信息在输出文件中表示出来。
{
cout<<*p1;
p1++;
}
cout<<endl;
}
int AccidenceAnalysis::IsOperator(char *p)
{
char ch=*p;
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')')
return 1;
else
p++;
continue;
}
else if(*p=='E')
{
p++;
if(IsUnsignedNum(p))
{
while(IsUnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
p++;
continue;
}
else if(*p=='+'||*p=='-')
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
三、实现方法与环境
1、首先设计识别各类单词的状态转换图。
描述无符号常数的确定、最小化状态转换图如图1所示。其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>,1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。
相关主题