算符优先语法分析程序设计与实现

制作一个简单的C语言词法分析程序_用c语言编写词法分析程序-CSDN博客文章浏览阅读378次。C语言的程序中,有很单词多符号和保留字。一些单词符号还有对应的左线性文法。所以我们需要先做出一个单词字符表,给出对应的识别码,然后跟据对应的表格来写出程序。_用c语言编写词法分析程序https://blog.csdn.net/lijj0304/article/details/134078944前置程序词法分析器参考这个帖子⬆️

1.程序目标

算符优先语法分析程序,程序可以识别实验1的输出文件中的二元序列,然后通过已经构造好的优先关系矩阵,分析算式是否是正确的,并且能够返回错误的位置。算式的语法如下:

G[E]:EE+TE-TT

         TT*FT/FF

         F(E)i

2.程序设计

算符优先部分是通过构造一个二维数组实现,数组中存储了关系矩阵相关的信息。-1表示移进操作,1表示规约操作,0表示先移进后规约。矩阵当中的2表示算符优先矩阵中不存在这个两者关系,程序识别到这个位置时应当返回错误。程序中还用到了栈的数据结构来辅助运算。其中移进时需要实现入栈操作,而规约时需要实现出栈操作,且最后栈为空时则是识别成功。

3.算符优先分析

1. 首先我根据给定的语法,计算处所需要用到的firstvt集和lastvt集

firstvt(E) = {+, -, *, /, (, i}

firstvt(T) = {*, /, (, i}

firstvt(F) = {(, i}

lastvt(E) = {+, -, *, /, }, i}

lastvt(T) = {*, /, ), i}

lastvt(F) = {), i}

2. 接着可以计算出这个语法的算符优先表

+

-

*

/

(

)

i

#

+

>

>

<

<

<

>

<

>

-

>

>

<

<

<

>

<

>

*

>

>

>

>

<

>

<

>

/

>

>

>

>

<

>

<

>

(

<

<

<

<

<

=

<

)

>

>

>

>

>

>

i

>

>

>

>

>

>

#

<

<

<

<

<

<

=

3. 再得到关系矩阵

+

-

*

/

(

)

i

#

+

1

1

-1

-1

-1

1

-1

1

-

1

1

-1

-1

-1

1

-1

1

*

1

1

1

1

-1

1

-1

1

/

1

1

1

1

-1

1

-1

1

(

-1

-1

-1

-1

-1

0

-1

-2

)

1

1

1

1

-2

1

-2

1

i

1

1

1

1

-2

1

-2

1

#

-1

-1

-1

-1

-1

-2

-1

0

4.完整程序

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_LEN 1000
char str[MAX_LEN];
char stack[MAX_LEN];
int top = 0;//+, -, *, /, (, ), i, #
int table[8][8] =  {{ 1, 1,-1,-1,-1, 1,-1, 1}, // +{ 1, 1,-1,-1,-1, 1,-1, 1}, // -{ 1, 1, 1, 1,-1, 1,-1, 1}, // *{ 1, 1, 1, 1,-1, 1,-1, 1}, // /{-1,-1,-1,-1,-1, 0,-1,-2}, // ({ 1, 1, 1, 1,-2, 1,-2, 1}, // ){ 1, 1, 1, 1,-2, 1,-2, 1}, // i{-1,-1,-1,-1,-1,-2,-1, 0}};// #int getindex(char ch) {switch(ch) {case '+': return 0;case '-': return 1;case '*': return 2;case '/': return 3;case '(': return 4;case ')': return 5;case 'i': return 6;case '#': return 7;default: return -1;}
}int OPG(char *str, char *stack) {int i = 0;while(i < strlen(str)) {if(top < 0) return 0;int x = getindex(stack[top]);int y = getindex(str[i]);if(x == -1 || y == -1) {return 0;}if(table[x][y] == -1) {stack[++top] = str[i];printf("%c -> ", str[i++]);}else if(table[x][y] == 1) {top--;}else if(table[x][y] == 0) {top--;printf("%c -> ", str[i++]);}else if(table[x][y] == -2) {return 0;}}if(top+1 == 0) return 1;else return 0;
}int main() {for(int m = 5; m <= 8; m++) {printf("test%d:\n", m);char txt[] = "./lexical/analyze";char num[6];sprintf(num, "%d.txt", m);strcat(txt, num);FILE *fp = fopen(txt, "r");char buf[MAX_LEN] = "";char input[MAX_LEN] = "";fgets(buf, MAX_LEN, fp);int i = 0, j = 0;for(int k = 0; k < strlen(buf); k++) {if(buf[k] == '1' && buf[k+1] == ',') {str[i++] = 'i';k += 3;while(1) {if(buf[k] == ')' && buf[k+1] == ' ')break;input[j++] = buf[k++];}continue;}if(buf[k] == ',' && buf[k+1] == ' ') {k += 2;while(1) {if(buf[k] == ')' && buf[k+1] == ' ')break;str[i++] = buf[k];input[j++] = buf[k++];}}}printf("Input scentence: %s\n", input);str[i] = '#';printf("str: %s\n", str);fclose(fp);stack[0] = '#', top = 0;if(OPG(str, stack)) {printf("end\n");printf("Gramma legal: %s\n", str);}else {printf("error\n");printf("Gramma illegal\n");}}return 0;
}

5.测试程序

