基于JavaScript的简单解释器实现(一)——表达式的语法树生成

前言

这个系列是关于CodeWars上的一条1Kyu题:Simple Interactive Interpreter。也就是实现一个简单的交互式解释器。
题目地址:http://www.codewars.com/kata/52ffcfa4aff455b3c2000750/train/javascript
github地址:https://github.com/woodensail/SimpleInteractiveInterpreter
本文地址:http://segmentfault.com/a/1190000004044789

补充

11月26日更新:
增加了对左结合运算符的支持。
增加了变量统计功能,用于支持下一步的函数parser
当表达式不符合语法要求时,抛出异常

实现要求

具体的细节可以参见上面的原题网站,大概的要求如下:
1:支持变量赋值语句

x = 7

2:支持四则运算,表达式中可以使用变量

x = (1 + 2) * y

3:函数声明:

fn add x y => x + y

4:函数调用

z = add a b

5:其他
也就是命名冲突检测,作用域链等,大家自己看吧。

语法树

这一章主要是完成语法树的生成。其中由于函数声明部分过于简单,没必要生成语法树,打算留到下一章一起处理。所以只做了表达式的语法树生成。

首先,题目所给的语言结构基本上是前缀表达式和中缀表达式的混杂。所以只需要将语句里面中缀的部分转化为前缀即可得到波兰式。
当然,我为了方便下一步处理还是选择将其进一步转化为语法树的结构。但是实现思路依旧可以参考波兰式生成

准备工作

var SPACE = {}, params = [], operatorStack = [], dataStack = [SPACE], expressionFlag = true, lValue, rValue, operator, vars = {};

声明变量:
params 用于存储函数调用的参数,其实这里不需要初始化,但我懒得改了。
operatorStack 运算符栈,用于存储各种操作符
dataStack 存储数据。包括数值,变量以及语法树的节点
expressionFlag 由于改语言中没有逗号,所以没有显式的标志来分割相邻的两个表达式。因此需要自行判断前一个表达式是否结束。
lValue,rValue 类似params, 只不过是给运算符用的,其实可以去掉,但我懒得改。
operator 一个用于存储当前运算符的临时变量


tokens = tokens.slice();
tokens.push(')');
tokens.unshift('(');
while (tokens.length) {
  ……
}
var varList = [];
for (va
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值