您的位置:首页 > 其它

编译原理(预测分析法)

2009-11-12 21:51 232 查看
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include<windows.h>

#define MAXSIZE 100

typedef struct //定义顺序栈

{

int data[MAXSIZE];

int top;//栈顶指针

}SeqStack;

SeqStack *s;//定义一个指向顺序栈的指针变量

void Scaner();//词法分析扫描函数

void abc(); //词法分析扫描函数

int IsRetainLetters(char *ch);//判断是否为保留字

char GetCh(FILE *fp);//读取文件中的字符,每次只读取一个字符

void Analyse();//LL1预测分析主程序

int digit;//数字变量

FILE *fpin;//用于操作输入文件

char ch = ' ';//用于存放字符

char temp[10];//用做中间变量存放字符

int main()

{

printf(" 编译正在进行....../n");

Analyse();

printf(" 执行结束!!/n");

return 0;

}

int Analyse_Table[10][30]=

{

{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0},

{ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,11, 0},

{ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0} ,

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

} ;//定义预测分析表

void Init_Stack()

{

s=new SeqStack;

if(!s)

{

printf("内存分配不足");

exit(1);

}

else

{

s->top=-1;

}

}

int Push(int x)

{

if(s->top==MAXSIZE-1)

{

printf("栈满,不能入栈!/n");

return 0;

}

else

{

s->top++;

s->data[s->top]=x;

return 1;

}

}

int Pop()

{

int x;

if(s->top==-1)

{

printf("栈空,不能出栈");

return 0;

}

else

{

x=s->data[s->top];

s->top--;

return x;

}

}

void Push_Stack(int a, int b)

{

switch(Analyse_Table[a][b])

{

case 1: Push(6); Push(101); Push(1); break;

case 2: break;

case 3: Push(102); Push(103); Push(26); break;

case 4: Push(105); Push(106); Push(13); break;

case 5: Push(105); Push(106); Push(14); break;

case 6: Push(107); Push(108); Push(15); break;

case 7: Push(107); Push(108); Push(16); break;

case 8: Push(102); Push(103); break;

case 9: Push(104); Push(18); Push(10); break;

case 10: Push(105); Push(106); break;

case 11: Push(107); Push(108); break;

case 12: Push(10); break;

case 13: Push(11); break;

}

}

int i,k;

void Scaner()//词法分析扫描函数

{

fpin=fopen("in.txt","rb");//以只读的形式打开该文件

if(fpin==NULL)

{

printf("文件不能打开或新建,请重新调试!/n");

exit (0);

}

i=0;

while(i++<6) temp[i]='/0'; //初始化temp数组

i=0;

if (ch ==' ' ) ch=GetCh(fpin);

if(ch==EOF)//文件结束

{

fclose(fpin);

return ;

}

}

void abc()

{

while(ch == ' ' || ch == 9 || ch == 10 || ch == 13 ) ch=GetCh(fpin);

if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')

{

k=0;

while(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >='0' && ch <= '9')

{//读取的是字母

temp[k++]=ch;

ch=GetCh(fpin);

}

digit=IsRetainLetters(temp);

while(i++<10) temp[i]='/0'; i=0;

}

else if(ch >= '0' && ch <= '9')

{//是数字

k=0;

while(ch >= '0' && ch <= '9')

{

temp[k++]=ch;

ch=GetCh(fpin);

}

digit=11;

i=0;

while(i++<10) temp[i]='/0';

i=0;

if(ch==EOF)

{

fclose(fpin);

return;

}

}

else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch==':'||ch==':='||ch=='<'||ch=='<>'

||ch=='<='||ch=='>'||ch=='>='||ch=='='||ch==';'||ch=='('||ch==')'||ch=='#')

{//为其他字符

switch(ch)

{

case '+': digit=13;break;

case '-': digit=14;break;

case '*': digit=15;break;

case '/': digit=16;break;

case ':': digit=17;break;

case '=': digit=18;break;

case '<': digit=20;break;

case '<>': digit=21;break;

case '<=': digit=22;break;

case '>': digit=23;break;

case '>=': digit=24;break;

case ':=': digit=25;break;

case ';': digit=26;break;

case '(': digit=27;break;

case ')': digit=28;break;

case '#': digit=0; break;

default:

break;

}

ch=GetCh(fpin);

}

else if(ch==EOF)

{

fclose(fpin);

return ;

}

else MessageBox(NULL,"有非法字符","ERROR",0);

}

void Analyse()

{

int temp;

Init_Stack();

Push(0); //界符入栈(#)

Push(100); //开始符号S入栈

Scaner();

abc();

while(1)

{

temp=Pop();



if(temp>0&&temp<100) //temp是终结符

{

if(digit==temp) //匹配

{

abc();

}

else

{

MessageBox(NULL,"error","error",0);

return ;

}

}

else if(temp>=100||temp==0) //temp是非终结符或'#'

{

if(temp==0) //temp=='#'

{

if(digit==temp) //匹配

{

MessageBox(NULL,"success","分析成功",0);

//Beep(100,1000);

return;

}

else

{

MessageBox(NULL,"error","error",0);

return ;

}

}

else

{

if(Analyse_Table[temp-100][digit])

{

Push_Stack(temp-100, digit);

}

else

{



MessageBox(NULL,"error","error",0);

return ;

}

}

}

else

{

MessageBox(NULL,"ERROR","ERROR",0);

return ;

}

}

}

//判断是否为保留字

int IsRetainLetters(char *ch)

{

int flag=1;

int i=0;

char *keyword[6]={"begin","if","then","while","do","end"};

while(i<6)

{

if(strcmp(ch,keyword[i])==0)

{



break;

}

flag++;

i++;

}

if(flag>=7)

return 10;

else

return flag;

}

//读取文件中的字符

char GetCh(FILE *fp)

{

char ch;

if(!feof(fp))

ch=fgetc(fp);//从fp所指向的文件的当前位置每次读取一个字符

return ch;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: