现在的位置: 首页 > 综合 > 正文

词法分析程序

2012年09月07日 ⁄ 综合 ⁄ 共 3986字 ⁄ 字号 评论关闭
/*************************************************************/
/*
/*词法分析程序
/*maker:张建波
/*date:2005-10-26
/*
/*************************************************************/
#include "stdio.h"
#include "ctype.h"
#include "string.h"

/*保留字数量*/
#define keywordSum 8
char *keyword[keywordSum]={"if","else","for","while","do","int","read","write"};

/*纯但单分界符*/
#define singlewordSum 10
char singleword[singlewordSum]="+-*(){};,:";

/*双分界符*/
#define doublewordSum 4
char doubleword[doublewordSum]="<>=!";

#define wordlen 40 /*单词最大长度*/

char ScanInFile[300];      /*待分析的源程序文件*/
char ScanOutFile[305];      /*词法分析后的输出文件*/

FILE *fin,*fout;         /*输入输出文件的指针*/

int LoadCodeFile()
{
    /* 打开待分析的 源代码文件*/
   
    printf("请输入源程序文件名:");
    scanf("%s",ScanInFile);
    if((fin=fopen(ScanInFile,"r"))==NULL)
    {
        printf("/n找不到文件:%s/n文件打开失败!/n");
        return 0;
    }
    else
    return 1;
}

int CreatWordFile()
{
    /*创建次词法分析后结果的输出 文件*/
    int len=0;
    int i=0;
    strcpy(ScanOutFile,ScanInFile);
    while(ScanOutFile[i++]!='.');
    ScanOutFile[i+1]='s';
    ScanOutFile[i+2]='c';
    ScanOutFile[i+3]='n';
    ScanOutFile[i+4]='/0';
    if((fout=fopen(ScanOutFile,"w"))==NULL)
    {
        /*文件创建失败*/
        return 0;
    }
    else
        return 1;

}

/*词法分析程序*/
int TScan()
{

    char ch,token[wordlen]; /*ch 为每次读入的字符,token 为识别出来的单词*/

    char ch1; /*处理注释时 用的临时变量*/

    int err=0;              /* 设置错误代码为 0, 表示没有错误 */
    int j,n;                /*临时变量,控制组合单词时的数组下标*/

    if(LoadCodeFile()==0)
        return 1;          /*源代码文件读取失败*/
    if(CreatWordFile()==0)
        return 2;          /*文件创建失败*/

    ch=getc(fin);
    while(ch!=EOF)
    {
        while(ch==' '||ch=='/n'||ch=='/t')
        {
            ch=getc(fin);
        }
        if(isalpha(ch))
        {
            /*输入的是字母,进行 标示符 处理*/
            token[0]=ch;
            j=1;
            while(isalnum(ch))
            {
                token[j++]=ch;
                ch=getc(fin);
            }/*如果是字母数字则组合,否则结束*/
            token[j]='/0';
            /*查找保留字*/
            n=0;
            while((n<keywordSum) && strcmp(token,keyword[n]))
                n++;
            if(n>=keywordSum)
            {
                /*输出标示符*/
                fprintf(fout,"%s/t%s/n","ID",token);
                printf("%s/t%s/n","ID",token);
            }
            else
            {
                /*输出保留字*/
                fprintf(fout,"%s/t%s/n",token,token);
                printf("%s/t%s/n",token,token);
            }
        }
        else if(isdigit(ch))
        {
            /*输入的是数字,进行 数字处理*/
            token[0]=ch;
            j=1;
            ch=getc(fin);/*读下一字符*/
            while(isdigit(ch))
            {/*如果是数字则整合数字*/
                token[j++]=ch;
                ch=getc(fin);
            }
            token[j]='/0';/*整数整合结束*/
            fprintf(fout,"%s/t%s/n","NUM",token);
            printf("%s/t%s/n","NUM",token);
        }
        else if(strchr(singleword,ch)>0)
        {
            /*输入的是单分界符*/
            token[0]=ch;
            token[1]='/0';
            ch=getc(fin);
            fprintf(fout,"%s/t%s/n",token,token);
            printf("%s/t%s/n",token,token);
        }
        else if(strchr(doubleword,ch)>0)
        {
            /*输入的是双分界符*/
            token[0]=ch;
            ch=getc(fin);
            if(ch=='=')  /*如果是 = 则组合双分界符*/
            {
                token[1]=ch;token[2]='/0';
                ch=getc(fin);
            }
            else
            {
                token[1]='/0';
            }
            fprintf(fout,"%s/t%s/n",token,token);
            printf("%s/t%s/n",token,token);
        }
        else if(ch=='/')
        {
            /*注释处理*/
            ch=getc(fin);
            if(ch=='*')
            {
                ch1=getc(fin);
                do
                {
                    ch=ch1;
                    ch1=getc(fin);
                }while((ch!='*'||ch1!='/')&&ch1!=EOF);
                ch=getc(fin);
            }
            else
            {
                token[0]='/';
                token[1]='/0';
                fprintf(fout,"%s/t%s/n",token,token);  /*输出单词分界符*/
                printf("%s/t%s/n",token,token);
            }
        }
        else
        {
            /*无法识别的字符 */
            token[0]=ch;
            token[1]='/0';
            ch=getc(fin);
            err=3;
            fprintf(fout,"%s/t%s/n","ERROR",token);  /*输出错误符号*/
            printf("%s/t%s/n","ERROR",token);
        }
    }
    return err;
}

void main()
{
    int e=0;
    e=TScan();
    if(e>0)printf("编译错误!");
    else
        printf("词法分析成功!");

}

抱歉!评论已关闭.