打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
自己动手开发语言.笔记@2014-1-13

经过许久的折腾,hello world 是出来了。

目前语言自身的类库还未准备好,所以直接调用了.net库来实现 基本控制台输出功能。

为什么开发一个语言

很多人问我这个语言有什么优势,我想了下,优势就是它是自己的语言,可以DIY。

语言只是个工具,我不指望有多少人可以用它。但我的目标是

做一个既能像C#一样方便、又能像C++一样跨平台、不可反编译的语言。

开发一个语言到底有多难

编译原理是开发语言首先会想到的知识,而事实上,编译原理只是语言开发的一个很小的阶段。

很多人说自己懂编译原理,其实也就是了解了LR之类的高科技词语。这些人整天就知道做个解析器

解析一些代码,事实上他们的工作只限于解析,解析只是为了炫耀他们会编译原理。

真正开发一门语言,技术上需要至少需要包含这些东西:

1. 编译器(或解释器)

2. 运行库

一个脚本语言解释器由这些部分组成:

词法解析器 -> 语法解析器 -> 解释执行器

为了提高执行效率,解释器改进为以下部分组成:

词法解析器 -> 语法解析器 ->即时编译器(JIT)-> 代码优化器 -> 解释执行器

一个编程语言编译器由这些部分组成:

词法解析器 -> 语法解析器 -> 语义分析器 -> 代码优化器 -> 代码生成器

运行库是语言能执行的必要条件。比如 js 来说,内置对象就是运行库。对于 C++ 来说 <stdlib.h> 就是运行库。

如果需要开发一个包含 100 种语法的且真实能用的编程语言,那么需要的时间是:

词法解析器 1 + 语法解析器 10 + 语义分析器 100 + 代码优化器 + 30 + 代码生成器 100 + 运行库 1000 。

如果有人突然有兴趣想做个语言玩玩,然后花了11天时间终于折腾个语法解析器出来,对不起,你还需要 1230 天来完成整个语言。

所以,开发语言不仅是技术难题,更是时间难题。

开发语言会碰到的一些问题

我已经开发完语言的大部分内容,总结下几个难题,以及解决思路。当然,对于脚本语言,碰到的问题会少很多。

但是,我觉得像JavaScript, Python 都做的非常好了,真的我们也不需要新的脚本语言。

1. 语言如何调用操作系统的 API 实现文件读写操作?

2. 如何检测代码内部的死循环?用过 C# 的人都知道,下面的代码会得到一个警告:

void Main(){    while(true) {    }    return; // 警告:  检测到无法访问的代码}

3. 如何支持泛型,支持GC,支持闭包,支持很多很多的流行特性?

也许这些问题你可以不解决,但试问,这些功能都没有的语言还值的用么。

脚本语言实现原理

我想更多的人应该期望给自己做个脚本语言玩玩,或者可以给工作提高很多效率。

这些脚本语言可以不需要自己的运行库,它可以转为现成的语言执行。

这样的语言开发起来其实不难,现在演示如何开发一个可以翻译为 JavaScript 的语言。

一、做语法解析器

自己写解析器其实很累,所以找一个现成语法生成器,用法可以看它的文档。语法解析器的目标是将语言代码字符串转换为语法树。

因为有太多教程介绍语法解析器做法,这里不再重点说明。

二、做代码转换器

语法树是代码解析后的一个数据结构,通过递归遍历语法树,可以知道代码中有什么,然后进行相应的转换操作。

var input = [    {        type: 'if',        condition: {             type: 'int',             value: '1'        },        then: [             {                  type: 'funcCall',                  value: 'alert'             }        ]    } ];var output = [];function visitNode(node) {     if(node.type == 'if') {        return visitIf(node);    }    if(node.type == 'funcCall') {         return  visitFuncNode(node);    }    if(node.type == 'int') {         return  visitInt(node);    }}function visitIf(node) {     visitNode(node.condition);     visitNode(node.then);     visitNode(node.elseNode);}function visitFuncCall(node) {     output.push(node.value);     output.push('(');     visitFuncArguments(node.arguments);     output.push(')');}function visitInt(node) {    output.push(node.value);}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
c#
求两直线交点坐标
啥?又开始搞c加加了本人会至少15种开发语言不过被淘汰的语言
用node和ffmpeg进行直播推流
[minis秘籍] AppCan推送实现代码
PAT_A1133#Splitting A Linked List
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服