ANTLR和Jetbrains MPS:解析文件并以树符号显示AST

Itemis再次这样做:他们刚刚为Jetbrains MPS发布了一个非常酷的新插件。 这允许定义新的树编辑器。

他们看起来像这样:

AST

在这篇文章中,我们将看到:

  • 如何在MPS中使用ANTLR解析器
  • 如何使用树符号表示已解析的AST

特别是,我们将使用解析ANTLR语法的ANTLR语法。 那是元吗? 当然,每个ANTLR语法都可以使用相同的方法。

GitHub上始终提供代码 。

依存关系

首先,您需要安装Jetbrains MPS。 在这里获取免费副本。

要使用树符号,您应该安装mbeddr平台。 只需转到此处 ,下载zip并将其解压缩到MPS安装的插件中​​即可。

全部设置好了,该做些编程了。

包装ANTLR以在MPS内部使用

在上一篇文章中,我们讨论了如何使用Gradle在Java项目中使用现有的ANTLR语法。 我们还将在此处应用该技术。

我们首先从此处下载语法: https : //github.com/antlr/grammars-v4/tree/master/antlr4

通过将LexBasic直接包含到ANTLRv4Lexer中,我们进行了一些小的更改。 注意,我们还需要LexerAdaptor 。

为了简化用法,我们创建了一个Facade:

package me.tomasetti.mpsantlr.parser;import me.tomassetti.antlr4.parser.ANTLRv4Lexer;
import me.tomassetti.antlr4.parser.ANTLRv4Parser;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;import java.io.*;
import java.nio.charset.StandardCharsets;public class Antlr4ParserFacade {public ANTLRv4Parser.GrammarSpecContext parseString(String code) {InputStream inputStream = new ByteArrayInputStream(code.getBytes(StandardCharsets.UTF_8));return parseStream(inputStream);}public ANTLRv4Parser.GrammarSpecContext parseFile(File file) throws FileNotFoundException {return parseStream(new FileInputStream(file));}public ANTLRv4Parser.GrammarSpecContext parseStream(InputStream inputStream) {try {ANTLRv4Lexer lexer = new ANTLRv4Lexer(new org.antlr.v4.runtime.ANTLRInputStream(inputStream));TokenStream tokens = new CommonTokenStream(lexer);ANTLRv4Parser parser = new ANTLRv4Parser(tokens);return parser.grammarSpec();} catch (IOException e) {throw new RuntimeException("That is unexpected", e);}}}

现在我们需要一个构建文件:

buildscript {repositories {maven {name 'JFrog OSS snapshot repo'url  'https://oss.jfrog.org/oss-snapshot-local/'}jcenter()}}repositories {mavenCentral()jcenter()
}apply plugin: 'java'
apply plugin: 'antlr'
apply plugin: 'idea'dependencies {antlr "org.antlr:antlr4:4.5.1"compile "org.antlr:antlr4-runtime:4.5.1"testCompile 'junit:junit:4.12'
}generateGrammarSource {maxHeapSize = "64m"arguments += ['-package', 'me.tomassetti.antlr4.parser']outputDirectory = new File("${project.buildDir}/generated-src/antlr/main/me/tomassetti/antlr4/parser".toString())
}task fatJar(type: Jar) {manifest {attributes 'Implementation-Title': 'Antlr4-Parser','Implementation-Version': '0.0.1'}baseName = project.name + '-all'from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }with jar
}

您可能要运行:

  • gradle这个主意 ,以创建一个Jetbrains的IDEA项目
  • gradle fatJar创建一个Jar,其中将包含我们的编译代码和所有依赖项

好。 现在要将这个解析器用于MPS,我们首先创建一个项目。 在向导中,我们还选择运行时和沙箱选项。 完成后,我们应该将胖子复制到运行时解决方案的models目录下。 在我的情况下,我从Java项目的目录运行以下命令:

cp build/libs/parser-all.jar ../languages/me.tomassetti.mpsantlr/runtime/models/

窗口1
然后我们也将其添加到库中:

window2

现在,JAR的内容应出现在运行时解决方案的存根中。

存根

从AST节点创建MPS节点

现在,我们将建立一个名为AntlrImporter的新概念。 我们将使用它来选择并将ANTLR语法导入MPS:

进口商

概念结构将非常简单:

蚂蚁进口

