#include <string>
using namespace std
string key[6] = {"begin", "if", "then", "while", "do", "end"}
//关键字
bool isKey( string str, int &syn) //判断是否为关键字,若是传虚雀回相
应关键码的种别名
{
int i
for(i=0i<6i++)
{
if(str == key[i])
{
syn = i + 1
return true
}
}
return false
}
bool isLetter(char c) //是否为字母
{
if((c >= 'A' &&c <= 'Z') || (c >= 'a' &&c <= 'z'))
return true
else
return false
}
bool isDigit(char c) //是否为数字
{
if(c >= '0' &&c <= '9')
return true
else
return false
}
void analyse(FILE *fileP)
{
int n
char c
string str = ""
while((c = fgetc(fileP)) != EOF)
{
if(c == ' ' || c == '\n' || c == '\t')
continue
else if(isDigit(c)) //数字
{
while(isDigit(c))
{
str += c
c = fgetc(fileP)
}
fseek(fileP, -1, SEEK_CUR)
cout <<"(11, " <<str <瞎誉嫌<")" <<endl
str = ""
}
else if(isLetter(c)) //字母开头的
{
while(isDigit(c) || isLetter(c))
{
str += c
c = fgetc(fileP)
}
fseek(fileP, -1, SEEK_CUR)
if(isKey(str, n))
cout <<"(" <<n <<", " <<str <<")" <<endl//关键码
else
cout <<"(10, " <<"\'"<<str <<"\'" <<")" <<endl//标志符
str = ""
}
else // *** 作符等
{
switch(c)
{
case '+':
cout <<"(13, +)" <<endl
break
case '-':
cout <<"(14, -)" <<endl
break
case '*':
cout <<"(15, *)" <<endl
break
case '/':
cout <<"(16, /)" <<endl
break
case ':':
{
if(c=fgetc(fileP) == '=')
cout <磨手<"(18, :=)" <<endl
else
{
cout <<"(17, :)" <<endl
fseek(fileP, -1, SEEK_CUR)
}
break
}
case '<':
{
c=fgetc(fileP)
if(c == '=')
cout <<"(22, <=)" <<endl
else if(c == '>')
cout <<"(21, <>)" <<endl
else
{
cout <<"(20, <)" <<endl
fseek(fileP, -1, SEEK_CUR)
}
break
}
case '>':
{
c=fgetc(fileP)
if(c == '=')
cout <<"(24, >=)" <<endl
else
{
cout <<"(23, >)" <<endl
fseek(fileP, -1, SEEK_CUR)
}
break
}
case '=':
cout <<"(25, =)" <<endl
break
case '':
cout <<"(26, )" <<endl
break
case '(':
cout <<"(27, ()" <<endl
break
case ')':
cout <<"(28, ))" <<endl
break
case '#':
cout <<"(0, #)" <<endl
break
}
}
}
}
int main()
{
FILE *fileP
fileP = fopen("test.txt", "r")
cout <<"------词法分析如下------" <<endl
analyse(fileP)
return 0
}
选我为最佳答案吧!南华大学
计算机科学与技术学院
实 验 报 告
( 2011~2012 学年度 第 二 学期 )
课程名称
程序设计语言与编译
姓名 学号
专业 电气信息类 班级
地点 8—209 教师
题目: 用直接分析方法编制C++语言子集的词法分析程序.
一、分析
对于单词符号我们将其分成四类:保留字K、标识符I、常数C和界符P,每类单词符号均可使用一张表格表示.在词法分析过程中,保留字K和界符P这两个表格的内容是固定不变袭脊的(由语言确定),源程序字符串只能从其中选取,而标识符I、常数C这两表是在分析过程中不断形成的.
对于一个具体源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是K、I、C或P中之一,那么就以单词的二元式形式输出.每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕,从而形成相应的单词串.
各类单词的二元式表述均具有相同的结构与长度,形式如下:
(单词种别t,单词自身的值i)
t是单词种别,而单词种别共分为K、I、C、P四类且每类对应一张表格.因此,t实际上就是一个指向这四类中某一类对应表格的指针.i则为指向该类表格中一个特定项目的指针.
所以整个的词法分析过程就是从源程序中获得一个个的单词符号,将这些符号分别填入四张类表中,并且有一个二元式序列构成一个索引,这个索引为以后的语法分析提供处理上的方便.
为了减少实习量,可以适量地选取K,P中的一个子集来进行.如下表:
表1 保留字K表
内部地址 1 2 3 4 5 6 7 8 9 10
保 留 字 BEGIN CONST DO ELSE END IF PROCEDURE THEN VAR WHILE
表2 界符P表
内部地址 1 2 3 4 5 6 7 8 9 10
界 符 ; + : : ( , ) < < <
组合界符 = = >
保留字表包括10个有代表性的保留字,界符表包括关系运算符三种(8,9,10),算术运算符(2),分隔符三种(1,4,6),一对圆括号,加上赋值号共10种.这两表的内容表明PASCAL语言的条件语句,赋值语句,WHILE型循环语句,复合语句,过程及变量说明均可作为源程序例子输入给词法分析程序,标识符表I中的每一项包含一个标识符,常数表C中的每一项包含一个整常数,后两表的内容都是在词法分析过程中产生的.
如何从源程序中识别出一个个的单词符号呢?图1中的流图清晰地反映出这一过程.
图1中,双圆圈的状态表示终态,即能到达终态就代表识别出一个单词符号,而带有*号的终态是指处理时应回退一字符.
二、算法
词法分析器在扫描过程中,依次从源程序中取出源字符,根据图1的扫描过程状态转换图,当碰到终态时,即双圆圈的状态时就得到一个单词符号,此时可以根据第一个字符判断单词属于K,I,C,P中哪一类,从而确定单词的"单词种别"和"单词自身的值".整个词法分析的算法流程如图2.
三、实现
选择实习环境为TURBO C2.0语言. 实现程序见附录.
四、总结
上机前应做好准备.即根据实习目的、要求和分析,选择相应的数据结构,使用C语言参照算法中的流程编写词法分析的程序.将编好的程序上机进行调试.注意调试的例子应有词法正确的,也应有词法错误的或是超出所选数据结构范围的.
实验完成达到实习目的之后,若尚有余力者,可以对所选子集适当扩大或是增加相应功能如:扩充界符和保留字数目;允许实型常数;进行词法错误检查;最大范围扩充以至PASCAL语言所有字符的集合.
实验完成以后编写出完整的实验报告,反映出最后的实验学习结果.
附录拍或渗
/* 实验代码:*/
实验结果:
五、结果感想
实验中需要识别的词有:
关键字:DIM、IF、DO、STOP、END单词种别码为1.2.3.4.5。
标识符;单词种别码为6。
常数为无符号整形数;单词种别码为7。
运算符包括:=、-、*、**单词种别码为8.9.10.11。
分隔符包括:,、(、); 单词种别码为12.13.14。
通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,根据识别语言单词的状态转换图,使用某种团漏高级语言(例如C++语言)直接编写此法分析程序。另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。
输入是字符串形式的源程序输出是属性字流
词法分析器的任务就是从左至右一次读字符串形式的源程序,按照源语言的词法规则闷搜识别蚂穗历具有独立意义的单词,并产生属性字流作为输族并出
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)