#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#define MAXSIZE 100
typedef struct
{
char elem[MAXSIZE];
int top;
int low;
int flag; //1是数字,2是字母,3是符号
}Stack;
char Identification[MAXSIZE][MAXSIZE]={"#","begin","if","then","while","do","end","","","","l(ld)*","dd*","","+","-","*","/",":",":=","","<","<=","<>",">",">=","=",";","(",")"};
Stack InitStack(); //初始化链表
Stack Push(Stack S,char x); //进栈
Stack Pop(Stack S); //出栈
int GetTop(Stack S); //取栈
int InputDate(char input[]); //录入输入数据
void PrintDate(char input[]); //打印数据
int IsNumber(char a); //若a是数字,返回1
int IsLetter(char a); //若a是字母,返回1
int IsSign(char a); //若a是符号,返回1 空格 和 下划线 返回0
int IsIdentifier(Stack S); //比较,看栈中数据的类型 是否是 标识符 是则返回相应的 种别码 否则返回-1
int IsTwoCharacters(Stack S); //比较,看栈中数据的类型 是否是已知字符符号 是则返回相应的 种别码 否则返回-1
void main()
{
Stack S;
int i,j,length,flag=0;
char input[1000];
system("title 词法分析");
printf(" 输入“****”时结束输入! ");
printf(" 请输入 -> (输入回车不能结束输入) ");
length=InputDate(input);
printf(" 输入完成! ");
system("pause");
system("cls");
system("mode con cols=60 lines=40");
printf(" 以下是输入内容 -> ");
PrintDate(input);
printf(" ");
printf(" 词法分析 ");
printf(" ---------------------------------------------- "); //输出上横线
S=InitStack();
for(i=0;i<length;)
{
if(IsNumber(input[i])) //首字符是数字
{
while((IsNumber(input[i])||input[i]==46)&&i<length)
{
S.flag=1;
S=Push(S,input[i]);
i++;
}
S=Push(S,' ');
printf("%15s %d ",S.elem,11);
S=InitStack();
if(input[i]==32||input[i]==' ')
i++;
}
else if(IsSign(input[i])) //首字符是符号
{
if((input[i]==':'&&input[i+1]=='=')||(input[i]=='<'&&input[i+1]=='=')||(input[i]=='<'&&input[i+1]=='>')||(input[i]=='>'&&input[i+1]=='='))
{
S=Push(S,input[i]);
S=Push(S,input[i+1]);
S=Push(S,' ');
if(IsTwoCharacters(S)!=-1)
{
printf("%15s %d ",S.elem,IsTwoCharacters(S));
S=InitStack();
i+=2;
}
}
else
{
S=Push(S,input[i]);
S=Push(S,' ');
if(IsTwoCharacters(S)!=-1)
printf("%15s %d ",S.elem,IsTwoCharacters(S));
else
printf("%15s %s ",S.elem,"未知符号"); //输出种别码表没有的字符
S=InitStack();
i+=1;
}
if(input[i]==32||input[i]==' ')
i++;
}
else if(IsLetter(input[i])) //首字符是字母
{
while((IsLetter(input[i])||IsNumber(input[i])||input[i]==95)&&i<length)
{
S.flag=2;
S=Push(S,input[i]);
i++;
}
S=Push(S,' '); //栈中数据后补
if(IsIdentifier(S)!=-1)
{
printf("%15s %d ",S.elem,IsIdentifier(S));
S=InitStack();
}
else
{
printf("%15s %d ",S.elem,10);
S=InitStack();
}
if(input[i]==32||input[i]==' ')
i++;
}
if(input[i]==32||input[i]==' ')
i++;
}
printf("---------------------------------------------- "); //输出下横线
}
int InputDate(char input[]) //录入输入数据,返回数据长度
{
int i;
for(i=0;2>1;i++)
{
input[i]=getch();
if(input[i]==' ')
putchar(' ');
else if(input[i]==8)
{
if(i<=0)
{
i-=1;
putchar(7);
}else{
i-=2;
printf(" ");
}
}
else
putchar(input[i]);
if(i>=3&&(input[i]=='*'&&input[i-1]=='*'&&input[i-2]=='*'&&input[i-3]=='*'))
break;
}
input[i-3]=' ';
return strlen(input);
}
void PrintDate(char input[]) //打印输入数据
{
int i;
for(i=0;input[i]!=' ';i++)
if(input[i]==' ')
putchar(' ');
else
putchar(input[i]);
}
Stack InitStack() //初始化链表
{
Stack S;
S.top=-1;
S.flag=0;
S.low=0;
return (S);
}
Stack Push(Stack S,char x) //进栈
{
if(S.top==MAXSIZE-1)
printf("栈已满,无法入栈");
else
{
S.top=S.top+1;
S.elem[S.top]=x;
}
return (S);
}
Stack Pop(Stack S) //出栈
{
if(S.top==-1)
printf("栈是空的,无法出栈");
else
S.top-=1;
return S;
}
int GetTop(Stack S) //取栈
{
int x;
if(S.top==-1)
printf("栈是空的,无法取栈顶!");
else
x=S.elem[S.top];
return x;
}
int IsNumber(char a) //若a是数字,返回1
{
return a>=48&&a<=57;
}
int IsLetter(char a) //若a是字母,返回1
{
return (a>=65&&a<=90)||(a>=97&&a<=122);
}
int IsSign(char a) //若a是符号,返回1 空格 和 下划线 返回0
{
return (a>32&&a<=47)||(a>=58&&a<=64)||(a>=91&&a<=94||a>=95&&a<=96)||(a>=123&&a<=127);
}
int IsIdentifier(Stack S) //比较,看栈中数据的类型 是否是标识符 是则返回相应的 种别码 否则返回-1
{
int i;
for(i=0;i<7;i++)
if(strcmp(S.elem,Identification[i])==0)
return i;
return -1;
}
int IsTwoCharacters(Stack S) //比较,看栈中数据的类型 是否是已知字符符号 是则返回相应的 种别码 否则返回-1
{
int i;
for(i=13;i<29;i++)
if(strcmp(S.elem,Identification[i])==0)
return i;
return -1;
}