词法分析程序设计问题
由于才刚刚接触这个问题,感到十分棘手,请朋友们帮我弄一个程序代码.先谢谢.这里把问题描述一下:
实验目的:
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
期待回复.
问题点数:100、回复次数:12Top
1 楼ykzhujiang(朱朱)回复于 2006-03-13 21:41:14 得分 0
楼主应该先对编译原理的理论了解一下,推荐一本比较好的书籍--龙书
然后可以参考一些开源的的编译器项目,去sourceforge上面看一下
对于词法分析来说Lex,和Jlex之类的都不错Top
2 楼llf_hust()回复于 2006-03-13 21:42:17 得分 40
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#define N 50
#define M 500
char *a[32]={"auto","break","case","char","const","continue","default","do",
"double","else","enum","extern","float","for","goto","if",
"int","long","register","return","short","signed","sizeof","static",
"struct","switch","typedef","union","unsigned","void","while","volatile"};
char *b[13]={"&&","||","++","--","+","-","*","/","=",">=","<=","==","!="};
char *c[10]={"[","]","{","}","(",")",",",";","'"};
char scmp(char *str) /*此函数判断单词类型*/
{
int i;
for(i=0;i<32;i++)
{
if(strcmp(str,a[i])==0)
return '1';
}
if(isdigit(str[0]))
return '3';
for(i=0;i<13;i++)
{
if(strcmp(str,b[i])==0)
return '4';
}
for(i=0;i<10;i++)
{
if(strcmp(str,c[i])==0)
return '5';
}
if(!isalnum(str[0]))
return '5';
else return '2';
}
void main(void)
{
FILE *in,*out,*fp;
char ch,cha,buffer[N],*zhou[M];
int i=0,j=0,k;
if((in=fopen("source.txt","r+"))==NULL)
{
printf("source.txt can't open or doesn't exist...\n");
getch();exit(0);
}
if((out=fopen("output.txt","w+"))==NULL)
{
printf("output file can not open...\n");
getch();exit(0);
}
/**************************以下是核心代码区**************************/
while(!feof(in))
{
ch=fgetc(in);
if(isalpha(ch)) /*如果首字符是字母*/
{
while(isalnum(ch)&&(i<N))
{
buffer[i++]=ch;
ch=fgetc(in);
}
if(i>=N)
{
printf("the string is too long...\n");
getch();exit(0);
}
buffer[i]='\0';
zhou[j++]=(char *)malloc(sizeof(char)*(strlen(buffer)+1));
strcpy(zhou[j-1],buffer);
i=0;
fseek(in,-1L,1);
}
else if(isdigit(ch)) /*如果首字符是数字*/
{
while(isdigit(ch)&&(i<N))
{
buffer[i++]=ch;
ch=fgetc(in);
}
if(i>=N)
{
printf("the digit is too long...\n");
getch();exit(0);
}
buffer[i]='\0';
zhou[j++]=(char *)malloc(sizeof(char)*(strlen(buffer)+1));
strcpy(zhou[j-1],buffer);
i=0;
fseek(in,-1L,1);
}
else if(!isalnum(ch)) /*如果首字符既不是数字也不是字母的话*/
{
if(ch!='\n'&&ch!=' ')
{
if(ch=='>'||ch=='<'||ch=='!') /* 以下代码实现超前搜索 */
{
if((cha=fgetc(in))=='=')
{
buffer[i++]=ch;
buffer[i++]=cha;buffer[i]='\0';
zhou[j++]=(char *)malloc(sizeof(char)*3);
strcpy(zhou[j-1],buffer);
i=0;
}
else
{
buffer[i++]=ch;buffer[i]='\0';
zhou[j++]=(char *)malloc(sizeof(char)*2);
strcpy(zhou[j-1],buffer);
i=0;
fseek(in,-1L,1);
}
}
else if(ch=='+'||ch=='-'||ch=='&'||ch=='|'||ch=='=')
{
if((cha=fgetc(in))==ch)
{
buffer[i++]=ch;buffer[i++]=cha;buffer[i]='\0';
zhou[j++]=(char *)malloc(sizeof(char)*3);
strcpy(zhou[j-1],buffer);
i=0;
}
else
{
buffer[i++]=ch;buffer[i]='\0';
zhou[j++]=(char *)malloc(sizeof(char)*2);
strcpy(zhou[j-1],buffer);
i=0;
fseek(in,-1L,1);
}
}
else
{
buffer[i++]=ch;buffer[i]='\0';
zhou[j++]=(char *)malloc(sizeof(char)*2);
strcpy(zhou[j-1],buffer);
i=0;
}
}
}
}
/**************************以上是核心代码区**************************/
for(i=0;i<j-1;i++) /*输出到文件*/
{
puts(zhou[i]);
cha=scmp(zhou[i]);
fputc('(',out);
fputc(cha,out);
fputc(',',out);
fputs(zhou[i],out);
fputc(')',out);
fputc('\n',out);
}
getch();
return;
}
Top
3 楼jixingzhong(瞌睡虫·星辰)回复于 2006-03-13 22:02:58 得分 35
一个简单的词法分析程序:
其中包括两个文件 compiler.c 和 search.h ,把search.h放到include 文件夹里就行。
/********************compiler.c*************************************/
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include"search.h"
extern int reserve(char*);
extern void output(int,char*);
char token[20];
char ch;
int i,c;
void scanner(FILE *fp)
{
ch=fgetc(fp);
if(isalpha(ch))
{
token[0]=ch;
i=1;
ch=fgetc(fp);
while(isalpha(ch)||isalnum(ch))
{
token[i]=ch;
i++;
ch=fgetc(fp);
}
fseek(fp,-1,1);
token[i]='\0';
c=reserve(token);
if(c!=-1)
output(c,token);
else
output(10,token);
}
else if(isdigit(ch))
{
token[0]=ch;
ch=fgetc(fp);
i=1;
while(isdigit(ch))
{
token[i]=ch;
i++;
ch=fgetc(fp);
}
token[i]='\0';
fseek(fp,-1,1);
output(11,token);
}
else
switch(ch)
{
case'=':ch=fgetc(fp);
if(ch=='=')
output(39,"==");
else
{
fseek(fp,-1,1);
output(21,"=");
}
break;
case'+':output(22,"+");break;
case'-':output(23,"-");break;
case'*':output(24,"*");break;
case'/':output(25,"/");break;
case'(':output(26,"(");break;
case')':output(27,")");break;
case'[':output(28,"[");break;
case']':output(29,"]");break;
case'{':output(30,"{");break;
case'}':output(31,"}");break;
case',':output(32,",");break;
case':':output(33,":");break;
case';':output(34,";");break;
case'>':ch=fgetc(fp);
if(ch=='=')
output(37,">=");
else
{
fseek(fp,-1,1);
output(35,">");
}
break;
case'<':ch=fgetc(fp);
if(ch=='=')
output(38,"<=");
else
{
fseek(fp,-1,1);
output(36,"<");
}
break;
case'!':ch=fgetc(fp);
if(ch=='=')
output(40,"!=");
else
{
fseek(fp,-1,1);
output(-1,"ERROR!");
}
break;
}
}
void main()
{ FILE *fp;
char wenjian[30];
printf("Please input the file you want to transform:");
scanf("%s",&wenjian);
fp=fopen(wenjian,"r");
while(!feof(fp))
{
scanner(fp);
}
}
/**************************search.h*********************************/
extern struct table
{
int id;
char code[10];
};
struct table key[31] = {{1,"main"},{2,"int"},{3,"char"},{4,"if"},{5,"else"},{6,"for"},{7,"while"},{10,"ID"},{20,"NUM"},{-1,"ERROR"}};
int reserve(char* p)
{ int i=0;
for(i=0;i<9;i++)
{
if(strcmp(p,key[i].code)==0)
return(key[i].id);
}
return(-1);
}
void output(int t,char *s)
{
printf("[ %-2d , %-6s ]\n",t,s);
}
/*******************************************************************/Top
4 楼aniude(重返荣耀)回复于 2006-03-13 23:13:19 得分 0
MarkTop
5 楼xiaocai0001(高楼目尽欲黄昏/梧桐叶上萧萧雨)回复于 2006-03-14 08:16:37 得分 10
找一本编译原理的书, 然后看看后面附录的PL/0编译程序源代码.Top
6 楼xuelong_zl(点雨点[我身上咋就没MM的香水味涅??#-_-])回复于 2006-03-14 08:39:56 得分 0
哇,楼上的兄弟们太帅了......
程序一句没看懂....-_-#Top
7 楼xuelong_zl(点雨点[我身上咋就没MM的香水味涅??#-_-])回复于 2006-03-14 08:40:51 得分 0
错了,楼上的不全是兄弟,还有个师傅....-_-#Top
8 楼lonelyforest(一生所爱)回复于 2006-03-14 10:08:09 得分 15
不建议使用 fget, 这个不好, 老是一个个从文件中读取, 那有效率, 建议使用 getline函数,一次读取一行,也可以标记出错或者正确的行号, 这个是大多编译器采用的方式。看看《编译原理及实践》 这本书,后面附带一个,确实很不错,分析词法采用的是 条件状态机。 很容易扩充。如果还有兴趣,本人曾今写过一个, IDE 界面, 功能比较完善的词法分析器,可以共享。Top
9 楼windking21(想玩玩WOW 真的那么难吗)回复于 2006-03-14 10:14:37 得分 0
primer上面有个特别详细的例子Top
10 楼51365133(渊海)回复于 2006-03-14 10:18:16 得分 0
xuelong_zl(点雨点[好想村里的MM们............]) ( ) 信誉:100 2006-03-14 08:39:00 得分: 0
哇,楼上的兄弟们太帅了......
程序一句没看懂....-_-#
///////////////////////////////
我也是哦 -_-!!Top
11 楼sandrowjw(我的小猫照片给弄坏了,心都碎了)回复于 2006-03-14 15:21:45 得分 0
其实……用DFS不是挺好?Top
12 楼xiangqianxu(冰♂☆♂snow)回复于 2006-03-18 19:03:23 得分 0
谢谢楼上各位朋友的支持,我会努力的.谢谢大家.
Top




