JavaScript实现ZLOGO: 用语法树实现多层循环

  • 日期:09-09
  • 点击:(1172)


像往常一样,首先展示弱效果图。演示地址仍然与:相同

代码如下:

开始循环4次循环4次前进50左转90度到目前为止,向右转90度结束复制代码

JavaScript实现ZLOGO子集: 测试用例末尾所述,本文使用Antlr进行代码分析以生成语法树。然后通过语法树生成p5js绘图代码。

Antlr支持两种代码分析方法:访问者(访问者)和访问者(访问者)。 SOAntlr4 Listeners and Visitors - which to implement?上的问答粗略地说明了差异。基于有限的实践,使用Visitor方法生成语法树似乎更方便实现。特别是,listener + stack用于在Creating a simple parser with ANTLR中构建语法树。

默认情况下,Antlr生成工具不会生成访问者。添加-visitor参数后,它可以生成:

Java -cp'ntrrr-4.7-complete.jar: $ CLASSPATH'org.antlr.v4.Tool -Dlanguage=JavaScript -visitor Circle 3.g4 copy code

以下是构建语法树的'custom accessor.js'的一部分,它似乎比实现更简单。默认生成'circle 3Visitor',visitXX方法实现是'this.visitChildren(ctx)',但是会将所有子节点返回值放入数组中,形成(至少在这里)额外级别:

自定义accessor.prototype.visit program=function {grammar tree={child node: this.visit(context.declaration())};返回语法树;}; custom accessor.prototype.visit loop=function(Context){return {type:'loop',number: parseInt(context.T number()。getText()),child node: this.visit(context.declaration()) };};自定义accessor.prototype。访问语句=function {return this.visit(context.getChild(0));}; custom accessor.prototype.visit turn=function(context){var direction=context.T turn()。getText()Var angle=parseInt(context.T number()。getText())*(direction==='left '?1: -1); return {type:'turn',参数: angle};};自定义访问.prototype.visit forward=function(context){return {type:'forward',argument: parseInt(context.T number()。getText())};};复制代码

上面的源代码生成语法树大致如下。在实施方面仍有许多改进,例如“前进”和“转动”现在是两种类型,但它应该是一种;根节点类型不应为空;依此类推:

f534387f130e42f59c444d5c5eb6c6c4

以下是在“编译”中基于语法树生成指令列表的方法。 js',然后像以前一样根据指令列表生成p5js绘图函数(代码不需要修改)。

函数生成指令序列(节点){var instruction sequence=[]; //如果(!Node.type){var declares node=node,则TODO:根节点类型不应为空。子节点; for(var I=0; I< declares node.length; I +){Array else。原型。推。 apply(指令序列,生成指令序列(声明节点[i]);} i} F(node.type='loop'){var instruction sequence=[]; for(var I=0; I< number of number节点; I +){数组。原型。推送。应用(指令序列,生成指令序列({子节点:节点。子节点});} ///TODO:修改类型统一为'指令别'( node.type='forward'| node.type)。=='Turn'){return [{Name:(Node.Type='Forward'?Constant_Instruction Name_Forward: Constant_Instruction Name_Turn),Parameter: Node.Parameter}];}返回指令序列;}复制代码

修改相应的测试用例,并清理不再使用的侦听器代码。代码已经从访问者分支(program-in-chinese/quan3分享Java,Spring,MyBatis,Netty源代码分析,高并发,高性能,分布式,微服务架构原则,JVM性能优化,分布式架构,BATJ访谈等信息。

转发此文,关注并私信小编“学习”web前端课程资料马上免费领取

http://www.sugys.com/bds83N2d