主题:急用~~C语言实现语法分析的功能
54875610
[专家分:20] 发布于 2005-10-09 21:52:00
哪位哥们能帮我弄个实验`。。来实现语法分析的功能 急用。。。
先谢谢了。。。知道的请留下你宝贵的意见~~~~~~
回复列表 (共11个回复)
沙发
liuanggh [专家分:0] 发布于 2005-10-10 22:14:00
//这是一个C++ 写的C语言词法分析器
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
FILE *f;
int line = 1;
struct ID{ char *name; int count;};
ID iD[100]; //用于存放ID号码
ID id[100];
int s = 1;
int I = 0;//用于记录ID存放的数量
int Number[100];// 用于存放数字
int P = 0;//用于记录存放数字的个数
int error[100] = {0};//用于记录错误的行数
int K = 0;//记录错误次数
void Error(); //记录错误
void loginID(char *);//注册ID
void loginNumber(int &);//放入数字
void noteLine(char &);//记录光标的行数
void print(); //输出部分
void Error()
{ error[K++] = line; }
void loginID(char *chr)
{
int i = 0;
while( i < I && !strcmp(chr,id[i].name))//检测是否已经注册
{i++;}
if( i == I )//新的ID注册
{
id[i].name = chr;
I++;
}
}
void loginNumber(int &nu)
{ Number[P++] = nu; }
void noteLine(char &ch)
{
if ( ch == '\n' )
++line;
}
void print()//////////////////////////输出部分
{
//cout << "关键字以及变量:" << endl;
//for(int i = 0; i < I; i++)
//cout << i <<" " << iD[i].name << " " << iD[i].count << endl;
//cout << "数字:" << endl;
//for(int i = 1; i <= P; i++)
//cout << i << ": " << Number[i-1] << endl;
if(error[0] != 0)
{
cout << "出现的错误!" << endl;
for(int i = 1; i <= K; i++)
cout << "第" << i << "个错误: " << "第" << error[i-1] << "行" << endl;
}
else
cout << "没有错误!" << endl;
}
//////////////////////////////文件处理部分
void noblank( char &ch)//跳过空格,回车
{
noteLine(ch);
while(ch == ' ' || ch == '\n')
ch = fgetc(f);
}
void identifier(char name[],char &ch)//字母变量
{
int i;
for(i = 0; i < 20; i++)
name[i] = ' ';
i = 0;
while (('0'<= ch && ch <= '9')||('a'<= ch&&ch <= 'z')||('A'<= ch&&ch <='Z'))
{
name[i] = ch;
i++;
ch = fgetc(f);
}
loginID(name);
//for(int j = 0; j < i; j++)
//{cout << name[j];}
// cout << ' ';
}
板凳
liuanggh [专家分:0] 发布于 2005-10-10 22:15:00
int number(char &ch)//数字
{
int num=0;
while('0'<= ch && ch <= '9')
{
num = num* 10 + (ch-'0');
ch = fgetc(f);
}
if( ('a'<= ch&&ch <= 'z')||('A'<= ch&&ch <='Z'))
{
Error();
}
else if( ch == '.')
{;}
loginNumber(num);
return num;
}
void test(char &ch)//符号
{
char str[2]={'0/'};
if(ch == '*')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '.')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ',')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '"')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '/')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '%')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '^')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '-')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '{')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '}')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '[')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ']')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ';')
{str[0] = ch; ch = fgetc(f);}
if(ch == ':')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '?')
{ str[0] = ch; ch = fgetc(f);}
if(ch == '(')
{ str[0] = ch; ch = fgetc(f);}
if(ch == ')')
{str[0] = ch; ch = fgetc(f);}
if(ch =='+')
{
str[0] = ch;
if((ch = fgetc(f)) == '+' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '-')
{
str[0] = ch;
if((ch = fgetc(f)) == '-' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '&')
{
str[0] = ch;
if((ch = fgetc(f)) == '&' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '|')
{
str[0] = ch;
if((ch = fgetc(f)) == '|' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '!')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
//cout << str[0]<< endl;
}
if(ch == '=')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
}
if(ch == '>')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
else
if(ch == '>' )
{
str[1] = ch;
ch = fgetc(f);
//cout << str[0] << str[1] << endl;
}
}
if(ch == '<')
{
str[0] = ch;
if((ch = fgetc(f)) == '=' )
{
str[1] = ch;
ch = fgetc(f);
}
else
if(ch == '<' )
{
str[1] = ch;
ch = fgetc(f);
}
}
}
3 楼
liuanggh [专家分:0] 发布于 2005-10-10 22:15:00
int main()
{
char ch;
char name[30];
f = fopen("c.txt","r");
if (f==NULL)
cout<<"no such file."<<endl;
ch = fgetc(f);
while(!feof(f))
{
noblank( ch );
if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{identifier(name,ch);}
if(ch >= '0'&& ch <= '9')
{number(ch);}
else
{test(ch);}
}
print();
fclose(f);
system("pause");
return 0;
}
4 楼
netbug818 [专家分:180] 发布于 2005-11-15 23:08:00
我编了个算符优先分析法的程序,不过现在不能公布代码,呵呵~~!
5 楼
zhgliet [专家分:140] 发布于 2005-12-20 21:16:00
大哥,看一下我的吧!
比较一下!
不过我没有完全。。。我的只是识别pascal的一小部分
不过很容易完善的.......
------------------------------------------------------------
#define BEGIN 1
#define END 2
#define IF 3
#define THEN 4
#define ELSE 5
#define ID 6
#define INT 7
#define LT 8
#define LE 9
#define EQ 10
#define NE 11
#define GT 12
#define GE 13
#define TOKEN_SIZE 64
#define TAB_SIZE 5
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
char TOKEN[TOKEN_SIZE];
extern int lookup(char *);
extern void out(int ,char*);
extern void report_error();
char ch;
//信息表
typedef struct{
int ad;
char id[6];
}info_ele;
info_ele info_tab[TAB_SIZE]={{1,"begin"},{2,"end"},{3,"if"},{4,"then"},{5,"else"}};
//扫描器函数
void scaner(FILE *fp)
{
int i,c_id;
ch=fgetc(fp);
if(isalpha(ch)){
TOKEN[0]=ch;
i=1;
ch=fgetc(fp);
while(isalnum(ch))
{TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
fseek(fp,-1,1);
TOKEN[i]='\0';
c_id=lookup(TOKEN);
if (c_id==0) out(ID,TOKEN);
else out(c_id,TOKEN);
}
else if(isdigit(ch)){
TOKEN[0]=ch;
i=1;
ch=fgetc(fp);
while(isdigit(ch))
{TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
fseek(fp,-1,1);
TOKEN[i]='\0';
out(INT,TOKEN);
}
else
if(ch==' ');//遇见空格继续
else switch(ch)
{
case '=':out(EQ,"=");
break;
case '>':ch=fgetc(fp);
if(ch=='=')out(GE,">=");
else{ fseek(fp,-1,1);
out(GT,">");
}
break;
case'<':ch=fgetc(fp);
if(ch=='=') out(LE,"<=");
else if(ch=='>')out(NE,"<>");
else{
fseek(fp,-1,1);
out(LT,"<");
}
break;
default: report_error();
break;
}
}
int lookup(char p[])
{
int i=0;
for(i;i<TAB_SIZE;i++)
{
if(!strcmp(info_tab[i].id,p))return (info_tab[i].ad);
}
return 0;
}
void out(int a,char *p)
{
switch(a){
case BEGIN: printf("(BEGIN,%s)",p);break;
case END : printf("(END,%s)",p); break;
case IF: printf("(IF,%s)",p);break;
case THEN: printf("(THEN,%s)",p);break;
case ELSE: printf("(ELSE,%s)",p);break;
case ID: printf("(ID,%s)",p);break;
case INT:printf("(INT,%s)",p);break;
case LT:printf("(LT,%s)",p);break;
case LE:printf("(LE,%s)",p);break;
case EQ:printf("(EQ,%s)",p);break;
case NE:printf("(NE,%s)",p);break;
case GT:printf("(GT,%s)",p);break;
case GE:printf("(GE,%s)",p);break;
default: break;
}
}
void report_error()
{
printf("\n有错误!\n");
exit(0);
}
6 楼
zhgliet [专家分:140] 发布于 2005-12-20 21:17:00
主函数如下:
#include<stdio.h>
#include<stdlib.h>
extern void scaner(FILE *);
void main()
{
extern char ch;
char fname[20];
FILE * fp;
printf("Enter file's name:");
scanf("%s",&fname);
if((fp=fopen(fname,"r"))==NULL)
{
printf("\nfile open error!\n");
exit(0);
}
do{scaner(fp);}while(ch!=EOF);
}
7 楼
zhgliet [专家分:140] 发布于 2005-12-20 21:23:00
感觉你的太复杂!
我的 自动机的思想/
8 楼
liuanggh [专家分:0] 发布于 2005-12-29 14:32:00
我用的也是自动机哦!
9 楼
一兮 [专家分:0] 发布于 2006-04-07 10:46:00
[em4]我借鉴了你的程序,我用while(fgetc(fp)!=EOF)
{scaner(fp);}
运行结果产生死循环呢!
10 楼
baby624779 [专家分:0] 发布于 2006-11-15 22:20:00
[em1]都挺厉害的,不过我用的是1楼同志的程序```易懂些``呵呵``,对了,你那可以该下哦,就是"void test(char &ch)//符号
{
char str[2]={'0','/'};
改成这样就没warning了```
我来回复