0000000

#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(l\d)*","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("\n输入“****”时结束输入!\n");

         printf("\n请输入 ->                       (输入回车不能结束输入)\n\n");

         length=InputDate(input);

         printf("\n\n输入完成!\n\n");

 

         system("pause");                                      

         system("cls");                                      

        

         system("mode con cols=60 lines=40");

         printf("\n以下是输入内容 ->\n\n");

         PrintDate(input);

         printf("\n\n");

        

         printf("\n                   词法分析\n");

         printf("\n----------------------------------------------\n");     //输出上横线

         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,'\0');

                            printf("%15s\t\t\t%d\n",S.elem,11);

                            S=InitStack();

                            if(input[i]==32||input[i]=='\r')

                                     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,'\0');

                                     if(IsTwoCharacters(S)!=-1)

                                     {

                                               printf("%15s\t\t\t%d\n",S.elem,IsTwoCharacters(S));

                                               S=InitStack();

                                               i+=2;

                                     }

                            }

                            else

                            {

                                     S=Push(S,input[i]);  

                                     S=Push(S,'\0');

                                     if(IsTwoCharacters(S)!=-1)

                                               printf("%15s\t\t\t%d\n",S.elem,IsTwoCharacters(S));

                                     else

                                               printf("%15s\t\t\t%s\n",S.elem,"未知符号");      //输出种别码表没有的字符

                                     S=InitStack();

                                     i+=1;

                            }

                            if(input[i]==32||input[i]=='\r')

                                     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,'\0');                                          //栈中数据后补  \0

                            if(IsIdentifier(S)!=-1)

                            {

                                     printf("%15s\t\t\t%d\n",S.elem,IsIdentifier(S));

                                     S=InitStack();

                            }

                            else

                            {

                                     printf("%15s\t\t\t%d\n",S.elem,10);

                                     S=InitStack();

                            }

                            if(input[i]==32||input[i]=='\r')

                                     i++;

                   }

                   if(input[i]==32||input[i]=='\r')

                            i++;

         }       

         printf("----------------------------------------------\n\n");     //输出下横线

}

int InputDate(char input[])                                           //录入输入数据,返回数据长度

{

         int i;

         for(i=0;2>1;i++)

         {

                   input[i]=getch();

                   if(input[i]=='\r')

                            putchar('\n');

                   else if(input[i]==8)

                   {

                            if(i<=0)

                            {

                                     i-=1;

                                     putchar(7);

                            }else{

                                     i-=2;

                                     printf("\b \b");

                            }

                   }

                   else

                            putchar(input[i]);

                   if(i>=3&&(input[i]=='*'&&input[i-1]=='*'&&input[i-2]=='*'&&input[i-3]=='*'))

                            break;

         }

         input[i-3]='\0';

         return strlen(input);

}

void PrintDate(char input[])      //打印输入数据

{

         int i;

         for(i=0;input[i]!='\0';i++)

                   if(input[i]=='\r')

                            putchar('\n');

                   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;

}

posted @ 2015-10-08 14:23  huangmp  阅读(1303)  评论(5编辑  收藏  举报