编译原理【c语言实现】将四则运算中缀表达式(带括号,有空格,有变量)化为后缀表达式

本文主要是介绍编译原理【c语言实现】将四则运算中缀表达式(带括号,有空格,有变量)化为后缀表达式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

示范1

输入中缀

var+2 +33

输出后缀

var 2 + 33 +

示范2

中缀

((1+3)*2 + 5)*33

后缀

1 3 + 2 * 5 + 33 *

思路

等以后有时间我会完善。整体受到编译原理教材的启示。关键就是写出左递归的产生式,然后消除左递归,表示成容易用程序实现的方式。

代码

/*  左递归expr -> expr + term  		{print(‘+’)}        | expr - term    		{print(‘-’)}| termterm -> term * factor 		{print(‘*’)}        |  term / factor 		{print(‘/’)}        |  factorfactor -> (expr)|  id				{ print(lexeme) }        |  num				{ print(tokenval) }
-----------------------------------------------------消除左递归后expr -> term restrest -> + term 	print{('+')} 	rest| - term 	print{('-')} 	rest| 空term   -> factor rest2rest2  -> * factor 	print{('*')} rest2| / factor 	print{('/')} rest2| 空factor -> (expr)| id            	{print(id)}| num           	{print(num)
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>using namespace std;#define TKN_NUM  500
#define TKN_ID   600int LookAhead; //词法单元类型
char lexeme[1000];//词素
int tokenval = 0; //记录完整的数值
int getToken();
void Match(int i);
void factor();
void rest2();
void term();
void rest();
void expr();int getToken(){int i, t;while(1){t = getchar();if(t == ' ' || t == '\t');else if(isdigit(t)){tokenval = 0;do {tokenval = tokenval * 10 + t -'0';t = getchar();} while (isdigit(t));ungetc(t, stdin); //把字符 char(一个无符号字符)推入到指定的流 stream 中,以便它是下一个被读取到的字符。即回退return TKN_NUM;}else if(isalpha(t)){i = 0;do {lexeme[i++]=t;t = getchar(); }while( isalpha(t) || isdigit(t) );lexeme[i]='\0'; ungetc(t, stdin);//回退return TKN_ID;}else{tokenval = 0;return t; //+ - * / ( ).etc}}
}
void Match(int i){if(i == LookAhead){LookAhead = getToken();}else{printf("\nmatch error\n", i);exit(1);}
}
void factor(){if( LookAhead==TKN_NUM) {printf("%d ",tokenval); Match(LookAhead); }else if( LookAhead==TKN_ID) {printf("%s ",lexeme); Match(LookAhead);}else if( LookAhead == '('){//stack_.push_back('(');LookAhead = getToken();expr();if(LookAhead != ')'){printf("\nBracket mismatch\n" );exit(1); //结束程序}LookAhead = getToken();}else{printf("\nerror\n" );exit(1); //结束程序}
}
void rest2(){switch( LookAhead ) {case '*':Match('*'); factor(); printf("* "); rest2(); // rest --> + term {print('+')} restbreak;case '/':Match('/'); factor(); printf("/ "); rest2(); // rest --> - term {print('-')} restbreak;default:   // rest --> 空break;}
}
void term(){factor();rest2();
}
void rest(){switch(LookAhead){case '+':Match('+'); term(); printf("+ "); rest();break;case '-':Match('-'); term(); printf("- ");rest();default: break;}
}
void expr(){term();rest();
}
int main(){printf("Input inOrder expression:\n");LookAhead = getToken();printf("postOrder is:\n");expr();return 0;
}

测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这篇关于编译原理【c语言实现】将四则运算中缀表达式(带括号,有空格,有变量)化为后缀表达式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Go语言使用sync.Mutex实现资源加锁

《Go语言使用sync.Mutex实现资源加锁》数据共享是一把双刃剑,Go语言为我们提供了sync.Mutex,一种最基础也是最常用的加锁方式,用于保证在任意时刻只有一个goroutine能访问共享... 目录一、什么是 Mutex二、为什么需要加锁三、实战案例:并发安全的计数器1. 未加锁示例(存在竞态)

基于Redisson实现分布式系统下的接口限流

《基于Redisson实现分布式系统下的接口限流》在高并发场景下,接口限流是保障系统稳定性的重要手段,本文将介绍利用Redisson结合Redis实现分布式环境下的接口限流,具有一定的参考价值,感兴趣... 目录分布式限流的核心挑战基于 Redisson 的分布式限流设计思路实现步骤引入依赖定义限流注解实现

SpringBoot实现虚拟线程的方案

《SpringBoot实现虚拟线程的方案》Java19引入虚拟线程,本文就来介绍一下SpringBoot实现虚拟线程的方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录什么是虚拟线程虚拟线程和普通线程的区别SpringBoot使用虚拟线程配置@Async性能对比H

C语言自定义类型之联合和枚举解读

《C语言自定义类型之联合和枚举解读》联合体共享内存,大小由最大成员决定,遵循对齐规则;枚举类型列举可能值,提升可读性和类型安全性,两者在C语言中用于优化内存和程序效率... 目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.2.1 特点11.2.2 特点21.2.3 特点31.3 联合体的大小1

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

基于Python实现进阶版PDF合并/拆分工具

《基于Python实现进阶版PDF合并/拆分工具》在数字化时代,PDF文件已成为日常工作和学习中不可或缺的一部分,本文将详细介绍一款简单易用的PDF工具,帮助用户轻松完成PDF文件的合并与拆分操作... 目录工具概述环境准备界面说明合并PDF文件拆分PDF文件高级技巧常见问题完整源代码总结在数字化时代,PD

Python实现Word转PDF全攻略(从入门到实战)

《Python实现Word转PDF全攻略(从入门到实战)》在数字化办公场景中,Word文档的跨平台兼容性始终是个难题,而PDF格式凭借所见即所得的特性,已成为文档分发和归档的标准格式,下面小编就来和大... 目录一、为什么需要python处理Word转PDF?二、主流转换方案对比三、五套实战方案详解方案1:

SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南

《SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南》本文将基于开源项目springboot-easyexcel-batch进行解析与扩展,手把手教大家如何在SpringBo... 目录项目结构概览核心依赖百万级导出实战场景核心代码效果百万级导入实战场景监听器和Service(核心

C# async await 异步编程实现机制详解

《C#asyncawait异步编程实现机制详解》async/await是C#5.0引入的语法糖,它基于**状态机(StateMachine)**模式实现,将异步方法转换为编译器生成的状态机类,本... 目录一、async/await 异步编程实现机制1.1 核心概念1.2 编译器转换过程1.3 关键组件解析

setsid 命令工作原理和使用案例介绍

《setsid命令工作原理和使用案例介绍》setsid命令在Linux中创建独立会话,使进程脱离终端运行,适用于守护进程和后台任务,通过重定向输出和确保权限,可有效管理长时间运行的进程,本文给大家介... 目录setsid 命令介绍和使用案例基本介绍基本语法主要特点命令参数使用案例1. 在后台运行命令2.