ide打开项目运行和调试按钮都是灰色的_如何开发一个IDE

IDE对于语言来说非常重要,让新手能更快入门,让老手能有更高的开发效率。所以我摸索着开发了Fanx语言的IDE。这里分享一些IDE内部工作原理和经验。

IDE和编译器

IDE为了实现功能,需要对源码进行解析。经过词法分析、语法分析、语义分析。相当于编译器的前端,相对与编译器来说少了优化器和代码生成等阶段。

  1. 语法分析:把字符串源文件变成单词串,每个单词叫做token。
  2. 语法分析:由token串构建AST(抽象语法树)
  3. 语义分析:决定AST每个结点的类型和相关信息,并进行类型检查。

IDE的语法解析和编译器理论上能共享代码。但是大部分语言编译器在开发时都没有考虑IDE的需求。两者功能上还有一定差异的:

  1. 错误恢复。编译器在遇见错误的时候可以直接退出。但是IDE不行,需要记录错误,并试图恢复后继续解析。在代码残缺不全的情况下也要进行语义分析。
  2. 多阶段编译。编译器可以把词法分析、语法分析、语义分析一遍全做了。但是IDE考虑到不能阻塞UI线程,需要分开多层。
  3. 增量编译。编译器可以把整个项目全部编译一遍。IDE中的文本一直在持续修改,需要增量的编译修改的部分。

IDE一般和编译器是独立的软件。当点击工具栏编译或者运行按钮的时候,IDE启动外部编译器进程进行编译。如果编译器和IDE版本不匹配,可能出现IDE显示有错误,但是编译是成功的。

编辑器

我们首先需要一个文本框来编辑代码,但是GUI框架提供的控件(例如TextArea)可能并不满足自定义颜色的要求。我们可以自己画一个控件,这样可以自定义排版和着色。

比较麻烦的地方是需要自己处理键盘事件,处理打字和光标操作等。还有拷贝和粘贴操作要访问系统剪贴板。中文输入法支持可以用一个隐藏的TextField来实现。这些功能开发完成后,我们就自己造了一个TextArea的轮子出来。

语法高亮

我们只需要完成词法分析,就能完成基本的语法高亮了。如果想要更高级的语义语法高亮,则需要等到完成语法分析或者语义分析。

语法分析和语法分析比较慢,在后台线程进行。词法分析比较快,在UI线程中处理。键盘事件中同步进行词法分析,后台线程的语义分析则是基于源码文本的快照。

语义错误

语义分析不只是当前文件的事情,还涉及依赖的库和项目内的其他文件。所以我们需要针对整个项目进行分析。最后把错误信息显出出来。

由于语义分析是整个项目进行的,所以成本比较高。我们在文件被修改的时候进行增量编译,只编译分析当前文件。当然增量编译的前提是项目首次加载时要进行一次全量编译。如果再进一步优化可以只分析文本被修改的部分所在的函数。

跳转到定义

按ctrl键并鼠标点击符号,跳转到符号的定义。我们在构建抽象语法树的时候一直维护结点所在的文本位置。根据点击位置查询抽象语法树得到点击的结点。点击的位置可能为类名,变量名,函数等,根据不同类型跳到不同的文件位置。在语义分析后我们就已经有了符号之间的引用信息。

补全提示

或者叫做自动完成。当用户键入时提示输入建议,并显示对应API文档。我们仍然和跳转定义的实现一样查询当前光标位置的抽象语法树结点,然后根据结点类型分不同情况做提示。例如用户在一个变量后面输入了“.”, 我们把这个变量在语义分析中确定的类型对应的所有方法列出来,作为候选。

需要把所有的第三方库和其他文件的符号索引在一起,供自动完成来查询。有时为了快速查询可以把符号建成倒排索引或者Trie树索引。很多脚本语言IDE实现会把这些索引持久保存,但我们为了简单,不进行持久化,每次启动时在后台线程建立索引。当文件保存时触发索引的更新。

调试

