编译原理词法分析程序

预头文件

/*----Head file for analysis programs in....----*/

#include <stdio.h>

#include <string.h>

#include <ctype.h>                  //使用到的字符分类函数定义在的头文件

 

/**

*TEST编译器:词法分析头文件

*@author mohui

*@date 2015/04/12

***/

 

//--------预定义常量--------

#define keywordSum 8                 //关键字个数

#define compileOK 0                  //词法分析成功完成代码

#define inputERROR 1                 //词法分析源文件输入出错代码

#define outputERROR 2                //词法分析输出文件出错代码

#define unusualChr 3                  //词法分析非法字符代码

 

//--------变量、结果类型--------

char *keyword[keywordSum]={"if","else","for","while","do","int","read","write"};

char singleword[20]="+-*(){};,:";      //纯单分界符

char doubleword[20]="><=!";         //双分界符的首字符

char inFile[50],outFile[50];           //源文件名与输出报告文件名(含路径)

FILE *fin,*fout;

 

//--------analysis.c---------

int TESTscan();                     //词法分析函数

int IOinfo();                        //文件流输入输出监管

void String(char *ch);                //检查标识符(包括关键字)并记录

void Number(char *ch);              //检查数字并记录

void sDelimiter(char *ch);            //纯单分界符

void dDelimiter(char *ch);            //分离双分界符与单分界符

void comments(char *ch);            //注释符内容处理

int illegalChr(char *ch);              //词法分析过程非法字符处理

 

 

C源程序

#include "analysis.h"

 

/**

*TEST编译器:词法分析

*@author mohui

*@date 2015/04/12

***/

//---------主    程   序--------

int main(){

    int ecode=compileOK;

    ecode=TESTscan();

    if(ecode>0)

    {

        printf("==================================\n");

        printf("ERROR : 词法分析存在错误,编译中断!\n错误代码 : %d\n",ecode);

        printf("==================================\n");

    }

    else

        printf("词法分析成功!\n");

    return 0;

}

 

//--------集成函数主模块--------

int TESTscan(){

    char ch;

    int ecode;

    ecode=IOinfo();

    ch=getc(fin);

 

    do{

        while(isspace(ch))     //检查是否是空格符和跳格符(控制字符)或换行符

            ch=getc(fin);

 

        if(isalpha(ch))                     //判断是否是字母

        {

            String(&ch);             //记录标识符[关键字]

        }

        else if(isdigit(ch))                //检查是否是数字

        {

            Number(&ch);             //记录数字

        }

        else if(strchr(singleword,ch)>0)    //判断singleword中有没有ch,有返回值为1,没有返回值为0

        {

            sDelimiter(&ch);         //记录纯单分界符

        }

        else if(strchr(doubleword,ch)>0)

        {

            dDelimiter(&ch);         //分离双分界符与单分界符

        }

        else if(ch=='/')

        {

            comments(&ch);           //分离注释处理

        }

        else

        {

            ecode=illegalChr(&ch);              //分析过程异常符号处理

        }

    }while(!feof(fin));

 

    fclose(fin);

    fclose(fout);

 

    return ecode;

}

 

//--------文件流情况的监管--------

int IOinfo(){

    printf("请输入源文件文件名[包括路径]:\n");

    fscanf(stdin,"%s",inFile);

    printf("请输入词法分析输出文件名[包括路径]:\n");

    fscanf(stdin,"%s",outFile);

 

    if((fin=fopen(inFile,"r"))==NULL)

    {

        printf("打开词法分析源文件出错!\n");

        return (inputERROR);

    }

    if((fout=fopen(outFile,"w"))==NULL)

    {

        printf("创建词法分析输出文件出错!\n");

        return (outputERROR);

    }

    return compileOK;

}

 

//--------检查&记录标识符(包括关键字)--------

void String(char *ch){

    char checked[50];

    int j,n;

    checked[0]=*ch;

    j=1;

    *ch=getc(fin);                   //读入下一个字符

    while(isalnum(*ch))              //检查是否是数字或字母

    {

        checked[j++]=*ch;

        *ch=getc(fin);

    }

    checked[j]='\0';                //标识符组合结束

        n=0;

    while((n<keywordSum)&&strcmp(checked,keyword[n]))

        n++;

    if(n>=keywordSum)

        fprintf(fout,"%s\t%s\n","ID",checked);      //输出标识符符号

    else

        fprintf(fout,"%s\t%s\n",checked,checked);   //输出保留字符号

}

 

//--------检 查&记 录 数 字--------

void Number(char *ch){

    char checked[100];

    int j;

    checked[0]=*ch;

    j=1;

    *ch=getc(fin);                   //读入下一个字符

    while(isdigit(*ch))

    {

        checked[j++]=*ch;

        *ch=getc(fin);

    }

    checked[j]='\0';                //数字组合结束

    fprintf(fout,"%s\t%s\n","NUM",checked);          //输出整数符号

}

 

//--------单分界符--------

void sDelimiter(char *ch){

    char checked[2];

    checked[0]=*ch;

    checked[1]='\0';

    *ch=getc(fin);

    fprintf(fout,"%s\t%s\n",checked,checked);       //输出单分界符

}

 

 

//--------双分界符--------

void dDelimiter(char *ch){

    char checked[5];

    checked[0]=*ch;

    *ch=getc(fin);

    if(*ch=='=')

    {

        checked[1]=*ch;

        checked[2]='\0';

        *ch=getc(fin);

    }

    else

        checked[1]='\0';

    fprintf(fout,"%s\t%s\n",checked,checked);       //输出双分界符或单分界符

}

 

//--------注释符处理--------

void comments(char *ch){         //程序顺序执行到这里,已经过单分界符的判断,so可以不必再记录ch

    char checked[2];

    *ch=getc(fin);

    if (*ch=='*')

    {

        char ch1;

        ch1=getc(fin);

        do{

            *ch=ch1;

            ch1=getc(fin);

        }while((*ch!='*'||ch1!='/')&&!feof(fin));

        *ch=getc(fin);

    }

    else

    {

        checked[0]='/';

        checked[1]='\0';

        fprintf(fout,"%s\t%s\n",checked,checked);       //输出单分界符

    }

}

 

//--------异常(非法)字符处理--------

int illegalChr(char *ch){

    char checked[2];

    checked[0]=*ch;

    checked[1]='\0';

    *ch=getc(fin);

    fprintf(fout,"%s\t%s\n",checked,checked);           //输出异常(非法)符号

    return (unusualChr);

}

 

 

 

测试用的两个TEST源码:

test.txt内容:

 

illegal.txt内容:

 

运行结果:

 

 

           

 

 

 

 

         

       

 

 

 

       

转载于:https://www.cnblogs.com/360-782/p/4516241.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值