网络上的ANTLR:为什么?

我开始在MS-DOS上编写我的第一个程序。 因此,我非常习惯在计算机上安装工具。 但是在2016年,网络无处不在,因此那里也可能需要我们的语言。

可能的情况:

  • ANTLR 也在网络上:

    • 用户可能还希望从网络访问DSL编写的较小更改文件,并可能对其进行细微更改,同时继续使用胖客户端执行复杂任务。
  • ANTLR 在网络上:
    • 您正在与不愿安装IDE的领域专家打交道,因此他们更喜欢使用一些Web应用程序编写DSL程序。

在第一种情况下,您可以使用Java目标 Javascript目标来生成ANTLR解析器,而在第二种情况下,您可以仅以JavaScript为目标

一个简单的例子:待办事项清单

在此示例中,我们将使用的DSL非常简单:它将表示一个待办事项列表,其中每个待办事项都包含在单独的行中,并以星号开头。

有效输入的示例:

* do this
* do that* do something else after an empty line

这是我们的语法:

grammar todo;elements: (element|emptyLine)* EOF;element: '*' ( ' ' | '\t' )* CONTENT NL+;emptyLine: NL;NL: '\r' | '\n' ;CONTENT: [a-zA-Z0-9_][a-zA-Z0-9_ \t]*;

使用ANTLR Javascript目标

您将需要安装ANTLR工具来为我们的解析器生成Javascript代码。 您可以使用简单的Gradle脚本来代替手动下载ANTLR及其依赖项。 更新所使用的ANTLR版本也非常简单。

apply plugin: 'java'repositories {jcenter()
}dependencies {runtime 'org.antlr:antlr4:4.5.2'
}task generateParser(type:JavaExec) {main = 'org.antlr.v4.Tool'classpath = sourceSets.main.runtimeClasspathargs = ['-Dlanguage=JavaScript', 'todo.g4', '-o', 'static/generated-parser']
}

您现在可以通过运行以下命令来生成解析器:

gradle generateParser

好的,这很简单。

调用解析器

不幸的是,仅打开本地文件时,我们使用的JS库无法正常工作:这意味着对于我们的小示例,我们也需要使用HTTP。 我们的Web服务器只需要提供大量静态文件即可。 为此,我选择在flask中编写一个超级简单的应用程序。 提供静态文件的替代方案有数百万种,因此请选择您喜欢的一种。 我不会在这里详细说明如何通过flask提供静态文件,但是GitHub上提供了代码,如果您对此有疑问,可以在此帖子中添加评论以告知我。

我们的静态文件将包括:

  • 通过运行gradle generateParser得到的生成的解析器
  • Antlr4 JS运行时
  • JS库require.js
  • HTML和CSS

您可以从此处获取Antlr4 JS运行时。 为了避免必须手动导入数十个文件,我们将使用require.js。 您可以从此处获取我们需要的口味或require.js。

我们将添加一个文本区域和一个按钮。 当用户单击按钮时,我们将解析文本区域的内容。 简单吧?

这是此设计杰作HTML代码:

<div id="inputs">
<textarea id="code">
* play with antlr4
* write a tutorial
</textarea>
<br/>
<button id="parse">Parse</button>
</div>

首先,导入require.js:

<script type="text/javascript" src="lib/require.js"></script>

顺便说一句,我们没有使用jQuery,我知道这可能令人震惊。

好,现在我们必须调用解析器

<script type="text/javascript">
var antlr4 = require('antlr4/index');
var TodoLexer = require('generated-parser/todoLexer');
var TodoParser = require('generated-parser/todoParser');
document.getElementById("parse").addEventListener("click", function(){var input = document.getElementById("code").value;var chars = new antlr4.InputStream(input);var lexer = new TodoLexer.todoLexer(chars);var tokens  = new antlr4.CommonTokenStream(lexer);var parser = new TodoParser.todoParser(tokens);parser.buildParseTrees = true;var tree = parser.elements();console.log("Parsed: "+ tree);
});
</script>

太好了,现在我们的代码已解析,但是我们不对其执行任何操作。 当然,我们可以在浏览器中启动开发者控制台,并打印有关树的一些信息,以验证树是否正常工作并熟悉ANTLR返回的树的结构。

显示结果

如果我们正在构建某种TODO应用程序,我们可能希望以某种方式表示用户通过DSL插入的信息。

让我们得到这样的东西:

为此,我们基本上需要添加函数updateTree来导航由ANTLR返回的树,并构建一些DOM节点来表示其内容

<script type="text/javascript">
var updateTree = function(tree, ruleNames) {var container = document.getElementById("tree");while (container.hasChildNodes()) {container.removeChild(container.lastChild);}for (var i = 0; i < tree.children.length; i++) {var child = tree.children[i];var nodeType = ruleNames[child.ruleIndex];if (nodeType == "element") {var newElement = document.createElement("div");newElement.className = "todoElement";var newElementText = document.createTextNode(child.children[2].getText());newElement.appendChild(newElementText);container.appendChild(newElement);}}
};var antlr4 = require('antlr4/index');
var TodoLexer = require('generated-parser/todoLexer');
var TodoParser = require('generated-parser/todoParser');
document.getElementById("parse").addEventListener("click", function(){var input = document.getElementById("code").value;var chars = new antlr4.InputStream(input);var lexer = new TodoLexer.todoLexer(chars);var tokens  = new antlr4.CommonTokenStream(lexer);var parser = new TodoParser.todoParser(tokens);parser.buildParseTrees = true;var tree = parser.elements();console.log("Parsed: "+ tree);updateTree(tree, parser.ruleNames);
});
</script>

