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

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

相关文章

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意