天天看点

0916 语法分析程序

0916 语法分析程序

源程序:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define _KEY_WOED_END "waiting for your expanding"     //关键字结束标志

typedef struct

{

    int typenum;

    char * word;

}WORD;

char input[255];   //输入换缓冲区

char token[255]="";   //单词缓冲区

int p_input;        //输入换缓冲区指针

int p_token;        //单词缓冲区指针

char ch;           //当前所读的字符

char *rwtab[]={"begin","if","then","while","do","end",_KEY_WOED_END};        //C语言关键字

WORD * scaner();    //词法扫描函数,获得关键字

main()

    int over=1;

    WORD *oneword;

    oneword=(WORD *)malloc(sizeof(WORD));

    printf("请输入您的字符串(以#作为结束标志):");

    scanf("%[^#]s",input);                        //读入源程序字符串到缓冲区,以#结束,允许多行输入

    p_input=0;

    printf("您输入的字符串是:%s\n\n",input);

    while(over<1000&&over!=-1)

    {

        oneword=scaner();

        printf("(%d,%s)\n",oneword->typenum,oneword->word);

        over=oneword->typenum;

    }

    printf("\n\n备注:数字10代表所输入的不是关键词,只是普通词\n");

    printf("     数字20代表您输入的是数字\n");

    printf("     数字1000是结束标志\n\n");

}

//需要用到的自编函数参考实现

//从输入缓冲区读取一个字符到ch中

char m_getch(){

    ch=input[p_input];

    p_input=p_input+1;

    return (ch);

//去掉空白字符

void getbc()

    while(ch==' '||ch==10){

//拼接单词

void concat()

    token[p_token]=ch;

    p_token=p_token+1;

    token[p_token]='\0';

//判断是否字母

int letter()

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

    else return 0;

//判断是否数字

int digit()

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

        return 1;

    else

        return 0;

//检索关键字表格

int reserve()

    int i=0;

    for(i=0;i<7;i++)

        if(!strcmp(rwtab[i],token))

        {

            return i+1;

        }

        i=i+1;

    return 10;

//回退一个字符

void retract()

    p_input=p_input-1;

WORD *scaner()

    WORD *myword;

    myword=(WORD *)malloc(sizeof(WORD));

    myword->typenum=10;

    myword->word="";

    p_token=0;

    m_getch();

    getbc();

    if(letter())

        while(letter()||digit())

           concat();

           m_getch();

        retract();

        myword->typenum=reserve();

        myword->word=token;

        return(myword);

    else if(digit())

        while(digit())

            concat();

            m_getch();

        myword->typenum=20;

        switch(ch)

        case '=':m_getch();

            if(ch=='=')

            {

                myword->typenum=39;

                myword->word="==";

                return(myword);

            }

            retract();

            myword->typenum=21;

            myword->word="=";

            return(myword);

            break;

        case '+':

            myword->typenum=22;

                myword->word="+";

                break;

        case '-':

            myword->typenum=23;

                myword->word="-";

        case '*':

            myword->typenum=24;

            myword->word="*";

        case '/':

            myword->typenum=25;

            myword->word="/";

        case '(':

            myword->typenum=26;

            myword->word="(";

        case ')':

            myword->typenum=27;

            myword->word=")";

        case '[':

            myword->typenum=28;

            myword->word="[";

        case ']':

            myword->typenum=29;

            myword->word="]";

        case '{':

            myword->typenum=30;

            myword->word="{";

        case '}':

            myword->typenum=31;

            myword->word="}";

        case ',':

            myword->typenum=32;

            myword->word=",";

        case ':':

            myword->typenum=33;

            myword->word=":";

        case ';':

            myword->typenum=34;

            myword->word=";";

        case '>':

            myword->typenum=35;

            myword->word=">";

        case '<':

            myword->typenum=36;

            myword->word="<";

        case '!':

                myword->typenum=40;

                myword->word="!=";

            myword->typenum=-1;

            myword->word="ERROR";

        case '\0':

            myword->typenum=1000;

            myword->word="OVER";

        default: