Kanvas:从您的ANTLR语法生成一个简单的IDE

什么是编辑器?

对我来说,编辑器是我工作中使用的主要工具。 作为语言工程师,我创建新的语言,使用现有的语言,并且需要其他工具来使用它们。 我希望能够在一个定制的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

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

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

相关文章

函数名/函数地址/函数指针

转自&#xff1a;http://hi.baidu.com/%C6%BF%D6%D0%B5%C4%C5%AE%CE%D7/blog/item/387db9ddaa54d0a9cd1166fa.html 函数指针&#xff1a;1。指针变量 2。指针变量指向函数 这正如用指针变量可指向整型变量、字符型、数组一样。 在编译时&#xff0c;每一个函数都有一个入口地址…

matlab imaqhwinfo

使用imaqhwinfo函数&#xff0c;来获取电脑上安装的摄像头的名称&#xff0c;比如winvideo&#xff0c;之后可以利用imaqhwinfo(winvideo)来进一步获取设备ID等边信息&#xff0c;这在之后的视频流获取中会用到。获取设备ID之后&#xff08;比如ID为1&#xff09;&#xff0c;可…

第二次作业--熟悉使用工具

GIT地址 https://github.com/ForeveruxGIT用户名 Foreverux学号后五位 62117博客地址 https://www.cnblogs.com/JQloveJX/ 作业链接 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2793声明&#xff1a;部分内容摘自ChildishChange Part 0. 背景 阿…

什么是javax.ws.rs.core.context? [ 第2部分 ]

如何使用Context批注 在什么是javax.ws.rs.core.context&#xff1f; 您学习了如何使用Context批注从HttpHeaders类的注入实例中检索HTTP标头信息&#xff0c;以及如何从UriInfo实例中检索URI信息&#xff0c;例如URI参数和变量。 在本文中&#xff0c;您将学习如何将Context批…

【题解】Luogu P2347 砝码称重

正经DP题解 一道非常好的背包练手题&#xff08; sto&#xff08;注&#xff1a;原思路来源 SLYZ_0120 的题解&#xff09;orz 开始这道题 1.输入六个数&#xff0c;存进数组中 2.初始化 f 数组为0。 f [ i ] 表示重量为 i 的情况是否出现过&#xff08;下面代码使用的是 int 数…

matlab 获取视频图像的信息

获取视频图像的信息可以通过get函数来获取&#xff0c;如get(vid)或者get(getselectedsource(vid))。使用set函数可以设置摄像头获取的图像的一些属性值&#xff0c;也可以直接使用结构数组的“点”来赋值&#xff0c;比如&#xff0c;要持续通过摄像头获取图像&#xff0c;则可…

tomcat使用ssl_使用SSL和Spring Security保护Tomcat应用程序的安全

tomcat使用ssl如果您看过我的上一个博客&#xff0c;您会知道我列出了Spring Security可以做的十件事 。 但是&#xff0c;在开始认真使用Spring Security之前&#xff0c;您真正要做的第一件事就是确保您的Web应用使用正确的传输协议&#xff0c;在这种情况下为HTTPS –毕竟&a…

matlab delete、clf、cla、close、closereq删除对象

matlab中删除对象 删除对象 &#xff08;1&#xff09;delete&#xff1a;删除文件或对象图形 删除文件对象h的格式为&#xff1a;delete(filename)或delete filename 删除图形对象h的格式为&#xff1a;delete(h); 若要无条件删除所有的图形对象&#xff0c;则&#xff1a;set…

Linux系统调用过程分析

参考&#xff1a; 《Linux内核设计与实现》 0 摘要 linux的系统调用过程&#xff1a; 层次如下&#xff1a; 用户程序------>C库&#xff08;即API&#xff09;&#xff1a;INT 0x80 ----->system_call------->系统调用服务例程-------->内核程序 先说明一下&#…

Spring Boot和应用程序上下文层次结构

Spring Boot支持一种指定Spring应用程序上下文层次结构的简单方法。 这篇文章只是演示了此功能&#xff0c;我尚未在我从事的项目中很好地使用它。 Spring Cloud使用此功能来创建引导上下文 &#xff0c;在该上下文中&#xff0c;如果需要&#xff0c;可以从外部配置服务器加载…

drf 解析器,响应器,路由控制

解析器 作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理。 有application/json&#xff0c;x-www-form-urlencoded&#xff0c;form-data等格式使用:局部使用:from rest_framework.parsers import JSONParser,FormParseparser_classes [JSONParser, ]全局…

matlab max与min获取矩阵最大最小值函数

1.matlab中Max的用法1&#xff08;Min类似&#xff09; Matlab中max函数在矩阵中求函数大小的实例如下: C max(A) 1&#xff09;返回一个数组各不同维中的最大元素。 2&#xff09;如果A是一个向量&#xff0c;max(A)返回A中的最大元素。 3&#xff09;如果A是一个矩阵&…

shell中exec解析

参考&#xff1a;《linux命令、编辑器与shell编程》 《unix环境高级编程》exec和source都属于bash内部命令&#xff08;builtins commands&#xff09;&#xff0c;在bash下输入man exec或man source可以查看所有的内部命令信息。 bash shell的命令分为两类&#xff1a;外部命…

今天敢用OSS放视频,明天阿里云就敢收你房子

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 请教各位大佬&#xff1a;如果网站里&#xff0c;视频多的话&#xff0c;有什么加速的办法&#xff0c;使用CDN可以嘛? 今天群友king王咨询了这个问题&#xff1a;他的客户网站在美国&#xff0c;用美国节点的服务…

matlab meshgrid

meshgrid用于从数组a和b产生网格。生成的网格矩阵A和B大小是相同的。它也可以是更高维的。 用法: [A,B]Meshgrid(a,b) 生成size(b)Xsize(a)大小的矩阵A和B。它相当于a从一行重复增加到size(b)行&#xff0c;把b转置成一列再重复增加到size(a)列。因此命令等效于&#xff1a; …

连续锁定2个不同的锁会死锁_研究死锁–第5部分:使用显式锁定

连续锁定2个不同的锁会死锁在我的上一个博客中&#xff0c;我研究了使用Java的传统synchronized关键字和锁排序来修复破碎的&#xff0c;死锁的余额转移示例代码。 但是&#xff0c;有另一种方法称为显式锁定。 在这里&#xff0c;将锁定机制称为显式而非隐式的想法是&#xf…

fork source exec区别差异

fork 使用 fork 方式运行 script 时, 就是让 shell(parent process) 产生一个 child process 去执行该 script, 当 child process 结束后, 会返回 parent process, 但 parent process 的环境是不会因 child process 的改变而改变的. source 使用 source 方式运行 scrip…

LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)

线段树每个节点维护(A,B,C,len)向量&#xff0c;操作即是将其乘上一个矩阵。 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long lo…

在ECR上推送Spring Boot Docker映像

在先前的博客中&#xff0c;我们将Spring Boot应用程序与EC2集成在一起。 它是您可以在Amazon Web Services上进行的最原始的部署形式之一。 在本教程中&#xff0c;我们将使用我们的应用程序创建一个docker映像&#xff0c;该映像将存储到Amazon EC2容器注册表中 。 您需要安…