# 词法分析之基于文法的实现
# 一、设计目的
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
# 二、设计要求
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。 并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
# 三、设计说明
## 3.1 需求分析:
### 3.1.1 输入及其范围
- 识别保留字:IF、THEN、ELSE、GOTO等,保留字类别码为K
- 其他的都识别为标识符;单词类别码为I
- 常数为无符号整形数;单词类别码为C
- 运算符包括:+、-、\*、/、=、>、<、>=、<=、!= ;类别码为O
- 界符符包括:,、;、{、}、(、); 类别码为P
- 结束标号L
### 3.1.2 输出形式
预处理文件和二元式表txt输出文件和控制台输出。
### 3.1.3 程序功能
词法分析器的功能是输入源程序,输出单词符号二元式。
### 3.1.4 测试数据
测试输入的程序为:
```c++
b=100;
101:a=2*(1+3);
IF(b>10)
THEN a=1;
ELSE IF(b>=5)
THEN a=2;
ELSE GOTO 101#
```
## 3.2 概要设计
### 3.2.1 数据类型的定义
```c++
FILE *fp;
FILE *out, *in;
char ch;
char filename[50];
char *keyword[4] = { "IF", "THEN", "ELSE", "GOTO" };
char *operatornum[4] = { "+", "-", "*", "/" };
char *comparison[6] = { ">", "<", ">=", "<=", "=", "<>" };
char *interpunction[5] = { ",", ":", "(", ")" ,";"};
int x = -1, y = -1, z = -1;
char K[Klen][10], P[Plen][2], I[Ilen][20], O[Olen][2];
int C[Clen], L[Llen];
```
### 3.2.2 主程序流程
![](http://www.writebug.com/myres/static/uploads/2021/10/19/5f929e8a5b97e048be7e8f5e952d4ce5.writebug)
### 3.2.3 模块间调用关系
![](http://www.writebug.com/myres/static/uploads/2021/10/19/98c00082c5c5df7717ef8c61cf0b7bf9.writebug)
## 3.3 详细设计
```c++
//处理字母,可能是标识符或者变量
char letterprocess( char ch )
{
int i = -1, j = -1, k, a = 1;
char letter[10], temp[10];
while ( isalnum( ch ) != 0 )
{
letter[++i] = ch;
ch = fgetc( fp );
}
letter[i + 1] = '\0';
if ( search( letter, 1 ) )
{
printf( "(K,%5s)\n", letter );
fprintf( out, "(K,%s)\n", letter );
if ( strcmp( letter, "GOTO" ) == 0 )
{
ch = fgetc( fp );
while ( isdigit( ch ) != 0 )
{
temp[++j] = ch;
ch = fgetc( fp );
}
temp[j + 1] = '\0';
printf( "(L,%5s)\n", temp );
fprintf( out, "(L,%s)\n", temp );
L[++y] = atoi( temp );
}
}
else
{
printf( "(I,%5s)\n", letter );
fprintf( out, "(I,%s)\n", letter );
for ( k = 0; k < 10; k++ )
{
if ( strcmp( letter, I[k] ) == 0 )
a = 0;
}
if ( a == 1 )
strcpy( I[++x], letter );
}
return(ch);
}
// 处理数字
char numberprocess( char ch )
{
int i = -1, n, temp, a = 1;
char num[20];
while ( isdigit( ch ) != 0 )
{
num[++i] = ch;
ch = fgetc( fp );
}
if ( isalpha( ch ) != 0 )
{
while ( isalpha( ch ) != 0 )
{
num[++i] = ch;
ch = fgetc( fp );
}
num[i + 1] = '\0';
printf( "非法标识符: %s\n", num );
fprintf( out, "非法标识符: %s\n", num );
}
if ( ch == ':' )
{
num[i + 1] = '\0';
printf( "(L,%5s)\n", num );
fprintf( out, "(L,%s)\n", num );
L[++y] = atoi( num );
}
else
{
num[i + 1] = '\0';
printf( "(C,%5s)\n", num );
fprintf( out, "(C,%s)\n", num );
temp = atoi( num );
for ( n = 0; n < 10; n++ )
{
if ( temp == C[n] )
a = 0;
}
if ( a == 1 )
C[++z] = temp;
}
return(ch);
}
// 处理其他情况
char otherprocess( char ch )
{
int i = -1;
char other[10];
if ( ch == '(' )
{
other[++i] = ch;
ch = fgetc( fp );
}
while ( isalnum( ch ) == 0 && ch != ' ' && ch != '(' && ch != ')' )
{
other[++i] = ch;
ch = fgetc( fp );
}
if ( ch == ')' )
{
other[++i] = ch;
ch = fgetc( fp );
}
other[i + 1] = '\0';
if ( search( other, 4 ) )
{
printf( "(P,%5s)\n", other );
fprintf( out, "(P,%s)\n", other );
}
else if ( search( other, 2 ) || search( other, 3 ) )
{
printf( "(O,%5s)\n", other );
fprintf( out, "(O,%s)\n", other );
}
else
{
printf( "非法字符: %s\n", other );
fprintf( out, "非法字符: %s\n", other );
}
return(ch);
}
```
# 四、运行结果及分析
## 4.1 测试数据
测试数据为test.txt文件内的数据:
![](http://www.writebug.com/myres/static/uploads/2021/10/19/ba0090149add462a60a98621d3cedd9e.writebug)
## 4.2 测试输出的结果
![](http://www.writebug.com/myres/static/uploads/2021/10/19/4575922cf30c944f7881a948f0b92951.writebug)
![](http://www.writebug.com/myres/static/uploads/2021/10/19/bd5de6b70820fdf57cf3487dc48f11c8.writebug)
## 4.3 设计和思考
本程序的设计是基于C实现的词法分析程序,对整个程序分模块进行开发,并对源程序预处理和最终结果分别在控制台和输出文件中输出,整个程序的思路就是依据编译原理的理论知识,但是实际使用技术都是C最基本的字符串解析和处理方法,很久没用C编程,也在这次实验中好好复习了C的语法。
# 五、总结
经过努力,终于完成了本次实验,在实验中遇到了诸多问题,经常发生空指针,数组越界等很基础的错误,不过经过不断地调试,逐渐把整个程序运行起来,也通过这次实验,对书本的理论知识,词法分析流程和方法有了较为深入的了解。
精选_毕业设计_词法分析之基于文法的实现_完整源码
版权申诉
8 浏览量
2022-03-05
17:47:07
上传
评论
收藏 566KB ZIP 举报
工具盒子
- 粉丝: 61
- 资源: 1313