ITKeyword,专注技术干货聚合推荐

注册 | 登录

FORTRAN语言编译器---词法分析(C语言简易版)

onlinewan 分享于 2007-01-05

推荐:c语言编译器的混乱

昨天,参加了学院组织的所谓的“编程大赛”c语言的机试。题目有三个,很蛋疼,第一题:输出1到1000之间能被7或者11整除,但是不能同时被7和11整除的数。第二题:

2020腾讯云共同战“疫”,助力复工(优惠前所未有!4核8G,5M带宽 1684元/3年),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1054

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

1.实验题目:词法分析
用高级语言编写一个词法分析器,使之能识别输入串,并把分析结果(单词符号,标识符,关键字等等)输出.输入源程序,输入单词符号,本词法分析器可以辨别关键字,标识符,常数,运算符号和某些界符,运用了文件读入来获取源程序代码,再对该源程序代码进行词法分析,这就是词法分析器的基本功能.当词法分析器调用预处理子程序处理出一串输入字符放进扫描缓冲区之后,分析器就从此缓冲区中逐一识别单词符号.当缓冲区里的字符串被处理完之后,它又调用预处理子程序来处理新串.
2.实验目的
1)熟悉词法分析的基本原理,词法分析的过程,以及词法分析中要注意的一些问题。
2)复习高级语言,进一步加强用高级语言来解决实际问题的能力。
3.实验内容
1)程序总控图如下
......
2)实验步骤
1、基于实验的内容,构造程序所需的模块.
2、根据已建构的模块,写出各个模块的相应程序代码.
3、在主函数中调用模块来完成所要得到的效果.

/*! @ compiler_CFFX.c 

************************************
模块名         : 编译器---词法分析 
文件名         : compiler_CFFX.c
文件实现功能   : 词法分析 
作者           : onlinewan
版本           : 1.0
** ******************************** */

#include <stdio.h>

#include <string.h>

#include <ctype.h>

#include <alloc.h>

#include <conio.h> 

int IsLetter(char ch) 

{/*判断是否是字母,是则返回 1,否则返回 0  */

    if(isalpha(ch))        return 1;

    return 0;

}

int IsDigit(char ch)

{/*判断是否为数字,是则返回 1,否则返回 0 */

    if(isalnum(ch))              return 1;

    return 0;

}

int IsSpace(char ch)

{/*判断是否为空白符(空格、换行、制表符等),是则返回 1,否则返回 0*/ 

    if(isspace(ch))              return 1;

    return 0; 

}

void GetChar(FILE *fp,char *ch)

{/*读取字符送ch*/

     *ch = fgetc(fp);

}

void GetBC(FILE *fp,char *ch)

{/*如果是空白则继续读下一个,直到不是空白*/

     do {

        GetChar(fp,ch);

     }while(IsSpace(*ch)&&(*ch != EOF));   

}

void Retract(FILE *fp,char *ch)

{/*光标回退一位,并使 ch 为空*/

     fseek(fp,-1,1);

     *ch = '';

}

char Reserve(char *strToken)

{/*返回关键字的编码*/

       if(strcmp(strToken,"BEGIN") == 0)  return '1';

       if(strcmp(strToken,"FOR") == 0)  return '2';

       if(strcmp(strToken,"END") == 0)  return '3';

       if(strcmp(strToken,"DIM") == 0)  return '4';

       if(strcmp(strToken,"WHILE") == 0)  return '5';

       if(strcmp(strToken,"STOP") == 0)  return '6';

       if(strcmp(strToken,"IF") == 0)  return '7';

       if(strcmp(strToken,"ELSE") == 0)  return '8';

       if(strcmp(strToken,"INT") == 0)  return '9';

       return '0';

}

void Concat(char *strToken, char *ch)