干得好!

如果这不是您第一次阅读此博客,则可能会怀疑某些代码即将到来。 和往常一样,代码在GitHub上: https : //github.com/ftomassetti/antlr-web-example

下一步

下一步是执行错误处理:我们要捕获错误并将其指向用户。 然后,我们可能想通过使用ACE来添加语法突出显示。 这似乎是一个很好的起点:

  • https://github.com/antlr/antlr4/blob/master/doc/ace-javascript-target.md

我真的认为简单的文本DSL可以帮助使多个应用程序更加强大。 但是,在网络上创建良好的编辑体验并非易事。 我想花更多时间玩这个。

翻译自: https://www.javacodegeeks.com/2016/05/antlr-web-simple-example.html

ANTLR和网络:一个简单的例子相关推荐

  1. antlr4例子_ANTLR和网络:一个简单的例子

    antlr4例子 网络上的ANTLR:为什么? 我开始在MS-DOS上编写我的第一个程序. 因此,我非常习惯在自己的机器上安装工具. 但是在2016年,网络无处不在,因此那里也可能需要我们的语言. 可 ...

  2. .net中的对象序列化(1): 序列化是什么, 以及一个简单的例子

    1. 为什么需要序列化,什么是序列化 对于一个程序来说, 使用到的对象都是存在于内存中的.如果想保存这些对象的运行时状态, 或者需要在不同进程或者网络间传递对象,就需要序列化. 序列化就是讲运行中的对 ...

  3. blockchain 区块链200行代码:在JavaScript实现的一个简单的例子

    blockchain 区块链200行代码:在JavaScript实现的一个简单的例子 了解blockchain的概念很简单(区块链,交易链块):它是分布式的(即不是放置在同一台机器上,不同的网络设备上 ...

  4. 一步一步解读神经网络编译器TVM(一)——一个简单的例子

    @TOC 前言 这是一个TVM教程系列,计划从TVM的使用说明,再到TVM的内部源码?为大家大致解析一下TVM的基本工作原理.因为TVM的中文资料比较少,也希望贡献一下自己的力量,如有描述方面的错误, ...

  5. 一个简单的例子看java线程机制

    一个简单的例子看java线程机制 作者: zyf0808 发表日期: 2006-03-26 11:20 文章属性: 原创 复制链接 import java.util.*; public class T ...

  6. pycharm安装scrapy失败_Scrapy ——环境搭配与一个简单的例子

    在我刚接触爬虫的时候就已经听过Scrapy大名了,据说是一个很厉害的爬虫框架,不过那个时候沉迷于Java爬虫.现在终于要来揭开它神秘的面纱了,来一起学习一下吧 欢迎关注公众号:老白和他的爬虫 1.环境 ...

  7. java继承类型转换_#java 一个简单的例子理解java继承、成员函数重写、类型转换...

    一个简单的例子理解java继承.成员函数重写.类型转换 1.继承简介 举一个简单的例子:笔分为很多种,比如毛笔.钢笔.圆珠笔等等,这些笔都有一些相同的属性比如长度.笔迹的粗细等等:但他们也有不同的特点 ...

  8. 类模板与运算符重载(一个简单的例子)

    类模板与运算符重载(一个简单的例子) 标签(空格分隔): C++ 算法竞赛 下面是一段简单的代码,表示我们建立了一个类模板Vector,可以看做是对STL中vector的简单实现. 为了让这个Vect ...

  9. 一个简单的例子,学习自定义注解和AOP

    转载自   一个简单的例子,学习自定义注解和AOP 记得今年年初刚开始面试的时候,被问的最多的就是你知道Spring的两大核心嘛?那你说说什么是AOP,什么是IOC?我相信你可能也被问了很多次了. 1 ...

最新文章

  1. 转载-如何应对在线故障
  2. Redis configuration
  3. java数据结构至对称矩阵压缩存储
  4. Python教程:快速掌握列表的常用方法
  5. Grafana Worldmap外网用户request地图监控
  6. HTML5+NodeJs实现WebSocket即时通讯
  7. linux wenj 立即生效_【新书连载】测试工程师核心开发技术(3)—远程登录Linux系统...
  8. LeetCode 775. 全局倒置与局部倒置(归并排序/二分查找/一次遍历)
  9. localdatetime 默认时间_java中的时间与时区:LocalDateTime和Date
  10. 网络压缩《network pruning 浅析》
  11. 基于php计算机等级考试系统毕业设计网站作品
  12. 交互软件Axure—高保真原型
  13. linux配置maven环境变量
  14. 软件测试工程师绩效考核细则,软件测试工程师绩效考核方案
  15. 安装 3dsMax 2020 错误 1625 系统策略禁止这个安装
  16. 装linux系统的工具箱,PE,Dos工具箱,自动安装linux的U盘制作
  17. 3、Latex学习笔记之表格篇
  18. 黑苹果传统BIOS引导安装
  19. 计算机教师使用计划书,信息技术教师个人发展计划
  20. oracle 监控内存和硬盘的排序比率_最好使它小于 .10,监控数据库性能的SQL

热门文章

  1. JVM内存管理------GC算法精解(五分钟让你彻底明白标记/清除算法)
  2. Java GC系列(4):垃圾回收监视和分析
  3. 面象对象设计6大原则之二:开放封闭原则
  4. 神奇,教你用随机数打印hello world
  5. Util包中Arrays
  6. java中如何对对象排序?
  7. 就业形势如此的严峻,你为何不努力?
  8. 深入C#中的String类
  9. 《线性代数及其应用》
  10. gc 堆外_GC解释:堆