编程语言试验之Antlr4+JavaScript实现"圈4"
参考: ANTLR4: Making a compiler with the JavaScript runtime
演示效果虽弱, 还是先上图吧:
在线演示: 地址.
下载到本地后在浏览器中打开"圈4.html"就可以在本地试验.
以后设计实现好语言后可以直接用静态网页作在线编程的演示, 觉得还蛮有用.
注: JS代码中各种不良操作(比如全局函数定义). 请勿作为JS学习材料使用. 与前文一样, 此文的目标不是一个实用的编程语言.
语法非常简单(圈4.g4), 只为演示之用. 前文编程语言试验之Antlr4+Java实现"圈2"有更多格式的解释:
grammar 圈4; 程序 : 求约数; 求约数 : '求约数' T数 ; T数 : [0-9]+ ; T空白 : [ \n\t]+ -> skip;
下面命令生成词法语法分析器相关JavaScript文件(圈4.tokens, 圈4Lexer.js, 圈4Lexer.tokens, 圈4Listener.js, 圈4Parser.js):
$ java -cp "antlr-4.7-complete.jar:$CLASSPATH" org.antlr.v4.Tool -Dlanguage=JavaScript 圈4.g4
作为解释器的"定制监听器.js":
var antlr4 = require('antlr4/index'); const 圈4Listener = require('./圈4Listener.js').圈4Listener 定制监听器 = function () { 圈4Listener.call(this); return this; } 定制监听器.prototype = Object.create(圈4Listener.prototype); 定制监听器.prototype.constructor = 定制监听器; /* 无需接口定义: enter程序/exit程序/enter求约数 */ 定制监听器.prototype.exit求约数 = function(上下文) { var 原数 = parseInt(上下文.getChild(1).getText()); document.getElementById("输出").innerHTML = 原数 + "的约数: " + 求约数(原数); }; function 求约数(原数) { var 约数 = []; for (var i = 1; i < 原数 - 1; i++) { if (原数 % i == 0) { 约数.push(i); } } return 约数; } exports.定制监听器 = 定制监听器;
读取文件输入, 调用附着了定制监听器的分析器"代码分析.js":
const antlr4 = require("antlr4/index") const 圈4Lexer = require("./圈4Lexer.js") const 圈4Parser = require("./圈4Parser.js") const 定制监听器 = require("./定制监听器.js").定制监听器 运行(); // TODO: 需改进-现为全局, 由于browserify function 运行() { var 代码 = document.getElementById('输入代码').value; var 输入流 = new antlr4.InputStream(代码) var 词法分析器 = new 圈4Lexer.圈4Lexer(输入流) var 词 = new antlr4.CommonTokenStream(词法分析器) var 语法分析器 = new 圈4Parser.圈4Parser(词) 语法分析器.buildParseTrees = true antlr4.tree.ParseTreeWalker.DEFAULT.walk(new 定制监听器(), 语法分析器.程序()) } window.运行 = 运行;
HTML界面"圈4.html":
<html> <head> <!-- defer原因: https://stackoverflow.com/a/26077148/1536803 不然需要document.ready判断 --> <script src="圈4.js" defer></script> </head> <body> <textarea id="输入代码">求约数50 </textarea> <button onclick="运行()">运行</button> <span id="输出"></span> </body> </html>
是的, 上面的"圈4.js"需要另行生成. 安装Browserify后运行:
$ browserify 代码分析.js > 圈4.js
2017-12-02
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Python3选择支持非ASCII码标识符的缘由
原文在: PEP 3131 -- Supporting Non-ASCII Identifiers. Python2并不支持非ASCII码标识符. PEP的全称是Python Enhancement Proposal, 即Python增强提案. 这个3131提案创建于2007年5月. Python3于2008年12月发布. Rationale一节开篇明义, 指出用母语命名标识符对代码清晰度和可维护性的提高. Python code is written by many people in the world who are not familiar with the English language, or even well-acquainted with the Latin writing system. Such developers often desire to define classes and functions with names in their native languages, rather than having to come up with an (of...
- 下一篇
编写Visual Studio Code插件初尝试
参考官方入门: Your First Visual Studio Code Extension - Hello World 源码在: program-in-chinese/vscode_helloWorld 创建插件过程中, 发现identifier和publisher name不允许中文命名(报错: invalid xxx): ? What type of extension do you want to create? New Extension (TypeScript) ? What's the name of your extension? 吃了么 ? What's the identifier of your extension? hello ? What's the description of your extension? 吃了么 ? What's your publisher name (more info: https://code.visualstudio.com/docs/tools/vscecli#_publishing-extensions)? nobody...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2全家桶,快速入门学习开发网站教程