ANTLR和网络:一个简单的例子

网络上的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。

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

Selection_052

这是此设计杰作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返回的树的结构。

Selection_054

显示结果

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

让我们得到这样的东西:

Selection_053

为此,我们基本上需要添加函数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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

下一秒

好想能看到 你嘴角微笑 最好在下一秒 好想能听到 你轻声歌唱 最好在下一秒 纯白棒球帽 墨绿色衣角 时间静止的美好 默契发生在每个下一秒 爱上同一种口味的蛋糕 不约而同哼唱一段曲调 喜欢这样看你傻傻的笑 好想能这样 就白头到老 最好从下一秒 转载于:https://www.cnblogs.com…

类加载器 jboss_JBoss AS 7类加载说明

类加载器 jboss这是示例章节&#xff0c;摘自Francesco Marchioni编辑的JBoss AS 7 Configuration Deployment and Administration一书&#xff0c;该书正在运行一个名为mastertheboss.com的JBoss门户。 根据Java EE规范的要求&#xff0c;理想情况下&#xff0c;应用程序服务器…

【转】Docker 容器化核心概念

DockerVM vs DockerDocker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。 示例一&…

弹簧活性样品

Spring-Reactive旨在为基于Spring的项目带来响应式编程支持 &#xff0c;并且有望在Spring 5的时间表中提供。 我的意图是使用此模型为REST端点行使一些非常基本的签名。 在继续之前&#xff0c;请允许我确认整个样本完全基于塞巴斯蒂安德勒兹&#xff08;SbastienDeleuze&…

团队作业_1_博客1(分工理解)

对于团队大作业分工&#xff08;服务端&#xff09;的理解&#xff1a; 这次大作业一经出炉&#xff0c;还是感觉很有意思的&#xff0c;虽然之前老师已经提及会出这么一个大作业来训练我们的能力&#xff0c;但是真的看到作业的出现&#xff0c;还是很惊喜的。 团队作业的分工…

pojo类继承pojo类_如何编写更好的POJO服务

pojo类继承pojo类在Java中&#xff0c;您可以轻松地在Plain Old Java Object&#xff08;POJO&#xff09;类中实现一些业务逻辑&#xff0c;并且可以在高级服务器或框架中轻松运行它们。 有许多服务器/框架&#xff0c;例如JBossAS&#xff0c;Spring或Camel等&#xff0c;它们…

国外机构操盘图

转载于:https://www.cnblogs.com/carl2380/p/9139020.html

代码气味–第二部分

在上一篇文章《代码气味–第一部分》中 &#xff0c;我谈到了膨胀器&#xff1a;它们是代码气味&#xff0c;可以识别为长方法&#xff0c;大型类&#xff0c;基元痴迷&#xff0c;长参数列表和数据块。 在这一篇中&#xff0c;我想深入研究面向对象的滥用者和变更阻止者 。 面…

solr 启动、停止

启动命令&#xff1a; solr start 停止命令 solr stop -all 转载于:https://www.cnblogs.com/yby120/p/9139791.html

第一篇博客测试

第一次发博客测试&#xff0c;看看都能进行什么操作。 再编辑一下&#xff0c;发表的时间就又改了&#xff1f; 没想到这个测试也有这么多人访问&#xff0c;那我把我的测试结果也贴出来供大家参考&#xff1a; 1. 无论怎么编辑&#xff0c;发表时间不会更改&#xff1b; 2. 编…

hadoop 提交程序并监控运行

程序编写及打包 使用maven导入第三方jar pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&qu…

digester_Apache Digester示例–轻松配置

digester解决问题–硬编码&#xff0c;需要为您的应用程序创建自定义配置&#xff0c;例如struts配置文件&#xff0c;仅通过更改文件即可改变应用程序的行为。 Apache Digester可以轻松为您完成此任务。 使用Apache Digester相当容易将XML文档转换为相应的Java bean对象层次结…

MFC状态栏编程(显示系统时间和进度条)

显示系统时间 1、 在状态栏中设置两个新的栏位Timer和Progress。首先到ResourceView中编辑String Table&#xff0c;增加IDS_TIMER(时间),PROGRESS(进度)。然后在MainFrame中修改indicators数组&#xff0c;插入IDS_TIMER和IDS_PROGRESS。插入的位置&#xff0c;即为显示的位置…

极光推送服务端API(定时推送任务,推送到指定设备,推送到所有设备)

极光推送常用的几个api方法总结&#xff0c;抽取出了utils类&#xff0c;利用MsgType进行业务类型区别&#xff0c;方便app端收到推送后进行不同处理&#xff1a; 首先引入依赖&#xff1a; <!-- 极光推送 --><dependency><groupId>cn.jpush.api</groupId…

Java 9附加流

Java 9即将发布&#xff01; 它不仅仅是Jigsaw项目 。 &#xff08;我也很惊讶。&#xff09;它给平台带来了很多小的变化&#xff0c;我想一一看一下。 我将标记所有这些帖子&#xff0c;您可以在这里找到它们。 让我们从…开始 流 Streams学习了两个新技巧。 第一个处理前缀…

MFC注册快捷键

1. 使用RegisterHotKey()注册快捷键&#xff1b;2. OnHotKey()函数中响应快捷键&#xff1b;3. 程序退出时&#xff0c;使用UnregisterHotKey(hWnd, m_HotKeyId)取消快捷键注册。

Hibernate---对象的三种状态

Hibernate---对象的三种状态 简而言之&#xff0c;hibernate本就是面向对象的基于ORM的框架&#xff0c;位于dao层&#xff0c;对数据进行操作的框架。我就谈谈hibernate的对象的三种状态。他们分别为&#xff1a;游离&#xff0c;持久和瞬时。通过代码来详解一下吧。 hibernat…

VS2008 C++ 项目添加“依赖”、“库目录”和“包含目录”

1. 添加编译所需要&#xff08;依赖&#xff09;的 lib 文件[解决方案资源管理器]“项目->属性->配置属性->连接器->输入->附加依赖项”里填写“winsock.lib”&#xff0c;多个 lib 以空格隔开。 &#xff08;等同于“#pragma comment(lib, "winsock.lib&q…

IDEA项目搭建四——使用Mybatis实现Dao层

一、引入mybatis及mysql的jar包 可以从阿里云上面查找版本&#xff0c;db操作放在dao层所以打开该层的pom.xml文件&#xff0c;找到<dependencies>节点增加两个引入 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifac…

连词我们…讨厌

最近&#xff0c;我写了与实现相关的名称&#xff0c;并提供了一些示例&#xff0c;这些示例由于方法名称与主体之间的紧密关系而导致方法名称不正确。 有一会儿&#xff0c;我们有以下代码&#xff1a; boolean isComplexOrUnreadableWithTests() { return (complex || unre…