这个依赖与JVM提供的调试协议和接口。运行程序时提供调试模式的参数,则JVM启动后监听指定端口,并暂停程序,等待调试客户端命令。调试客户端在指定端口中连接被调试进程,并发出相关调试命令。他们通过socket来通信,所以远程调试是可能的。

总结

这里说的都是针对单个语言的基本功能。从头开发完整的IDE的工作量非常大,架构的复杂度也很大。

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

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

相关文章

电容的q值计算公式_在设计电路中电容容量大小、耐压等级选取详解 (转)

原文链接:在设计电路中电容容量大小、耐压等级选取详解 作者:张飞电容的计算 我们对电容的计算,目的是要知道,我们在电路中需要一个多大的电容。为什么要需要这么个电容?它的电压要多高?它的容量要多大?这是…

一个显示器分两个屏幕_桌面改造计划2.0:一个显示器不够那就两个,桌面好物分享...

日常生活节奏快,工作压力大应该目前年轻人的共识。为了适应快节奏的生活,使得大家往往不得不接受996或者997甚至更长的工作时间。而随着更长的工作时间也导致大家在电脑显示器前的时间更长,从而带来更多的不良影响,这两年过劳死的…

python寻找屏幕上的特定字符_库Turtle:用Python指挥小海龟在屏幕上绘图,流行的儿童编程...

海龟绘图(Turtle Graphics)是向儿童介绍编程的流行方式,源于Wally Feurzig和Seymour Papert1966年开发的LOGO语言。Python内置了Turtle库,基本包含所有原始功能。想象绘图区左上角有一只小海龟,代码就是指挥它动作的命…

flutterapp部分手机无法打开_Flutter run无法在iPhone上打开应用,直接在iphone也无法打开...

在电脑端运行flutter run后,报错信息如下:$ flutter runLaunching lib/main.dart on yuan的 iPhone in debug mode...Automatically signing iOS for device deployment using specified development team in Xcode project: 9D2Q3H854TRunning Xcode bu…

centos7 mysql 安装_CentOS7安装MySQL8.0图文教程(相对最齐全)

登录主机,然后进行下载第一步:在mysql官网下载源文件第二步:Select Operating System: 选择 Red Hat ,CentOS 是基于红帽的,Select OS Version: 选择 linux 7第三步:选择 RPM Bundle 点击 Download第四步&a…

mysql定时导入_MySQL导入、导出、数据库定时备份

本篇使用的MySQL版本是5.7.30,注意不同版本之间可能会有差异。一、导出操作1、查找mysqldump命令位置which mysqldump2、mysqldump导出示例用户名和密码分别是root和123456;导出远程库,使用-hIP和-port端口,如下所示。后面的命令默…

ubuntu mysql 初始化_Ubuntu初始化MySQL碰到的坑

想着将MySQL初始化,改变一下存放数据文件的位置:rootubuntu:/lvmdata# mkdir datarootubuntu:/lvmdata# chown -R mysql:mysql /lvmdata/data修改MySQL配置文件:datadir /lvmdata/data然后初始化:rootubuntu:/lvmdata# mysqld --…

mysql 攻击密码_MySQL用户Root密码为弱口令的攻击

1、连接到对方MYSQL 服务器mysql -u root -h 192.168.0.1mysql.exe 这个程序在你安装了MYSQL的的BIN目录中。2、让我们来看看服务器中有些什么数据库mysqlshow databases; MYSQL默认安装时会有MYSQL、TEST这两个数据库,如果你看到有其它的数据库那么就是用户自建的数…

mysql封装执行_解决Mysql封装类执行报错——Mysql::insert() should not be called

今天在写程序的时候使用了别的程序员写的一个Mysql封装类,但是执行后php会报错:Strict standards: Non-static method Mysql::insert() should not be called statically in关于这个错误的的处理方法是修改类文件,将对应报错的“function ins…

mysql建立从库同时备份_mysql主从库配置读写分离以及备份

1,什么是读写分离?其实就是将数据库分为了主从库,一个主库用于写数据,多个从库完成读数据的操作,主从库之间通过某种机制进行数据的同步,是一种常见的数据库架构。一个组从同步集群,通常被称为是…

