#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;
}