zoukankan      html  css  js  c++  java
  • 自己动手开发语言.笔记@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);
    }
  • 相关阅读:
    什么是HTTP
    通过递归法解决阶梯问题(n个台阶,上楼可以一步上1阶,也可以一步上2阶,一共有多少种上楼的方法)
    在Intelli Idea中使用plantuml(plantuml时序图的使用)
    Java中if(boolean)与if(boolean=true)的区别
    实现一个Servlet程序
    退出mysql的编辑模式
    mysql数据库基本操作命令行
    通过mysql命令查看mysql服务实例支持的搜索引擎
    Mac环境下使用终端启动Mysql,并进行mysql数据库的连接
    路飞学城Python-Day4
  • 原文地址:https://www.cnblogs.com/xuld/p/3518109.html
Copyright © 2011-2022 走看看