实验目的:
1、通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
2、编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。
实验要求
要求用C++Builder或者Dephi或者VB或者VC或者Jbuilder等可视化编程工具编写;要求有界面(即一般windows下应用程序界面)。
实验原理及思想
1、定义部分:定义常量、变量、数据结构。
2、初始化:从文件将源程序输入到字符缓冲区中。
3、取单词前:去掉多余空白。
4、提取字符组成单词,利用课本P90图4.5转换图构造单词扫描过程
5、判断单词的种别码
6、显示(导出)结果。
识别保留字:if、int、for、while、do、return、break、continue等等;单词种别码为1。
其他的都识别为标识符;单词种别码为2。
常数为无符号数;单词种别码为3。
运算符包括:+、-、*、/、=、>、<等;可以考虑更复杂情况>=、<=、!= ;单词种别码为4。
分隔符包括: “,”“;”“(”“)”“{”“}”等; 单词种别码为5。
源文件中的关键字、分界符、操作符
String[]key={"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register","return","short","signed","static","struct","switch","typedef","union","unsigned","void","volatile","while"};
String[]delimiter={"(",")","[","]",",",";","{","}","#"}; //分界符
String[]operation1={"*","%","&","+","-","<","=",">","!","|"};//操作符
String[]operation2={"++","--","&&","==","!=","||","<=",">=","<<",">>"};判断标识符模块:
private char isIdentifier(char ch)
{
int flag=1;
String str="";
str+=ch;
count++;
ch=allchar.charAt(count); //从源程序文本区域读取字符
while(Character.isLetter(ch)||Character.isDigit(ch)||ch=='_')//标识符开始符号判别
{
str+=ch;
count++;
ch=allchar.charAt(count);
}
for(int j=0;j<key.length;j++) / /与已知的关键字进行匹配
{
if(key[j].compareTo(str)==0)
{
flag=1; //表示判断结果为关键字退出
break;
}
else
flag=0; //判断结果为其他标识符
}
if(flag==0)
result.append(str+"\t标识符\n");
else
result.append(str+"\t保留字\n");
return ch;
}
判断为常数(包括浮点数的判断)模块
private char isDigit(char ch)
{
String str="";
str+=ch;
count++;
ch=allchar.charAt(count);
while(Character.isDigit(ch))
{
str+=ch;
count++;
h=allchar.charAt(count);
}
if (ch=='.')//出现非数字且为点时
{
str+=ch; //将点加入
count++;
ch=allchar.charAt(count);//读入下一个字符
if (Character.isDigit(ch))
{
while(Character.isDigit(ch)) //是数字时,收入,并将加一
{
str+=ch; //将点加入
count++;
ch=allchar.charAt(count);
}
if(Character.isDigit(ch))//如果是数字加点再加数字再出现字母,就是错误
{
while(Character.isDigit(ch)||Character.isLetter(ch)||ch=='.')
{
str+=ch;
count++;
ch=allchar.charAt(count);
}
result.append(str+"\t标示符错误\n");
}
else
result.append(str+"\t浮点数\n");
}
}
else if(Character.isLetter(ch))//如果出现在数字后的是字符,则判断为标识错误
{
while(Character.isDigit(ch)||Character.isLetter(ch)||ch=='.')
{
str+=ch;
count++;
ch=allchar.charAt(count);
}
result.append(str+"\t标示符错误\n");
}
else//如果是单词段结束符时,就判断为常数
{
result.append(str+"\t整数\n");
}
return ch;
}
判断注释(包括//型注释和/**/型注释)模块
private char isComment(char ch)
{
String str="";
str+=ch;
count++;
ch=allchar.charAt(count);
if(ch=='/')//判断"//"型注释部分
{
while(ch!='\n'){
str+=ch;
count++;
ch=allchar.charAt(count);
}
}
else if(ch=='*')//判断/**/型注释{
str+=ch;
count++;
ch=allchar.charAt(count);
while(!(str.charAt(str.length()-1)=='*'&&ch=='/')){
str+=ch;
count++;
ch=allchar.charAt(count);
}
count++;
ch=allchar.charAt(count);
}
else//否则就是除法运算符
result.append(str+"\t除法运算符\n");//除法运算符
return ch;
}
判断运算符、分界符模块
private char isOther(char ch)
{
String str="";
str+=ch;
count++;
for(int j=0;j<delimiter.length;j++)//与已知分界符匹配
{
if(delimiter[j].compareTo(str)==0)
{
result.append(str+"\t分界符\n");
ch=allchar.charAt(count);
return ch;
}
}
for(int i=0;i<operation1.length;i++)//先与一个字符的操作符进行匹配
{
if(operation1[i].compareTo(str)==0)
{
ch=allchar.charAt(count);
for(int k=0;k<operation2.length;k++)
{
if(operation2[k].charAt(1)==ch)
{
str+=ch;
result.append(str+"\t运算符\n");//两个字符的操作符
count++;
ch=allchar.charAt(count);
return ch;
}
}
result.append(str+"\t运算符\n");//一个字符的操作符
return ch;
}
}
if(ch=='"')//字符串的判断
{
str+=ch;
ch=allchar.charAt(count);
while(ch!='"')
{
str+=ch;
count++;
ch=allchar.charAt(count);
}
if(ch=='"')
{
count++;
str+=ch;
result.append(str+"\t字符串\n");
}
else
{
result.append(str+"\t字符串错误\n");
}
}
ch=allchar.charAt(count);
return ch;
}