问题描述:
用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表。如果产生词法错误,则显示错误信息、位置,并试图从错误中恢复。简单的恢复方法是忽略该字符(或单词)重新开始扫描。
相关词法规则
::=
::=
::=
::=
::=
::=
::=
::=a|b|c|……|x|y|z
::=0|1|2|3|4|5|6|7|8|9
::=+|-
::=*|/
::=|!=|>=|<=|==
::=,|;|(|)|{|}
::=main|int|if|else|while|do
编写词法分析程序的步骤:
(1)确定所要翻译的语言(或其子集)。
C语言
(2)设计属性字,及各类表格,如标识符表、常量表、符号及其机内表示对照表等。
与词法分析有关的表格:
1. 字符表
保留字:main,int,if,else,while,do
字母(全小写):a|b|c|……|x|y|z
数字:0,1,2,3,4,5,6,7,8,9
运算符和界符:,!=,>=,<=,==,,,;,(,),{,}
2. 特定单词机内表示表

3.画出总控流程图及各个子程序的流程图。

4. 程序
输入:一个存放C语言程序的s.txt文件
输出:存放以(单词,种别码)形式输出的result.txt文件
需要6个数组:
1. 存储关键字 key[6]
2. 存储对应下标关键字的种别码 keyNum[6]
3. 存储运算符和界符 symbol[17]
4. 存储运算符对应下标的种别码 symbolNum[17]
5. 存储从文件中取出的每个字符(不包括括号)letter[1000]
主要函数:
TakeWord();
功能:将文件letter[]中每个字符进行提取,找出关键字,输出种别码
Num作为全局变量保存提取到字符的哪个下标
1. 先提取一个字符,如果是字母,进入case1,调用identifier(),不断的提取字母或数字进行连接,没连接一个字符用int
isKeyWord()程序(返回关键字种别码)判断是否为关键字,是就退出函数返回string,不是就继续执行函数,直到连接的字符不再是字母或数字,即此时字符串为标识符
2. 如果是数字,进入case 2,调用Number()函数,不断进行字符串连接,知道下一个连接字符不再是数字
3. 如果是符号,进入case 3,调用symbolStr()函数,如果是=,>,
其他辅助函数:
int isSymbol()判断运算符和界符,并返回种别码
bool isNum() 判断是否为数字
bool isLetter()判断是否为字母
int isKeyWord()判断是否为关键字,是返回种别码
int typeword()返回单个字符的类型
string identifier()标识符的连接
string symbolStr()符号和界符的连接
string Number()数字的连接
void print()输出
#include #include#include#include
using namespacestd;//关键字
string key[6]={"main","int","if","else","while","do"};//关键字的种别码
int keyNum[6]={1,2,3,4,5,6};//运算符和界符
string symbol[17]={"","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","="};//char symbol[12]={‘‘,‘!=‘,‘>=‘,‘<=‘,‘==‘,‘,‘,‘;‘,‘(‘,‘)‘,‘{‘,‘}‘};//运算符和界符的种别码
int symbolNum[17]={7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};//存放文件取出的字符
string letter[1000];//将字符转换为单词
string words[1000];int length; //保存程序中字符的数目
intnum;int isSymbol(string s){ //判断运算符和界符
inti;for(i=0;i<17;i++){if(s==symbol[i])returnsymbolNum[i];
}return 0;
}//判断是否为数字
bool isNum(strings){if(s>="0" && s<="9")return true;return false;
}//判断是否为字母
bool isLetter(strings)
{if(s>="a" && s<="z")return true;return false;
}//判断是否为关键字,是返回种别码
int isKeyWord(strings){inti;for(i=0;i<6;i++){if(s==key[i])returnkeyNum[i];
}return 0;
}//返回单个字符的类型
int typeword(stringstr){if(str>="a" && str<="z") //字母
return 1;if(str>="0" && str<="9") //数字
return 2;if(str==">"||str=="="||str=="
||str=="+"||str=="-"||str=="*"||str=="/") //判断运算符和界符
return 3;
}string identifier(string s,intn){int j=n+1;int flag=1;while(flag){if(isNum(letter[j]) ||isLetter(letter[j])){
s=(s+letter[j]).c_str();if(isKeyWord(s)){
j++;
num=j;returns;
}
j++;
}else{
flag=0;
}
}
num=j;returns;
}string symbolStr(string s,intn){int j=n+1;string str=letter[j];if(str==">"||str=="="||str=="
s=(s+letter[j]).c_str();
j++;
}
num=j;returns;
}string Number(string s,intn){int j=n+1;int flag=1;while(flag){if(isNum(letter[j])){
s=(s+letter[j]).c_str();
j++;
}else{
flag=0;
}
}
num=j;returns;
}void print(string s,intn){
cout<
}void TakeWord(){ //取单词
intk;for(num=0;num
str=letter[num];
k=typeword(str);switch(k){case 1:
{
str1=identifier(str,num);if(isKeyWord(str1))
print(str1,isKeyWord(str1));elseprint(str1,0);break;
}case 2:
{
str1=Number(str,num);
print(str1,24);break;
}case 3:
{
str1=symbolStr(str,num);
print(str1,isSymbol(str1));break;
}
}
}
}intmain(){charw;inti,j;
freopen("s.txt","r",stdin);
freopen("result.txt","w",stdout); //从控制台输出,而不是文本输出
length=0;while(cin>>w){if(w!=‘ ‘){
letter[length]=w;
length++;
}//去掉程序中的空格
}
TakeWord();//for(j=0;j
fclose(stdin);//关闭文件
fclose(stdout);//关闭文件
return 0;
}





原文:https://www.cnblogs.com/lufeibin/p/10708317.html
这篇博客介绍如何使用C语言编写一个简单的词法分析程序,针对C语言小子集的源程序,根据预设的词法规则进行识别。程序包括关键字识别、数字和运算符的处理,并具备错误恢复功能。程序涉及的关键字、运算符和界符等词法规则被详细列出,以及词法分析的主要函数和辅助函数的实现。

3万+

被折叠的 条评论
为什么被折叠?



