问题描述:

用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 <iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std; //关键字
string key[]={"main","int","if","else","while","do"};
//关键字的种别码
int keyNum[]={,,,,,};
//运算符和界符
string symbol[]={"<",">","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","="};
//char symbol[12]={'<','>','!=','>=','<=','==',',',';','(',')','{','}'};
//运算符和界符的种别码
int symbolNum[]={,,,,,,,,,,,,,,,,};
//存放文件取出的字符
string letter[];
//将字符转换为单词
string words[];
int length; //保存程序中字符的数目
int num; int isSymbol(string s){ //判断运算符和界符
int i;
for(i=;i<;i++){
if(s==symbol[i])
return symbolNum[i];
}
return ;
} //判断是否为数字
bool isNum(string s){
if(s>="" && s<="")
return true;
return false;
} //判断是否为字母
bool isLetter(string s)
{
if(s>="a" && s<="z")
return true;
return false;
} //判断是否为关键字,是返回种别码
int isKeyWord(string s){
int i;
for(i=;i<;i++){
if(s==key[i])
return keyNum[i];
}
return ;
} //返回单个字符的类型
int typeword(string str){
if(str>="a" && str<="z") // 字母
return ; if(str>="" && str<="") //数字
return ; if(str==">"||str=="="||str=="<"||str=="!"||str==","||str==";"||str=="("||str==")"||str=="{"||str=="}"
||str=="+"||str=="-"||str=="*"||str=="/") //判断运算符和界符
return ; } string identifier(string s,int n){
int j=n+;
int flag=; while(flag){
if(isNum(letter[j]) || isLetter(letter[j])){
s=(s+letter[j]).c_str();
if(isKeyWord(s)){
j++;
num=j;
return s;
}
j++;
}
else{
flag=;
}
} num=j;
return s;
} string symbolStr(string s,int n){
int j=n+;
string str=letter[j];
if(str==">"||str=="="||str=="<"||str=="!") {
s=(s+letter[j]).c_str();
j++;
}
num=j;
return s;
} string Number(string s,int n){
int j=n+;
int flag=; while(flag){
if(isNum(letter[j])){
s=(s+letter[j]).c_str();
j++;
}
else{
flag=;
}
} num=j;
return s;
} void print(string s,int n){
cout<<"("<<s<<","<<n<<")"<<endl;
} void TakeWord(){ //取单词
int k; for(num=;num<length;){
string str1,str;
str=letter[num];
k=typeword(str);
switch(k){
case :
{
str1=identifier(str,num);
if(isKeyWord(str1))
print(str1,isKeyWord(str1));
else
print(str1,);
break;
} case :
{
str1=Number(str,num);
print(str1,);
break;
} case :
{
str1=symbolStr(str,num);
print(str1,isSymbol(str1));
break;
} } }
} int main(){
char w;
int i,j; freopen("s.txt","r",stdin);
freopen("result.txt","w",stdout); //从控制台输出,而不是文本输出 length=;
while(cin>>w){
if(w!=' '){
letter[length]=w;
length++;
} //去掉程序中的空格
} TakeWord();
// for(j=0;j<length;j++){
// cout<<letter[j]<<endl;
// } fclose(stdin);//关闭文件
fclose(stdout);//关闭文件
return ;
}