我们还需要要导入的AST节点的概念。 首先,我们将定义抽象概念AstNode 。 然后,我们将为终端和非终端AST节点定义两个子概念。

terminal_node non_terminal_node

现在,让我们看一下AntlrImporter的编辑器。

antlrimporter_editor

第一个swing组件是一个按钮,用于打开文件选择器。 这样,我们可以轻松地选择一个文件并设置属性path 。 或者,如果愿意,我们可以手动编辑它。

file_chooser

选择文件后,我们可以通过单击第二个按钮将其导入

纽扣

导入逻辑在importModel中 ,这是AntlrImporter行为的一种方法。

import_logic

好。 这就对了。 这样我们就可以解析任何ANTLR语法并将其放入MPS。 现在我们只需要使用一个很好的表示。 我们要使用树符号。

使用树符号

树符号令人惊讶地易于使用。

首先,将com.mbeddr.mpsutil.treenotation.styles.editor添加到我们语言的编辑器方面的依赖项中。

editor_deps

我们还需要com.mbeddr.mpsutil.treenotation成为使用的语言。

editor_langs

Non TerminalNode的编辑器由单个树单元组成。 树单元的顶部代表此节点。 我们将使用ruleName表示它。 相反,我们应该在底部选择包含要在树中显示的子项的关系

non_terminal_editor

我们可以将光标放在顶部和底部之间的树形图上(“ / | \”符号),然后打开检查器。 在那里,我们可以使用样式属性来自定义树的外观

non_terminal_inspector

我们只是决定从左到右而不是从上到下显示树。 然后,当孩子过多时,我们决定在父母与孩子之间添加更多空间。 这样,线条就不会重叠太多。

这是没有财产的样子

挤

属性集的外观如下

不拥挤

例如,还有其他属性可用于控制线条的颜色和粗细。 或者,您可以在线条的末端添加形状。 现在我们不需要这些功能,但是很高兴知道它们在那里。

TerminalNode的编辑器非常简单

terminal_editor

结论

多年来,MPS变得更加稳定且易于使用。 它已达到您可以非常有效地使用它的地步。 投影编辑是一个已经存在了一段时间的想法,并且还有其他可用的实现方式,例如整个平台 。 但是,MPS的成熟度很高。

我认为我们仍然想念的是:

  • 流程和最佳实践:我们应该如何管理与其他MPS项目的依赖关系? 我们应该如何与Java库集成?
  • 示例:令人惊讶的是,几乎没有公开的应用程序。 毕竟,许多用户针对其特定用途开发DSL,并且不打算共享它们。 但是,这意味着我们几乎没有机会互相学习
  • 扩展:Mbeddr团队作为Mbeddr平台的一部分,提供了很多好东西,做得很棒。 但是,它们似乎是唯一生产可复用组件并共享它们的组件

我认为现在是时候共同了解使用投影编辑可以实现的目标了。 我认为这将是非常有趣的时期。

如果我要表达的一个愿望是,我想听到更多有关其他人如何使用MPS的信息。 如果您在那里,请敲门。 并发表评论

翻译自: https://www.javacodegeeks.com/2016/05/antlr-jetbrains-mps-parsing-files-display-ast-usign-tree-notation.html

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

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

相关文章

MATLAB判断矩阵相等

1. AB;%得到的是一个矩阵,对应值相等则返回1,否则返回02. ~norm(A-B);%若AB则A-B全零,norm(A-B)的结果为0,否则为1;其中norm为范数3. ~sum(sum(abs(A-B)));%原理和2相同,但是计算速度要快于2数倍 4. isequ…

python全栈-Day 1

Python是一种动态强类型解释型语言 1、Python历史 Python2与Python3的区别: Python2: 源码不标准,混乱,重复代码多 默认编码方式是ASCII码,因此需要在文件的首行 #-*- encoding:utf-8 -*- Python3: 统一标准…

KMP字符串模式匹配详解

刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的。且听详细分解:KMP字符串模式匹配详解 来自CSDN A_B_C_ABC 网友 KMP字符串模式匹配通俗点说…

Matlab找矩阵中最大最小值的位置

1. ind find(Amin(min(A)));2. [row,column]find(Amin(min(A)));

ASP.NET Core IdentityServer4 新手上路

