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

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

相关文章

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。