用C语言编写一个简单的词法分析程序的更多相关文章

  1. 编写一个简单的C++程序

    编写一个简单的C++程序 每个C++程序都包含一个或多个函数(function),其中一个必须命名为main.操作系统通过调用main来运行C++程序.下面是一个非常简单的main函数,它什么也不干, ...

  2. Java入门篇(一)——如何编写一个简单的Java程序

    最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...

  3. 用 C 语言编写一个简单的垃圾回收器

    人们似乎觉得编写垃圾回收机制是非常难的,是一种仅仅有少数智者和Hans Boehm(et al)才干理解的高深魔法.我觉得编写垃圾回收最难的地方就是内存分配,这和阅读K&R所写的malloc例 ...

  4. 使用PyQt5编写一个简单的GUI程序(pyside 有 pyside-uic 把ui文件转成py文件,pyside-rcc 把qrc文件转成 py文件导入就行了)

    我做Python窗口界面编程时,经常使用PyQt进行设计.这里简单叙述一下使用PyQt5制作一个简单的图形界面的流程 PyQt的简介以及开发环境的搭建在此不多赘述. 1.       打开Qt Des ...

  5. socket实例C语言:一个简单的聊天程序

    我们老师让写一个简单的聊天软件,并且实现不同机子之间的通信,我用的是SOCKET编程.不废话多说了,先附上代码: 服务器端server.c #include <stdio.h> #incl ...

  6. 用SMIL语言编写一个简单的演示

    一.首先需要注意的几点是: 1.用记事本编写代码时,要保存为后缀名为.smil或.smi的文件,并且编码格式选择为UTF-8. 2.打开.smil文件的播放器选择为:RealPlayer或是Ambul ...

  7. C语言编写一个简单游戏

    感悟:这算是一个起点吧,我都大二了,还这么菜,才开始写游戏,这个游戏很简单,利用随机数猜大小! #include <stdlib.h> #include <stdio.h> # ...

  8. 编写一个简单的 JDBC 程序

    连接数据库的步骤: 1.注册驱动(只做一次) 2.建立连接(Connection) 3.创建执行SQL的语句(Statement) 4.执行语句 5.处理执行结果(ResultSet) 6.释放资源 ...

  9. [数据结构] 用C语言模拟一个简单的队列程序

    #include<stdio.h> #include <stdlib.h> #include<string.h> #include<math.h> // ...

随机推荐

  1. 级联Cascade

    cascade分为两类: 1.JPA标准 2.Hibernate标准 JPA的方法使用JPA规范 如@OneToMany(cascade=CascadeType.ALL,mappedBy=" ...

  2. Skyline TerraExplorer -二次开发- 加载外部数据的各种连接串

    Skyline 可以连接外部的数据源,包括SQL Server,Oracle ,excel,mySQL,SQlite,WFS....... 连接字符串如下:例如连接shp文件,为“FileName=C ...

  3. 如何解决button,a,input标签自带蓝色边框

    通常我们会设置该标签outline:0;但是我在使用iview自带的button组件的时候,设置无效,经过测试只要设置 :focus{      outline:0; }  即可,方便有效

  4. Spring 框架用到的 9 个设计模式汇总!

      1. 简单工厂 又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一. 简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类 ...

  5. MSMQ 队列消息和死信队列

    日志消息 日志队列可以保存你操作过的消息的备份.它的好处是,一但发现前面的操作失败,可以从日志队列中重新创建出原先的消息对象,然后再进行操作. 例如,向远方发送一个消息对象,然后对方返回一个失败的确认 ...

  6. linux查看tomcat启动运行日志

    1.先切换到:cd tomcat/logs 2.tail -f catalina.out 3.这样运行时就可以实时查看运行日志了

  7. CentOS 6.5 64位下安装Redis3.0.2的具体流程

    系统环境:CentOS 6.5 64位 安装方式:编译安装 防火墙:开启 Redis版本:Redis 3.0.2 一.环境准备 1.安装 gcc gcc-c++ [root@iZ94ebgv853Z ...

  8. Hadoop学习笔记记录

    NameNode的介绍: NameNode是HDFS的核心,也称为master,它仅存储元数据(文件系统中所有文件的目录树) NameNode不存储实际的数据或数据集,数据本身存储在DateNodes ...

  9. Reactive Programming

    Reactive的表现 Reactive 规范是 JVM Reactive 扩展规范 Reactive Streams JVM,而 Reactive 实现框架则是最典型的实现: Reactive St ...

  10. eclipse打包java项目

    参考链接:https://blog.csdn.net/heshushun/article/details/78039801