OAuth2.0资料 今天看到一篇博主写了该系列文章,贴图和过程都比较详细,俗话说实践是检验真理的唯一标准(如果是按照参考文章复制粘贴,应该不会出现踩坑,但是我喜欢自己手动敲一遍),发现几个坑,因而总结下经验&#xff0…

MATLAB矩阵复制数据

如果想让矩阵A(m,n)的数据的每一行复制b遍,组成一个m*b行的大矩阵,可以用B A(reshape(ones(b,1)*(1:m),m*b,1),:);

博弈知识汇总

以下是我从网上收集的关于组合博弈的资料汇总: 有一种很有意思的游戏,就是有物体若干堆,可以是火柴棍或是围棋子等等均可。两个 人轮流从堆中取物体若干,规定最后取光物体者取胜。这是我国民间很古老的一个游戏 ,别看这…

主成分分析和因子分析区别与联系

主成分分析可以简单的总结成一句话:数据的压缩和解释。常被用来寻找判断某种事物或现象的综合指标,并且给综合指标所包含的信息以适当的解释。在实际的应用过程中,主成分分析常被用作达到目的的中间手段,而非完全的一种分析方法。…

MATLAB空矩阵

创建空矩阵a [];%[]表示为空a zeros(m,n);%创建m*n的全零矩阵,不同于空矩阵判断空矩阵isempty(a);判断a是不是空矩阵

将Spring Boot应用程序绑定到Cloud Foundry中的服务的方法

如果要试用Cloud Foundry ,最简单的方法是下载出色的PCF开发人员或在Pivotal Web Services站点上创建试用帐户。 文章的其余部分假定您已经安装了Cloud Foundry,并且对Cloud Foundry有较高的了解。 这篇文章的目的是列出将Java应用程序集成到服务实例中…

matlab里插入行和列

matlab里插入行和列>> Amagic(4)A 16 2 3 135 11 10 89 7 6 124 14 15 1>> b1:4b 1 2 3 4>> C[A(1:2,:) ; b ; A(3:end,:)] % 行向量b插入第2行和第3行之间C 16 2 3 135 11 10 …

博弈问题及SG函数(真的很经典)

博弈问题 若你想仔细学习博弈论,我强烈推荐加利福尼亚大学的Thomas S. Ferguson教授精心撰写并免费提供的这份教材,它使我受益太多。(如果你的英文水平不足以阅读它,我只能说,恐怕你还没到需要看“博弈论”的时候。&am…

luogu P1519 穿越栅栏 Overfencing

题目描述 描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷…

Matlab reshape重新排布数组

使用reshape需要保证前后调整后的元素个数一致,否则会报错

hibernate关联映射_具有关联映射的Hibernate Composite ID

hibernate关联映射最近,我们面临着带有复合id字段的Hibernate关联映射的棘手情况。 我们需要与一对一和多对一进行双向关联。我们的拖曳表是“ REPORT”和“ REPORT_SUMMARY”,它们之间具有从REPORT到REPORT_SUMMARY的一对多关系,而从REPORT_…

css实现简单的告警提示动画效果

需求&#xff1a;css实现简单的告警提示动画效果&#xff0c;当接收到实时信息的时候&#xff0c;页面弹出告警信息的动画效果<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>css实现告警提示动画</…

博弈-sg函数的原理和优化(hdu-1536)

sg函数&#xff1a;sg函数是博弈中的确定一个position性质的一个函数&#xff0c;全称是sprague-grundy。性质1&#xff1a;对于所有的p-position&#xff0c;都有sg 0&#xff1b;对于所有的n-position都有sg &#xff01; 0&#xff1b; 性质2&#xff1a;某点a的sg函数的值…

java项目中Classpath路径到底指的是哪里?

1、src不是classpath, WEB-INF/classes,lib才是classpath&#xff0c;WEB-INF/ 是资源目录, 客户端不能直接访问。 2、WEB-INF/classes目录存放src目录java文件编译之后的class文件&#xff0c;xml、properties等资源配置文件&#xff0c;这是一个定位资源的入口。 3、引用clas…

程序员的八个级别

2009年4月6日 陈皓 在面试时&#xff0c;你可能会被经常问到“在未来5年&#xff0c;你想干什么&#xff1f;”&#xff0c;这可能是一个比较难回答的问题。在中国&#xff0c;答案一般可能会是Team leader&#xff0c;Manager&#xff0c;或是Architect&#xff0c;Specialist…