前言
我是小学时候用易语言入门了编程, 用了一两年后, 由于切换到了Linux平台, 就再也没怎么用过易语言了. 最近打算复习一下编译原理, 所以决定用易语言实现一个易语言的虚拟机(自举), 并给易语言添加扩展语法, 让她现代化起来.
易语言社区关于计算机科学的东西太少了, 我来补充一些吧.
本篇内容
这里用易语言基于栈实现了一个带括号的四则运算文本解析工具来解析合法的表达式文本并求值, 一些输入输出为:
> 10 * (2 + 2) +2 * (808080 - 808080)遇到数: 1遇到数: 0遇到符: *准备合并, 当前操作数|操作符栈长度 1 | 1准备求值括号内容: 2 + 2) +2 * (808080 - 808080)遇到数: 2遇到符: +准备合并, 当前操作数|操作符栈长度 1 | 1遇到数: 2准备合并, 当前操作数|操作符栈长度 1 | 2准备合并, 当前操作数|操作符栈长度 0 | 1已食用文本: 2 + 2)遇到符: +准备合并, 当前操作数|操作符栈长度 2 | 2准备合并, 当前操作数|操作符栈长度 1 | 1遇到数: 2遇到符: *准备合并, 当前操作数|操作符栈长度 2 | 2准备求值括号内容: 808080 - 808080)遇到数: 8遇到数: 0遇到数: 8遇到数: 0遇到数: 8遇到数: 0遇到符: -准备合并, 当前操作数|操作符栈长度 1 | 1遇到数: 8遇到数: 0遇到数: 8遇到数: 0遇到数: 8遇到数: 0准备合并, 当前操作数|操作符栈长度 1 | 2准备合并, 当前操作数|操作符栈长度 0 | 1已食用文本: 808080 - 808080)准备合并, 当前操作数|操作符栈长度 2 | 3准备合并, 当前操作数|操作符栈长度 1 | 2准备合并, 当前操作数|操作符栈长度 0 | 110 * (2 + 2) +2 * (808080 - 808080) 之计算结果为 40> 1+1遇到数: 1遇到符: +准备合并, 当前操作数|操作符栈长度 1 | 1遇到数: 1准备合并, 当前操作数|操作符栈长度 1 | 2准备合并, 当前操作数|操作符栈长度 0 | 11+1 之计算结果为 2> 1+2*3遇到数: 1遇到符: +准备合并, 当前操作数|操作符栈长度 1 | 1遇到数: 2遇到符: *准备合并, 当前操作数|操作符栈长度 2 | 2遇到数: 3准备合并, 当前操作数|操作符栈长度 2 | 3准备合并, 当前操作数|操作符栈长度 1 | 2准备合并, 当前操作数|操作符栈长度 0 | 11+2*3 之计算结果为 7>
代码逻辑翻译自我过去用于给别人教编程时的Python代码:https://gist.github.com/myuanz/d7f43062d3ad2fe746469c27026147d6
原理
遇到每个字符前先判断是数字/算符/括号中哪个, 数字的话放到数字栈中, 算符放到算符栈中, 直到新的算符优先级<=前面的算符, 弹出计算前面的数和算符计算后再压入数字栈. 遇到左括号则将左括号后面的表达式作为本函数的参数传入, 得值后压入数字栈. 如此直到结束.
网上也有很多讲解的, 我随便找了个看着还行的:https://blog.csdn.net/qq_28602957/article/details/70948575
线路图
- 四则运算解析器
- 带更多函数的科学计算器
- Lisp 解析器
- Lisp 虚拟机
- 易语言语法解析和AST制定
- 易语言语法扩展(数组和字符串切片语法, Dict, 宏, 以及更多看情况的语法糖)
- 易语言翻译器(翻译到C/Zig lang/Python, 具体哪个尚未确定)
- 易语言虚拟机
线路图随时可能更改