编译原理词法分析程序

#include <stdio.h>
#include <ctype.h>


char Scanin[300],Scanout[300];
extern int TESTscan();
char Scanin[300],Scanout[300];
FILE *fin,*fout;//指向输入输出文件的指针
int main()
{
    int i;
    char ch;
    int es=0;
    for(i=0;i<3;i++)
    {
        es=TESTscan();
        if(es>0)
            printf("词法分析有错误!\n");
        else
            printf("词法分析成功!\n");
        printf("-------------------------------------------------------------------------\n");
        printf("\n");
        printf("\n");
    }

}



#include<stdlib.h>
#include <stdio.h>
#include <string.h>
//定义关键字
#define keywordSum 36
char *keyword[keywordSum]={"auto","break","call","case","char","const","continue","default","do","double","else",
"enum","extern","float","for","function","goto","if","int","long","read","register","return","short","signed",
"sizeof","static","struct","switch","typedef","union","unsigned","void","volatile","while","write"};
//定义单分界符
char singleword[50]="+-*\(){}[];'\"',:.'%^";
//定义双分界符
char doubleword[10]="><=!&|";

extern char Scanin[300],Scanout[300];
extern FILE *fin,*fout;//指向输入输出文件的指针

int TESTscan()
{
    int number=1;
    char ch,token[40],*t;//ch为每次读入的字符,token用于保存识别出的单词
    int es=0,j,n;
    printf("-------------------------------------------------------------------------\n");
    printf("请输入源程序文件名字(in1.txt in2.txt in3.txt):");
    scanf("%s",Scanin);
    printf("-------------------------------------------------------------------------\n");
    printf("请输入词法分析输出文件名字(out1.txt out2.txt out3.txt):");
    scanf("%s",Scanout);
    printf("-------------------------------------------------------------------------\n");
    if((fin=fopen(Scanin,"r"))==NULL)
    {
        printf("打开源程序文件出错!\n");
        return 1;
    }
    if((fout=fopen(Scanout,"w"))==NULL)
    {
        printf("\n打开词法分析输出文件出错!\n");
        return 2;
    }
    ch=getc(fin);//取一个字符
    while(ch!=EOF)//没有到文件结尾
    {
        while(ch==' '||ch=='\t'||ch=='\n') //如果是空格,换行,则直接跳过
        {
            if(ch=='\n')
                number++;
            ch=getc(fin);
        }
        if(isalpha(ch)||ch=='_')//如果ch是字母,则进行标识符处理
        {
           token[0]=ch;
           j=1;
           ch=getc(fin);
           while(isalnum(ch)||ch=='_') //如果是字母数字
           {
               token[j++]=ch;
               ch=getc(fin);
           }
            token[j]='\0';//标识符组合结束
            //查关键字
            int left=0,right=keywordSum-1,mid;
            while(left<=right)
            {
                mid=(left+right)/2;
                if(strcmp(keyword[mid],token)==0)
                {
                    fprintf(fout,"%s\t%s\n",token,token);
                    break;
                }
                if(strcmp(keyword[mid],token)>0)
                    right=mid-1;
                if(strcmp(keyword[mid],token)<0)
                    left=mid+1;
            }
            if(left>right)
                fprintf(fout,"%s\t%s\n","ID",token);
        }
        else if(isdigit(ch)) //如果是常数
        {
            int flag=0;
            token[0]=ch;
            j=1;
            ch=getc(fin);
            while(isalpha(ch))
            {
                token[j++]=ch;
                ch=getc(fin);
                flag=1;
            }
            while(isdigit(ch))
            {
                token[j++]=ch;//组合整数保存在token中
                ch=getc(fin);
            }
            if(ch=='.')
            {
                token[j++]=ch;
                ch=getc(fin);
            }
            while(isdigit(ch))
            {
                token[j++]=ch;//组合整数保存在token中
                ch=getc(fin);
            }
            token[j]='\0';
            if(flag==1)
            {
                fprintf(fout,"%s\t%s\n","ERROR",token);
                printf("程序第%d行有错误!",number);
                printf("%s\t%s\n","ERROR",token);
            }
            else
                fprintf(fout,"%s\t%s\n","NUM",token);
        }
        else if(strchr(singleword,ch)>0)//能在singleword这个数组里查找到ch
        {
            token[0]=ch;
            token[1]='\0';
            ch=getc(fin);
            fprintf(fout,"%s\t%s\n",token,token);
        }
        else if(strchr(doubleword,ch)>0) //在双分里查找界符这个数组里查找单词的第一个字符
        {
            token[0]=ch;
            ch=getc(fin);
            if(token[0]=='>'||token[0]=='<'||token[0]=='='||token[0]=='!')
            {
                if(ch=='=')
                {
                    token[1]=ch;
                    token[2]='\0';
                    ch=getc(fin);
                    fprintf(fout,"%s\t%s\n",token,token);
                }
                else if(isalpha(ch))
                {
                    token[1]='\0';
                    fprintf(fout,"%s\t%s\n",token,token);
                }
                else if(isalnum(ch))
                {
                    token[1]='\0';
                    fprintf(fout,"%s\t%s\n",token,token);
                }
                else if(ch=='(')
                {
                    token[1]='\0';
                    fprintf(fout,"%s\t%s\n",token,token);
                }
                else
                {
                    token[1]=ch;
                    token[2]='\0';
                    ch=getc(fin);
                    fprintf(fout,"%s\t%s\n","ERROR",token);
                    printf("程序第%d行有错误!",number);
                    printf("%s\t%s\n","ERROR",token);
                    printf("************************");

                }
            }
            else if(token[0]=='&')
            {
                if(ch=='&')
                {
                    token[1]=ch;
                    token[2]='\0';
                    ch=getc(fin);
                    fprintf(fout,"%s\t%s\n",token,token);
                }
                else
                {
                    token[1]=ch;
                    token[2]='\0';
                    ch=getc(fin);
                    fprintf(fout,"%s\t%s\n","ERROR",token);
                    printf("程序第%d行有错误!",number);
                    printf("%s\t%s\n","ERROR",token);
                }
            }
            else if(token[0]=='|')
            {
                if(ch=='|')
                {
                    token[1]=ch;
                    token[2]='\0';
                    ch=getc(fin);
                    fprintf(fout,"%s\t%s\n",token,token);
                }
                else
                {
                    token[1]=ch;
                    token[2]='\0';
                    ch=getc(fin);
                    fprintf(fout,"%s\t%s\n","ERROR",token);
                    printf("程序第%d行有错误!",number);
                    printf("%s\t%s\n","ERROR",token);
                }
            }
            else
            {
                token[1]='\0';
                fprintf(fout,"%s\t%s\n",token,token);
            }
        }

        else if(ch=='/')//进行注释处理
        {
            ch=getc(fin);
            if(ch=='*')
            {
                char ch1;
                ch1=getc(fin);
                do
                {
                    ch=ch1;
                    ch1=getc(fin);
                    if(ch1=='\n')
                        number++;
                }
                while((ch!='*'||ch1!='/')&&ch1!=EOF);  //当ch=='*'&&ch1=='/' 或者 ch1为文件结尾 就退出循环
                ch=getc(fin);
                if(ch=='\n')
                    number++;
            }
            else if(ch=='/')
            {
                number++;
                ch=getc(fin);
                do
                    ch=getc(fin);
                while(ch!='\n'&&ch!=EOF);
                ch=getc(fin);
            }
            else
            {
                token[0]='/';
                token[1]='\0';
                fprintf(fout,"%s\t%s\n",token,token);
            }
        }
        else//以上情况都不是
        {
            token[0]=ch;
            token[1]='\0';
            ch=getc(fin);
            es=3;
            fprintf(fout,"%s\t%s\n","ERROR",token);
            printf("程序第%d行有错误!",number);
            printf("%s\t%s\n","ERROR",token);
        }
    }
    fclose(fin);
    fclose(fout);
    return es;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值