cesium等高线_Cesium开源三维地球离线地图发布源码示例功能

一、概述Cesium开源三维地球离线地图发布源码提供了地图切换、查询定位、模型加载、专题图叠加显示和测量功能等,旨在为用户提供一个可以在Cesium快速加载离线地图或在线地图的解决方案,并提供技术支持。除了现有基本功能之外,还可以根据用户…

mat 和asmatrix的区别_R语言的稀疏矩阵太大可能就不能用as.matrix了

一个很大的矩阵, 320127 行, 8189列,假如用一个全为0的普通矩阵来存储,需要用到9.8Gbcols rows mat print(object.size(mat), unit"GB")# 19.5 Gbmat print(object.size(mat), unit"GB")# 9.8 Gb这里的0其实也要区分这里…

python 爬取贝壳网小区名称_Python爬虫实战:爬取贝壳网二手房40000条数据

前言本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理以下文章来源于啤酒就辣条 ,作者啤酒就辣条一、网页分析爬取贝壳网石家庄二手房信息,先打开链接https://sjz.ke.com/ershoufang…

python入门基础系列八_Python 入门系列 —— 21. dict 的介绍

Dictionary字典常用于存储键值对的集合,它是一种无序,可修改并且不允许重复,字典是用 {} 来表示,并带有 k/v 键值对,比如下面定义的字典结构。thisdict {"brand": "Ford","model": "Mustang&…

hive mysql5.7_安装并使用mysql5.7作为hive的metastore

前言hive的metastore默认是使用derby来作为metastore,但是derby有一个缺点是不能支持多用户链接,虽然你可以通过切换目录来支持,但是不同目录的metastore会不一致,所以这里使用mysql来作为hive的metastore。在linux上安装mysql数据…

centos禁用exec_CentOS停用按下Ctrl-Alt-Del 重启系统的功能

在Linux里,由于对安全的考虑,我们允许任何人按下Ctrl-Alt-Del来重启系统。但是在生产环境中,应该停用按下Ctrl-Alt-Del 重启系统的功能。[rootlocalhost ~]# cat /etc/inittab# Trap CTRL-ALT-DELETE#ca::ctrlaltdel:/sbin/shutdown -t3 -r n…

gitee如何搭建mysql_Windows基于gitee使用hexo搭建个人博客笔记

声明"全局变量"(以后我提到的站点配置文件和主题配置文件地址):"站点配置文件"位置为 hexo/_config.yml"主题配置文件"位置为 hexo/themes/next/_config.yml搭建hexo安装hexo命令行中输入以下命令(npm即为Node.js环境,如果…

mysql error nr.2003_[MySQL]在安装windows版MySQL时遇到过如下问题Error Nr.1045和Error.Nr.2003,相应解决办法如下...

1、准备mysql server-5.0.27.exe2、按照指导安装,在安装到最后一步时遇到如下两个错误:2.1、出现错误Error Nr.1045解决办法:a).停止MySQL服务:我的电脑-->右键-->管理-->服务和应用程序-->服务 找到名为"MySQL&…

python定制框架知识点_python框架中flask知识点总结

有很久没有更新我的博客了,在学习flask去了,别人都说flask不难,其实现在我也这么觉得,但是在刚接触的时候还是有点吃力的。在学习的过程中查阅了不少,也了解了许多,今天想做个总结。。。以免觉得学了那么久…

如何把通达信公式变成python_通达信附图如何改成选股公式?

龙起爆点副图{龙起爆点副图}{庄家起爆点幅图}DRAWGBK(O>C,RGB(48,41,124),RGB(0,0,0),0,1,0);VAR3AA:IF((CLOSE>REF(CLOSE,1)),88,0);VAR4AA:IF(((CLOSE)/(REF(CLOSE,1))>1.05)AND...龙起爆点副图{龙起爆点副图}{庄家起爆点幅图}DRAWGBK(O>C,RGB(48,41,124),RGB(0,…