什么是编辑器?

对我来说,编辑器是我工作中使用的主要工具。 作为语言工程师,我创建新的语言,使用现有的语言,并且需要其他工具来使用它们。 我希望能够在一个定制的IDE中将所有这些黑客一起入侵,我可以为我成长。 这就是为什么我要使用可破解的编辑器Kanvas的原因。 当然在GitHub上 。

在许多情况下,我需要一个用于DSL的简单文本编辑器,并且倾向于使用ANTLR构建它们。 我将需要其他东西,例如表格或图形投影,模拟器等,但是我需要从某个地方开始,对吗? 另外,我认为目前还没有一种简单的方法来获得具有最小依赖性和简单结构的DSL独立编辑器。 菜单上没有灯光选项。 是时候添加一个了。

快速从语法中获取编辑器

定义语言语法后,您可以从中提取很多信息。 我认为您应该能够免费从中获得尽可能多的价值,并可以根据需要进一步自定义它。 这类似于Xtext的想法(减去理解EMF所需阅读的400页)。

您能多快获得ANTLR语法的编辑器? 您为编辑器创建一个新项目,将Kanvas添加为依赖项,并注册您打算支持的语言:

fun main(args: Array<String>) {languageSupportRegistry.register("sm", smLangSupport)val kanvas = Kanvas()SwingUtilities.invokeLater {kanvas.createAndShowKanvasGUI()kanvas.addTab("My SM", languageSupport = smLangSupport)}

并添加以下行以支持您的语言:

object smLangSupport : BaseLanguageSupport() {override val antlrLexerFactory: AntlrLexerFactoryget() = object : AntlrLexerFactory {override fun create(code: String): Lexer = SMLexer(org.antlr.v4.runtime.ANTLRInputStream(code))}override val parserData: ParserData?get() = ParserData(SMParser.ruleNames, SMParser.VOCABULARY, SMParser._ATN)
}

这样很快。 少于10行代码。 我们只需要指定Lexer和Parser类(在此示例中为SMLexerSMParser )。

如果您想知道那是什么语言,那就是Kotlin:一种用于JVM的简洁静态语言,可以轻松与Java互操作。

让我们对其进行一些改进:语法突出显示

因此,我有一种简单的语言,基本上可以免费获得编辑器,然后开始使用它。 首先,我想为不同种类的标记定义样式。 我们正在做一些简单的事情,只需设置颜色即可:

object smLangSyntaxScheme : SyntaxScheme(true) {override fun getStyle(index: Int): Style {val style = Style()val color = when (index) {// TypesSMLexer.STRING, SMLexer.INT, SMLexer.DECIMAL -> Color(42, 53, 114)// LiteralsSMLexer.STRINGLIT -> Color(21, 175, 36)SMLexer.INTLIT, SMLexer.DECLIT -> Color.BLUE// CommentsSMLexer.COMMENT -> Color(170, 181, 171)// OperatorsSMLexer.ASTERISK, SMLexer.DIVISION, SMLexer.PLUS, SMLexer.MINUS -> Color.WHITE// KeywordsSMLexer.VAR -> Color.GREENSMLexer.INPUT -> Color(200, 250, 200)SMLexer.SM -> Color(200, 250, 200)SMLexer.EVENT -> Color(200, 250, 200)SMLexer.AS -> Color(50, 12, 96)// IdentifiersSMLexer.ID -> Color.MAGENTA// SeparatorsSMLexer.ARROW -> Color(50, 12, 96)SMLexer.COLON -> Color(50, 12, 96)SMLexer.ASSIGN -> Color(50, 12, 96)SMLexer.LPAREN, SMLexer.RPAREN -> Color.WHITE// RestSMLexer.UNMATCHED -> Color.REDelse -> null}if (color != null) {style.foreground = color}return style}
}

我们没有将某些标记设置为粗体或斜体,因为我们想使事情简单。 顺便说一句,如果您对Kanvas中语法突出显示的工作方式感兴趣,我将在本文中进行介绍。

然后是自动补全

现在,我们免费获得了一些有限的自动完成功能。 基本上,我们会根据语言的结构获得自动补全功能,因此我们的算法可以告诉我们哪些关键字可以插入当前位置,或者在某个位置可以接受标识符。 该算法不能免费确定的是应该建议哪些标识符。 让我们实现一个非常简单的逻辑:当我们可以插入一个标识符时,我们将查看前面的标记并使用它们来确定要提出的建议。 例如,在定义输入时,我们可以建议“ anInput”,而在定义变量时,我们可以建议“ aVar”:

override val propositionProvider: PropositionProviderget() = object : PropositionProvider {override fun fromTokenType(completionProvider: CompletionProvider,preecedingTokens: List<Token>, tokenType: Int): List<Completion> {val res = LinkedList<Completion>()var proposition : String? = this@smLangSupport.parserData!!.vocabulary.getLiteralName(tokenType)if (proposition != null) {if (proposition.startsWith("'") && proposition.endsWith("'")) {proposition = proposition.substring(1, proposition.length - 1)}res.add(BasicCompletion(completionProvider, proposition))} else {when (tokenType) {SMParser.ID -> {val determiningToken = preecedingTokens.findLast { setOf(SMLexer.SM, SMLexer.VAR, SMLexer.EVENT, SMLexer.INPUT).contains(it.type) }val text = when (determiningToken?.type) {SMLexer.SM -> "aStateMachine"SMLexer.EVENT -> "anEvent"SMLexer.INPUT -> "aInput"SMLexer.VAR -> "aVar"else -> "someID"}res.add(BasicCompletion(completionProvider, text))}}}return res}}

这是代码。 这够了吗? 我不知道,但是我所知道的是,这是一个很小的系统,可以理解并且简单到可以轻松扩展和定制。 因此,我计划将其用于这种小型语言,并根据需要改进自动完成功能,尤其是针对该语言。 游戏的名称是有机地和迭代地增长的工具支持。

设计目标:类似于Sublime Text但开源

我们都喜欢Sublime Text。 我想从中得到启发,但是开源。 为什么要开源? 这样我就可以根据需要自定义它。

现在是这样的:

是的,它还没有Sublime Text精美。 但这意味着我还有改进的空间。

到语言工作台还是不到语言工作台?

我经常使用Jetbrains MPS和Xtext等语言工作台。 它们之所以出色,是因为它们允许很快地获得非常好的工具支持。 在许多情况下,它们是您的最佳选择。 但是,作为每种工程选择,都需要考虑不同的方面。 Jetbrains MPS和Xtext是非常大而复杂的软件,这种东西重数百MB。 要了解这些平台的内部知识,需要进行大量的工作和大量的努力。 只需使用这些平台,您将获得巨大收益。 但是,它们并不是在所有情况下的最佳解决方案,因为在某些情况下,您需要将语言与现有系统集成在一起,因此,您必须以非设计的方式来弯​​曲这些语言工作台。 也许您想将您的编辑器或工具嵌入到现有平台中,也许您想要在平板电脑上使用一个简单的编辑器,也许您希望从命令行使用这些工具。 也许您想以某种特殊的方式将系统组合在一起以满足您的特定需求。 在这些情况下,使用语言工作台不是正确的选择。 您需要一些简单的东西,可以入侵的东西。 这是我正在尝试的方法。 为此,我正在研究一些开源项目,并写了一本书 。

结论

这会飞吗? 我不知道。 我很开心地花了一些时间在这个项目上。 我觉得这是为使用ANTLR构建的DSL获得简单的独立编辑器的好方法。 我还想将其用作Kotlin支持的vim,一种新千年的vim。 具有超投射力。 让我们看看它是如何增长的。

是的,我知道Atom将自己描述为可入侵的编辑器。 但是,从我的角度来看,这还不够黑客入侵。

翻译自: https://www.javacodegeeks.com/2017/01/kanvas-generating-simple-ide-antlr-grammar.html

Kanvas:从您的ANTLR语法生成一个简单的IDE相关推荐

  1. VS2017生成一个简单的DLL文件 和 LIB文件——C语言

    下面我们将用两种不同的姿势来用VS2017生成dll文件(动态库文件)和lib文件(静态库文件),这里以C语言为例,用最简单的例子,来让读者了解如何生成dll文件(动态库文件) 生成动态库文件 姿势一 ...

  2. APM - Javassist 入门 生成一个简单类

    文章目录 官网 概述 Javassist作用 常用API Javassist 语法 Javassist使用流程 Demo Demo2 注意事项 参考 官网 http://www.javassist.o ...

  3. Yii学习笔记之二(使用gii生成一个简单的样例)

    1. 数据库准备 (1) 首先我们建一数据库 yii2test 并建立一张表例如以下: DROP TABLE IF EXISTS `posts`; CREATE TABLE `posts` (`pos ...

  4. 用java生成一个简单的二维码

    转自:原来Java生成二维码这么简单_一个爱运动的程序员的博客-CSDN博客_java二维码生成 首先创建一个maven项目 pom.xml引入zxing依赖 <dependency>&l ...

  5. C++ 有关string类的基本语法以及一个简单算法 理论加案例的形式

    #include<iostream> using namespace std; #include"string" //string类的头文件 #include" ...

  6. 教你怎么用c++基本语法实现一个简单的五子棋小游戏

    这个小游戏是在2020年5月份无聊写的,代码量不大,权当娱乐哈 基本思路: 1.创建一个15*15棋盘类,并设计相关函数(输出棋盘,下黑棋,下白棋等) 2.编写judge()函数,判断胜负条件 3.主 ...

  7. 利用C#生成一个简单的TIN三角网

    ###输入TXT数据 private void inputbutton_Click(object sender, EventArgs e){OpenFileDialog opg = new OpenF ...

  8. 生成一个点开跳出情人节快乐和鲜花的python代码文件

    可以使用 Python 中的 print 函数来生成一个简单的 "情人节快乐和鲜花" 的消息. 以下是一个示例代码: print("情人节快乐!献上我最真挚的祝福和一束鲜 ...

  9. freetype的简单使用之 生成一个字体bmp

    前言:最近项目上需要在linux上做字体的图像生成,经查找资料选择使用freetype来进行字体的生成 一:bmp的基础定义 1.bmp相关的定义 BMP_API.h 这一步我们可以先进行bmp相关基 ...

最新文章

  1. 揭晓飞桨平台提速秘诀:INT8量化加速实现“事半功倍”
  2. Python之pyarrow:pyarrow的简介、安装、使用方法之详细攻略
  3. centos7启动dhcp失败_4:Nginx服务启动、停止、重启
  4. macpro生成公钥并查看公钥
  5. Android 的一点总结
  6. 最少换乘(最短路+恶心的输入)acm寒假集训日记22/1/3 or 22/1/4
  7. MySQL数据库查询重复数据办法
  8. Java示例:如何执行进程并读取输出
  9. Android基于代理的插件化思路分析
  10. 有道词典与奇迹背单词生词本同步
  11. IIC上拉电阻的注意事项
  12. 1817735-45-7,Carboxy-PEG2-sulfonic acid在EDC和HATU等活化剂存在下,末端羧酸可参与与伯胺的反应
  13. CMOS图像传感器——深入ISO
  14. 小程序源码:2022强大的修复版趣味心理测试小程序源码,趣味测试引流裂变神器-多玩法安装简单
  15. java.lang.IllegalArgumentException: Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are requir
  16. 动态规划特训:切木棍(UVA10003)区间切分dp
  17. 时序动作定位 | 面向时序行为定位任务的无监督预训练
  18. SEO新手怎么做好网站关键词优化?
  19. 四则运算——结对项目报告
  20. 猎曲奇兵soundhound的原理

热门文章

  1. Oracle入门(十四.6)之使用标量数据类型
  2. php如何接收前端返回的各种类型的数据
  3. 【php】php对mysql的连接操作【mysql】
  4. sqlserver建库建表建约束,删库删表删约束的示例总结
  5. python中math库_Python的math库、random库实际应用
  6. Object.hashCode()与Object.equals()
  7. 哈儿小波分解和重构(降维和升维)实现算法
  8. Redis学习之缓存穿透、缓存击穿和缓存雪崩详解
  9. jdk8 cms g1gc_JDK 14:CMS GC是OBE
  10. argparser_Java命令行界面(第22部分):argparser