赞
踩
词法分析是编译的第一个阶段,其任务是:从左至右对原程序进行扫描,产生一个个单词符号。
对常用有限个单词进行编码
(1)identify_char:标识符
(2)include等:关键词
(3)+ - * /:操作符
(4){ }等:分界符
(5)# 等:程序不能识别的字符
注:本段程序只能分析出下表给出的字符
(1)判断是否为关键字,字母,数字。
bool isKey(char * token);//keyword
bool isLetter(char letter);//letter
bool isDigit(char digit);//digit
(2)通过代码访问文件,文件指针依次扫描文件中的字符,如果文件指针遇到(\t,\n,’ '),程序什么都不做,将得到的字符串进行判断,文件指针向后退一格,准备读下一个字符串。
(3)对使用到的文件函数进行说明
//1. /*从文件指针fgetc(stream)指向的文件读取一个字符,读取一个字节后,光标位置后移一个字节 * format: int fgetc(FILE*stream) * 函数返回得到的字符值 * 读到结尾或者读到错误,返回EOF * EOF是一个有效的整型值 * 二进制文件使用feof函数进行结束检测 * 用ferror函数进行出错检查 //2. * /*int fseek(FILE*stream,long offset,int fromwhere),调整文件当前指针 * 若果函数成功执行,stream指针将指向以fromwhere为基准,偏移offset个字节的位置,函数返回0 * 若果函数执行失败(offset的值大于等于2*1024*1024*1024,即long的整数范围为2G),函数返回非零值 * 偏移起始位置:文件头0(SEEK_SET) * 当前位置:当前位置1(SEEK_CUR) * 文件尾2(SEEK_END)*/ */
(4)详细注释在代码在代码注释中。
编译环境:eclipse + MinGW
#include<stdio.h> #include<string.h> #define bool int #define true 1 #define false 0 #define MAX 11 char ch = ' '; char* keyWord[11] = {"include","main","void","break","int","float","if","else","while","printf","for"}; char token[20];//定义获取的字符 //判断是否是关键字 bool isKey(char * token) { for(int i = 0;i < MAX;i++) { if(strcmp(token,keyWord[i]) == 0) return true; } return false; } //判断是否是字母 bool isLetter(char letter) { if((letter >= 'a' && letter <= 'z')||(letter >= 'A' && letter <= 'Z')) return true; else return false; } //判断是否是数字 bool isDigit(char digit) { if(digit >= '0' && digit <= '9') return true; else return false; } //1. /*从文件指针fgetc(stream)指向的文件读取一个字符,读取一个字节后,光标位置后移一个字节 * format: int fgetc(FILE*stream) * 函数返回得到的字符值 * 读到结尾或者读到错误,返回EOF * EOF是一个有效的整型值 * 二进制文件使用feof函数进行结束检测 * 用ferror函数进行出错检查 */ void analyze(FILE *fpin) { while((ch = fgetc(fpin)) != EOF){ if(ch == ' '||ch == '\t'||ch == '\n'){}//读到空字符,空格,换行符什么都不做 else if(isLetter(ch)){ char token[20]={'\0'}; int i=0; while(isLetter(ch)||isDigit(ch)){ token[i] = ch; i++; ch = fgetc(fpin);//读下一个字符 } //回退一个指针 /*int fseek(FILE*stream,long offset,int fromwhere),调整文件当前指针 * 若果函数成功执行,stream指针将指向以fromwhere为基准,偏移offset个字节的位置,函数返回0 * 若果函数执行失败(offset的值大于等于2*1024*1024*1024,即long的整数范围为2G),函数返回非零值* * 偏移起始位置:文件头0(SEEK_SET) * 当前位置:当前位置1(SEEK_CUR) * 文件尾2(SEEK_END)*/ fseek(fpin,-1L,SEEK_CUR);//文件指针停留在空字符,空格,换行符的位置上 if(isKey(token)){ //关键字 int i,j; for( i = 0;i < MAX;i++) { if(strcmp(token,keyWord[i]) == 0)j=i; } printf("%s\t%d\tkeyword\n",token,j); } else{ //标识符 printf("%s\t4\tidentify_char\n",token); } } else if(isDigit(ch)||(ch == '.')) { int i=0; char token[20]={'\0'};//清空缓冲数组;但文件指针还在;即读入下一个字符 while(isDigit(ch)||(ch == '.'&&isDigit(fgetc(fpin)))) { if(ch == '.')fseek(fpin,-1L,SEEK_CUR); token[i] = ch; i++; ch = fgetc(fpin); } fseek(fpin,-1L,SEEK_CUR); //属于无符号常数 printf("%s\t11\tconstant\n",token); fflush(stdout); } else switch(ch){ //运算符 case '+':{ ch = fgetc(fpin); if(ch == '+') { printf("++\t12\toperator\n"); fflush(stdout); } else { printf("+ \t13\toperator\n"); fflush(stdout); fseek(fpin,-1L,SEEK_CUR); } }break; case '-':{ ch = fgetc(fpin); if(ch == '-') { printf("--\t14\toperator\n"); fflush(stdout); } else { printf("- \t15\toperator\n"); fflush(stdout); fseek(fpin,-1L,SEEK_CUR); } }break; case '*':printf("%c\t16\toperateor\n",ch);break; case '/':printf("%c\t17\toperateor\n",ch);break; //分界符 case '(':printf("%c\t18\tboundary\n",ch);break; case ')':printf("%c\t19\tboundary\n",ch);break; case '[':printf("%c\t20\tboundary\n",ch);break; case ']':printf("%c\t21\tboundary\n",ch);break; case ';':printf("%c\t22\tboundary\n",ch);break; case '{':printf("%c\t23\tboundary\n",ch);break; case '}':printf("%c\t24\tboundary\n",ch);break; case '#':printf("%c\t25\tboundary\n",ch);break; //运算符 case '=':{ ch = fgetc(fpin); if(ch == '=')printf("==\t26\toperator\n"); else { printf("= \t27\toperator\n"); fseek(fpin,-1L,SEEK_CUR); } }break; case ':':{ ch = fgetc(fpin); if(ch == '=')printf(":=\t28\toperator\n"); else { printf(": \t29\toperator\n");; fseek(fpin,-1L,SEEK_CUR); } }break; case '>':{ ch = fgetc(fpin); if(ch == '=')printf(">=\t30\toperator\n"); else { printf("> \t31\toperator\n");; fseek(fpin,-1L,SEEK_CUR); } }break; case '<':{ ch = fgetc(fpin); if(ch == '=')printf("<=\t32\toperator\n"); else { printf("< \t33\toperator\n"); fseek(fpin,-1L,SEEK_CUR); } }break; //无识别 default: printf("%c\t34\tno_recognition\n",ch); } } } int main(){ char input[30]; FILE *fpin; printf("Please input the path of file that you want to compile:(C:\...)\n "); fflush(stdout); scanf("%s",input); if((fpin = fopen(input,"r")) != NULL) { printf("File open success!\n"); } else { printf("Path Error!\n\n"); fflush(stdout); } printf("****************Lexical analysis start*********************\n"); analyze(fpin); printf("****************Lexical analysis finish********************\n"); fclose(fpin); printf("File close success!"); return 0; }
参考资料:
[1]:https://www.cnblogs.com/ya-qiang/p/8987926.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。