tets1:a+b/c-d*e/f

test2:(a+b+c)/d-e-f+(g+h/j)

test3:(a+b*c)/d)+e-f

test4:a*/c+d/(e*f)

程序1分析结果:

analyze1:

(1, a) (44, +) (1, b) (38, /) (1, c) (47, -) (1, d) (50, *) (1, e) (38, /) (1, f)

analyze2:

(16, () (1, a) (44, +) (1, b) (44, +) (1, c) (17, )) (38, /) (1, d) (47, -) (1, e) (47, -) (1, f) (44, +) (16, () (1, g) (44, +) (1, h) (38, /) (1, j) (17, ))

analyze3:

(16, () (1, a) (44, +) (1, b) (50, *) (1, c) (17, )) (38, /) (1, d) (17, )) (44, +) (1, e) (47, -) (1, f)

analyze4:

(1, a) (50, *) (38, /) (1, c) (44, +) (1, d) (38, /) (16, () (1, e) (50, *) (1, f) (17, ))

程序3运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/247662.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6、原型模式(Prototype Pattern,不常用)

原型模式指通过调用原型实例的Clone方法或其他手段来创建对象。 原型模式属于创建型设计模式&#xff0c;它以当前对象为原型&#xff08;蓝本&#xff09;来创建另一个新的对象&#xff0c;而无须知道创建的细节。原型模式在Java中通常使用Clone技术实现&#xff0c;在JavaSc…

Java架构师技术架构路线

目录 1 概论2 如何规划短中长期的技术架构路线图3 如何规划面向未来的架构4 如何修订路线图执行过程中的偏差5 如何落地路线图-阿里系糙快猛之下的敏捷模式想学习架构师构建流程请跳转:Java架构师系统架构设计 1 概论 首先,规划一个短中长期的技术路线图是非常重要的。短中…

创新领航 | 竹云参编《基层智治系统安全接入规范》团体标准正式发布!

近日&#xff0c;由杭州市委办公厅&#xff08;市密码管理局&#xff09;、杭州市基层治理综合指挥保障中心、杭州市拱墅区社会治理中心、杭州市拱墅区数据资源管理局、杭州竹云数字智能科技有限公司、杭州智诚质量标准技术评定中心共同参与编写的《基层智治系统安全接入规范》…

【Linux下如何生成coredump文件】

一&#xff0c;什么是coredump 我们经常听到大家说到程序core掉了&#xff0c;需要定位解决&#xff0c;这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止&#xff0c;并且在满足一定条件下&#xff08;这里为什么说需要满足一定的条件呢&#…

快速处理Python爬虫:异步和缓存技巧

在当今的数字化时代&#xff0c;数据是商业的核心&#xff0c;而爬虫程序是获取数据的重要工具。Python作为一种流行的编程语言&#xff0c;提供了许多库以方便快捷地创建爬虫程序。本文将探讨如何使用Python快速处理爬虫的异步和缓存技巧。 异步处理 Python的异步处理主要通…

Python小案例:打印10以内的素数

解析 1、利用循环控制范围&#xff08;1,100&#xff09; 2、通过循环判断素数 3、利用标记法进行打印素数 代码 #求1——100之间的素数 for i in range(2,101):is_primeNum Truefor j in range(2,i):if i%j 0:# print(f"{i}不是素数")is_primeNum Falseif is_…

任意文件上传漏洞实战和防范

文件上传漏洞广泛存在于Web1.0时代&#xff0c;恶意攻击者的主要攻击手法是将可执行脚本&#xff08;WebShell&#xff09;上传至目标服务器&#xff0c;以达到控制目标服务器的目的。 此漏洞成立的前提条件至少有下面两个&#xff1a; 1.可以上传对应的脚本文件&#xff0c;…

探索 SSO 的世界:简化登录流程的最佳实践(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

前端——html拖拽原理

文章目录 ⭐前言⭐draggable属性&#x1f496; api&#x1f496; 单向拖动示例&#x1f496; 双向拖动示例 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 前端——html拖拽原理。 vue3系列相关文章&#xff1a; vue3 fastapi 实现选择目录所有文…

LoadBalancer将服务暴露到外部实现负载均衡Openelb-layer2模式配置介绍

目录 一.openelb简介 二.主要介绍layer2模式 1.简介 2.原理 3.部署 &#xff08;1&#xff09;先在集群master上开启kube-proxy的strictARP &#xff08;2&#xff09;应用下载openelb.yaml&#xff08;需要修改镜像地址&#xff09; &#xff08;3&#xff09;编写yam…

mysql有哪些锁,理解各种表锁和行锁

全局锁 主要用于数据库的备份&#xff0c;但会使得备份期间不能有任何事务插入删除更新数据&#xff0c;这很影响实际业务。所以通常不用这个全局锁来完成数据库的备份。假设数据库的存储引擎支持可重复读&#xff0c;那么常见的方法是通过MVCC来实现的&#xff0c;也就是备份…

ADAudit Plus:强大的网络安全卫士

随着数字化时代的不断发展&#xff0c;企业面临着越来越复杂和多样化的网络安全威胁。在这个信息爆炸的时代&#xff0c;保护组织的敏感信息和确保网络安全已经成为企业发展不可或缺的一环。为了更好地管理和监控网络安全&#xff0c;ADAudit Plus应运而生&#xff0c;成为网络…