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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值