【编译原理】一个词法分析器源码的剖析

2024-04-05 01:58

本文主要是介绍【编译原理】一个词法分析器源码的剖析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一,词法分析器

        作用:读取源程序的输入字符、将他们组成词素,生成并输出一个词法单元序列

二,设计原理

        1)C程序语言的符号分类:关键字、标识符、常数、运算符、界符

        2)词法分析器的二元输出:<单词种别,单词符号属性值>

        3)正规式和状态转换图

 

           4)程序说明:

                               1>main 中打开源码文件,从第一个字符流读取

                               2>如果第一个是字符,则交给letterprocess(str); 处理

                               3>如果第一个是数字,则交给numberprocess(str); 处理

                               4>如果第一个是数字,则交给otherprocess(str); 处理

                               5>注意上述过程中,File *fp每读取一个词素,fp都会移动到下一个词素。对于空格的处理:isspace(ch)检查参数c是否为空格字符,也就是判断是否为空格('')、定位字符

  ('\t')、CR('\r')、换行('\n')、垂直定位字符('\v')或 翻页('\f')的情况

                 这个程序输出结果情况汇总:关键字、算术运算符、关系运算符、分割符号、特殊符号、注释符号、逻辑运算符、非法符号

三,程序源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <conio.h>
#define NULL 0
FILE *fp;
char ch;
char *keyword[34]={"auto","break","case","char","const","continue","default","do","double", 
"else","enum","extern","float","for","goto","if","int","long","register", 
"return","short","signed","sizeof","static","struct","switch","typedef", "printf",
"union","unsigned","void","volatile","while","main"};
char *operatornum[6]={"+","-","*","/","++","--"};
char *comparison[8]={"<","<=","=",">",">=","<>","==","!="};
char *interpunction[8]={",",";",":=",".","(",")","{","}"};
char *biaoshifu[6]={"%","$","^","&","_","#"};//特殊标识符
char *zhushifu[3]={"//","/*","*/"};//注释符
char *luoji[3]={"&&","||","!"};//逻辑运算符bool search(char searchstr[],int wordtype)//符号匹配 
{int i;switch (wordtype){case 1:for(i=0;i<=33;i++){if(strcmp(keyword[i],searchstr)==0)return(true);}break;case 2:for(i=0;i<=5;i++){if(strcmp(operatornum[i],searchstr)==0)return(true);}break;case 3: for(i=0;i<=7;i++){if(strcmp(comparison[i],searchstr)==0)return(true);}break;case 4: for(i=0;i<=7;i++){if(strcmp(interpunction[i],searchstr)==0)return(true);}break;case 5: for(i=0;i<=5;i++){if(strcmp(biaoshifu[i],searchstr)==0)return(true);}break;case 6:for(i=0;i<=2;i++){if(strcmp(zhushifu[i],searchstr)==0)return(true);}break;case 7: for(i=0;i<=2;i++){if(strcmp(luoji[i],searchstr)==0)return(true);}break;}return false;
}char letterprocess (char ch)//字母处理函数
{int i=-1;char letter[20];while (isalnum(ch)!=0){letter[++i]=ch;ch=fgetc(fp);}letter[i+1]='\0';if (search(letter,1)){printf("<%s,关键字>\n",letter);//strcat(letter,"\n");//fputs('<' letter '>\n',outp);}else{printf("<%s,自定义变量>\n",letter);//strcat(letter,"\n");//fputs(letter,outp);}return(ch);
}char numberprocess(char ch)//数字处理程序
{int i=-1;char num[20];while (isdigit(ch)!=0){num[++i]=ch;ch=fgetc(fp);}if(isalpha(ch)!=0)//数字后面是字符 {while(isspace(ch)==0){num[++i]=ch;ch=fgetc(fp);}num[i+1]='\0';printf("错误!非法标识符:%s\n",num);goto u;}num[i+1]='\0';printf("<%s,数字>\n",num);u: return(ch);
}char otherprocess(char ch)//其他处理程序 
{int i=-1;char other[20];if (isspace(ch)!=0){ch=fgetc(fp);goto u;}while ((isspace(ch)==0)&&(isalnum(ch)==0)){other[++i]=ch;ch=fgetc(fp);}other[i+1]='\0';if (search(other,2))printf("<%s,算数运算符>\n",other);else if (search(other,3))printf("<%s,关系运算符号>\n",other);else if (search(other,4))printf("<%s,分隔符号>\n",other);else if (search(other,5))printf("<%s,特殊标识符号>\n",other);else if (search(other,6))printf("<%s,注释符号>\n",other);else if (search(other,7))printf("<%s,逻辑运算符号>\n",other);else printf("错误!非法字符:%s\n",other);u: return (ch);
}int main ()
{char str;printf("**********************************词法分析器************************************\n");if ((fp=fopen("源程序.txt","r"))==NULL)printf("源程序无法打开!\n");else{str =fgetc(fp);//从流中读取字符 while (str!=EOF){if (isalpha(str)!=0)//如果是字符    isalpha包含在#include <cctype>str=letterprocess(str);else{if (isdigit(str)!=0)str=numberprocess(str);elsestr=otherprocess(str);}};printf("词法分析结束,谢谢使用!\n");//printf("点任意键退出!\n");}//c=getch();return 0;
}


这篇关于【编译原理】一个词法分析器源码的剖析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877374

相关文章

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

MySQL中的MVCC底层原理解读

《MySQL中的MVCC底层原理解读》本文详细介绍了MySQL中的多版本并发控制(MVCC)机制,包括版本链、ReadView以及在不同事务隔离级别下MVCC的工作原理,通过一个具体的示例演示了在可重... 目录简介ReadView版本链演示过程总结简介MVCC(Multi-Version Concurr

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一