首页 > 其他 > 详细

词法分析程序的设计与实现

时间:2019-10-11 21:11:32      阅读:156      评论:0      收藏:0      [点我收藏+]

词法分析程序(Lexical Analyzer)要求:

- 从左至右扫描构成源程序的字符流

-  识别出有词法意义的单词(Lexemes

-  返回单词记录(单词类别,单词本身)

-  滤掉空格

-  跳过注释

-  发现词法错误

 

程序结构:

输入:字符流(什么输入方式,什么数据结构保存)

处理:

–遍历(什么遍历方式)

–词法规则

输出:单词流(什么输出形式)

–二元组

 

单词类别:

1.标识符(10)

2.无符号数(11)

3.保留字(一词一码)

4.运算符(一词一码)

5.界符(一词一码)

 

单词符号

种别码

单词符号

种别码

begin

1

:

17

if

2

:=

18

then

3

<

20

while

4

<=

21

do

5

<>

22

end

6

>

23

l(l|d)*

10

>=

24

dd*

11

=

25

+

13

;

26

-

14

(

27

*

15

)

28

/

16

#

0

 

 

#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE 50
int i, row = 0, line = 0;
char a[1000]; //程序
int number[1000][100]; //常数表
char mark[100][5]; //标识符表
char file,file1;
FILE fp,fwp;
//词法分析
int wordanalysis()
{
if ((a[i] >= ‘A‘&&a[i] <= ‘Z‘)||(a[i]>=‘a‘&&a[i]<=‘z‘))
{
char word[10];
char pro[100][100] = {"char","int","if","else","return","break","do","while","for","double","float","short"};
int n = 0;
word[n++] = a[i++];
//若字符为AZ或09,则继续读取
while ((a[i] >= ‘A‘&&a[i] <= ‘Z‘) || (a[i] >= ‘0‘ && a[i] <= ‘9‘)||(a[i]>=‘a‘&&a[i]<=‘z‘))
{
word[n++] = a[i++];
}
word[n] =‘\0‘;
//i-;
//判断该标识符是否为保留字
for (n = 0; n < 100; n++)
{
if (strcmp(word, pro[n]) == 0)
{
printf("( %d,%s) 关键字\n", n + 1,pro[n]);
fprintf(fwp,"( %d,%s) 关键字\n", n + 1,pro[n);
return 3;
}
}
//判断标识符长度是否超出规定
if (strlen(word)>10)
{
printf("%s\tERROR\n",word);
fprintf(fwp,"%s\tERROR\n",word );
return 3;
}
//判断该标识符是否存在标识符表中
int m = 0;
if (line != 0)
{
int q = 0;
while (q<line)
{
if (strcmp(word, mark[q++]) == 0)
{
printf("( %d,%s) 标识符\n", q,word);
fprintf(fwp,"( %d,%s) 标识符\n", q,word);
return 3;
}
}
}
//将该标识符保存到标识符表中
strcpy(mark[line], word);
printf("( %d,%s ) 标识符\n", line + 1,word);
fprintf(fwp,"( %d,%s ) 标识符\n", line + 1,word);
line++;
return 3;
}
//判断该标识符是否存在标识符表中
else if (a[i] >= ‘0‘ && a[i] <= ‘9‘) //分析常数
{
char x[100];
int n = 0, sum;
x[n++] = a[i++];
//判断字符是否是0~9
while (a[i] >= ‘0‘ && a[i] <= ‘9‘)
{
x[n++] = a[i++];
}
x[n] = ‘\0‘;
i-;
int num = atoi(x); //将字符串转换成int型
//判断该常数是否存在于常数表中
if (row != 0)
{
int y;
for (y = 0; y < 1000; y++)
{
int w = number[y][0];
sum = 0;
int d;
for (d = 1; d <= number[y][0]; d++)
{
w = w - 1;
sum = sum + number[y][d] * pow(2, w);
}
if (num == sum)
{
printf("( %d,%d ) 数字\n", y + 1,num);
fprintf(fwp,"( %d,%d ) 数字\n", y + 1,num);
return 3;
}
}
}
int z = num, c = num;
int m = 0;
do //计算是几位二进制数
{
z = z / 2;
m++;
} while (z != 0);
for (n = m; n > 0; n-) //将二进制保存于常数表中
{
number[row][n] = c % 2;
c = c / 2;
}
number[row][0] = m;
int line = row;
printf("( %d,%d ) 数字\n", line + 1,num);
fprintf(fwp,"( %d,%d ) 数字\n", line + 1,num);
row++;
return 3;
}
else //分析符号
switch (a[i])
{
case ‘ ‘:
case ‘\n‘:return -1;
case ‘#‘: return 0;
case ‘=‘:printf("( 14,= ) 运算符\n"); fprintf(fwp,"( 14,= ) 运算符\n");return 3;
case ‘<‘:
i++;
if (a[i] == ‘=‘)
{
printf("( 16,<= ) 运算符\n"); fprintf(fwp,"( 16,<= ) 运算符\n");return 3;
}
else if (a[i] == ‘>‘)
{
printf("( 19,<> ) 界符\n"); fprintf(fwp,"( 19,<> ) 界符\n");return 3;
}
else
{
i-;
printf("( 15,< ) 运算符\n"); fprintf(fwp,"( 15,< ) 运算符\n"); return 3;
}
case ‘>‘:
i++;
if (a[i] == ‘=‘)
{
printf("( 18,>= ) 运算符\n"); fprintf(fwp,"( 18,>= ) 运算符\n"); return 3;
}
else
{
i-;
printf("( 17,> ) 运算符\n"); fprintf(fwp,"( 17,> ) 运算符\n"); return 3;
}
case ‘+‘: printf("( 20,+ ) 运算符\n"); fprintf(fwp,"( 20,+ ) 运算符\n"); return 3;
case ‘-‘: printf("( 21,- ) 运算符\n");fprintf(fwp,"( 21,- ) 运算符\n"); return 3;
case ‘ ‘: printf("( 22, ) 运算符\n"); fprintf(fwp,"( 21, ) 运算符\n"); return 3;
case ‘/‘:
i++;
if(a[i]!=‘/‘){
i-;
printf("( 23,/ ) 运算符\n");fprintf(fwp,"( 23,/ ) 运算符\n"); return 3;
}
else{
while(1){
if(a[i++]==‘\n‘)
return -1;
}
printf("( 35,// ) 界符\n");fprintf(fwp,"( 35,// ) 界符\n");return 3;
}
case ‘:‘: printf("( 24,: ) 界符\n");fprintf(fwp,"( 24,: ) 界符\n"); return 3;
case ‘;‘: printf("( 25,; ) 界符\n");fprintf(fwp,"( 25,; ) 界符\n"); return 3;
case ‘(‘: printf("( 26,( ) 界符\n");fprintf(fwp,"( 26,( ) 界符\n"); return 3;
case ‘)‘: printf("( 27,) ) 界符\n");fprintf(fwp,"( 27,) ) 界符\n"); return 3;
case ‘{‘: printf("( 28,{ ) 界符\n");fprintf(fwp,"( 28,{ ) 界符\n"); return 3;
case ‘}‘: printf("( 29,} ) 界符\n");fprintf(fwp,"( 29,} ) 界符\n"); return 3;
case ‘[‘: printf("( 30,[ ) 界符\n");fprintf(fwp,"( 30,[ ) 界符\n"); return 3;
case ‘]‘: printf("( 31,] ) 界符\n");fprintf(fwp,"( 31,] ) 界符\n"); return 3;
case ‘|‘: printf("( 32,| ) 运算符\n");fprintf(fwp,"( 32,| ) 运算符\n"); return 3;
case ‘!‘: printf("( 33,! ) 界符\n");fprintf(fwp,"( 33,! ) 界符\n"); return 3;
case ‘,‘: printf("( 34, ) 界符\n");fprintf(fwp,"( 34, ) 界符\n"); return 3;
case ‘~‘: printf("( 35,~ ) 运算符\n");fprintf(fwp,"( 35,~ ) 运算符\n"); return 3;
case ‘&‘:
i++;
if(a[i]!=‘&‘){
i-;
printf("( 37,& ) 运算符\n");fprintf(fwp,"( 37,& ) 运算符\n"); return 3;
}
else{
printf("( 38,&& ) 运算符\n");fprintf(fwp,"( 38,&& ) 运算符\n"); return 3;
}
//case ‘\‘: printf("( 39,\ ) 界符\n");fprintf(fwp,"( 39,\ ) 界符\n"); return 3;
}
fclose(fwp);
}
int main()
{
int l = 0;
int m;
i = 0;
file=(char)malloc(sizeof(char)MAXSIZE);
file1=(char)malloc(sizeof(char)MAXSIZE);
printf(" 词法分析器*\n");
printf("请输入要进行词法分析的文件名(含路径):");
gets(file);
if(!(fp=fopen(file,"r")))
{
puts("打开文件失败!\n");
printf("请重新输入要进行词法分析的文件名(含路径):");
gets(file);
}
else
{
printf("成功打开文件%s!\n",file);
}
printf("请输入词法分析结果要存放的文件名(含路径):");
gets(file1);
if(!(fwp=fopen(file1,"w")))
{
printf("该文件不存在!\n");
}
else {
fwp = fopen(file1,"w");//打开文档,写入
while (!feof(fp))//检测流上的文件结束符,文件结束,返回非0值,否则返回0
{
a[l++] = fgetc(fp);
}
a[l] = ‘#‘;
do
{
m = wordanalysis();
switch (m)
{
case -1:i++; break;
case 0: i++; break;
case 3: i++; break;
}
} while (m != 0);
}
return 0;
}

 

转自http://www.pianshen.com/article/9571146300/

太难了

 

词法分析程序的设计与实现

原文:https://www.cnblogs.com/hjqq/p/11656681.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!