{/*将ch中的字符连接到strToken后面*/

     int i;

        for(i=0;i<80;i++) {

              if(*strToken == NULL) {

                     *strToken = *ch;

                     break;

              }

              strToken++;           

        }

int lexSubFunc(FILE *fp1,FILE *fp2)

{/*词法分析子程序*/

    char ch,code;

    int i; 

    char strToken[80];

       

       while(1) {

              GetBC(fp1,&ch);

              for(i=0;i<80;i++) strToken[i]=NULL;

              if(ch == EOF) return 0;

              if (IsLetter(ch))  {                       

                     while (IsLetter(ch) || IsDigit(ch)) {

                            Concat(strToken,&ch);

                            GetChar(fp1,&ch);

                     }

                     Retract(fp1,&ch);

                     code = Reserve(strToken);    

                     if (code == '0') {

                            printf("<$ID,%s>/n",strToken);

                            fputs("<$ID,",fp2); fputs(strToken,fp2); fputs(">/n",fp2);  

                     }

                     else {

                            printf("<%c,->/n",code);

                            fputs("<",fp2); fputc(code,fp2); fputs(",->/n",fp2);                          

                     }

              }      

              else if (IsDigit(ch)) {

                     while (IsDigit(ch)) {

                            Concat(strToken,&ch);

                            GetChar(fp1,&ch); 

                     }

                     printf("<$INT,%s>/n",strToken);

                     fputs("<$INT,",fp2); fputs(strToken,fp2); fputs(">/n",fp2);

推荐:使用Lex和Yacc开发C语言的编译器

(1) 从网站:http://www.lysator.liu.se/c/  下载C语言的语法文件: The ANSI C grammar ( Yacc  and  Lex )  (2) 编译词法文件: >  lex c.l (3) 编译语法文件

              }

              else if (ch == '=') {

                     printf("<$ASSIGN,->/n");

                     fputs("<$ASSIGN,->/n",fp2);

              }

              else if (ch == '+') {

                     printf("<$PLUS,->/n");

                     fputs("<$PLUS,->/n",fp2);

              }

              else if (ch == '*') {

                     GetChar(fp1,&ch);

                     if (ch == '*') {

                            printf("<$POWER,->/n");

                            fputs("<$POWER,->/n",fp2);

                     }

                     else {

                            Retract(fp1,&ch);

                            printf("<$STAR,->/n");

                            fputs("<$STAR,->/n",fp2);

                     }

        }

              else if (ch == ';') {

                     printf("<$SEMICOLON,->/n");

                     fputs("<$SEMICOLON,->/n",fp2);

              }

              else if (ch == '(') {

                     printf("<$LPAR,->/n");

                     fputs("<$LPAR,->/n",fp2);

              }

              else if (ch == ')') {

                     printf("<$RPAR,->/n");

                     fputs("<$RPAR,->/n",fp2);

              }

              else if (ch == '{') {

                     printf("<$LBRACE,->/n");

                     fputs("<$LBRACE,->/n",fp2);

              }

              else if (ch == '}') {

                     printf("<$RBRACE,->/n");

                     fputs("<$RBRACE,->/n",fp2);

              }

       }  

}

void main(int argc, char *argv[])

{/*主程序*/

       FILE *fp1,*fp2; 

       if(argc==1) 

       { 

              printf("have not enter file name. strike any key exit"); 

              getch(); exit(0); 

       } 

       if((fp1=fopen(argv[1],"rt"))==NULL) 

       { 

              printf("Cannot open %s/n",argv[1]); 

              getch(); exit(1); 

       } 

       if((fp2=fopen("out.txt","wt+"))==NULL) 

       { 

              printf("Cannot create out.txt FILE.strike any key exit"); 

              getch(); exit(1); 

       } 

       lexSubFunc(fp1,fp2);

       fclose(fp1); 

       fclose(fp2); 

}

/*compiler_CFFX.c 结束*/

输入文件(input.txt)内容:

{}BEGIN;

FOR(I=0;I<10;I=I+1){}

END;

 

程序运行时在命令行下输入:

       Compiler_CFFX  input.txt

 

输出文件(out.txt)内容:

<$LBRACE,->

<$RBRACE,->

<1,->

<$SEMICOLON,->

<2,->

<$LPAR,->

<$ID,I>

<$ASSIGN,->

<$INT,0>

<$ID,I>

<$INT,10>

<$ID,I>

<$ASSIGN,->

<$ID,I>

<$PLUS,->

<$INT,1>

<$LBRACE,->

<$RBRACE,->

<3,->

<$SEMICOLON,->

 

 

推荐:Linux:C语言的标准和编译器

1. C语言的标准 1.1 K&R C 1973年,Dennis M. Ritchie设计和实现了C语言,从那以后使用者逐渐增加。 1978年,Kernighan 和 Ritchie 合著了《The C Programming L

1.实验题目:词法分析 用高级语言编写一个词法分析器,使之能识别输入串,并把分析结果(单词符号,标识符,关键字等等)输出.输入源程序,输入单词符号,本词法分析器可以辨别关键字,标识符,常数,运算

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。