V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
JustSong
V2EX  ›  分享创造

用 C++ 写了个 JavaScript 解释器

  •  
  •   JustSong ·
    songquanpeng · 2020-05-06 09:51:23 +08:00 · 4509 次点击
    这是一个创建于 935 天前的主题,其中的信息可能已经有所发展或是发生改变。

    主要是拿来练习编译原理,该项目前前后后历时将近两个月,现在终于支持了大部分必要的语法(不包含对象),例如执行选择排序算法:

    function printArray(array, len) {
        while (len > 0) {
            len = len - 1;
            output(array[len]);
        }
    }
    
    function selectionSort(arr, length) {
        for (let i = 0; i < length; i = i + 1) {
            let minIndex = i;
            for (let j = i; j < length; j = j + 1) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            if (minIndex != i) {
                let temp = arr[i];
                arr[i] = arr[minIndex];
                arr[minIndex] = temp;
            }
        }
        printArray(arr, len);
    }
    
    let arr = [2, 5, 17, 7, 19, 90, -9, 11, 1, 0, 10, -6];
    let len = 12;
    selectionSort(arr, len);
    

    运行结果

    目前支持交互模式:

    shell 展示

    项目地址: https://github.com/songquanpeng/node

    希望大家能给个 Star,满足我的一个小小愿望,另外如果看的人多了,我就把源码里的注释好好地补一下。

    希望能对想要实践编译原理的同学有所帮助,谢谢。

    18 条回复    2020-05-09 17:19:14 +08:00
    GeruzoniAnsasu
        1
    GeruzoniAnsasu  
       2020-05-06 10:44:45 +08:00   ❤️ 2
    emmmm 本来想 star 的,看了眼代码又关掉了

    暴力匹配关键字 lexer
    强行手写并不知道会不会符合语法定义的 parser

    这个程度的 project 私以为随便做点现成语言的子集或者玩具语言就够了,意义不是很大
    我觉得搞懂 bison 怎么写都比这个有成就感。。



    就像 yin 神说的,写出来一个 parser 并不能完成什么里程碑

    撸一撸自动机生成器或者接一下 llvm 实现一个编译型语言挑战大得多
    JustSong
        2
    JustSong  
    OP
       2020-05-06 10:53:04 +08:00
    @GeruzoniAnsasu 新手刚开始总是从简单的开始嘛,当然以后还会再改进的
    djyde
        3
    djyde  
       2020-05-06 13:26:10 +08:00   ❤️ 1
    @GeruzoniAnsasu #1 最近想研究一下写 DSL, 本人只略懂代码编译的大致流程,想为了提高一些场景下的效率写些 DSL, 请问这方面有什么值得一读的书?
    crella
        4
    crella  
       2020-05-06 13:33:42 +08:00 via Android   ❤️ 1
    @djyde ruby 里面 sinatra 是经典的 DSL 案例,可以看看。
    Mohanson
        5
    Mohanson  
       2020-05-06 13:51:01 +08:00 via Android   ❤️ 1
    首先支持下楼主,希望坚持下去。我去年花了 3 个月写了个 typescript 静态编译器,后端走 llvm,感兴趣可以瞅两眼,支持 class,不过烂尾了

    https://github.com/nervosnetwork/minits

    今年目标本来是写 go 编译器,不过现在改为 webassembly (pywasm) 实现 AOT 方案了
    GPF
        6
    GPF  
       2020-05-06 17:21:26 +08:00   ❤️ 1
    支持,楼主都说了练习编译原理的,用暴力匹配 lexer 和递归下降实现 parser 无可厚非。明白原理之后很容易就转到 flex/bison 的实现了。再说到底是用 bison 生成 parser 还是手写 parser 也要根据实际情况而论。
    zuiluo
        7
    zuiluo  
       2020-05-06 17:46:55 +08:00   ❤️ 1
    挺好的,我前不久也写了一个 js 解释器 : https://github.com/zuluoaaa/makeJs
    Jirajine
        8
    Jirajine  
       2020-05-06 17:50:20 +08:00 via Android   ❤️ 1
    @Mohanson 这个不错,要是成熟的话 ts 编译到 llvm 再到 wasm,前端要彻底变天了。
    hetech
        9
    hetech  
       2020-05-06 18:33:21 +08:00   ❤️ 1
    写解释器是用来练手相当不错。最近想学习 go 语言,就照着 http://www.craftinginterpreters.com 上的教程来用 go 语言实现(仓库地址: https://github.com/ziyoung/lox-go )。写解释器其实是体力活。但是在这个过程,开始逐渐掌握了 go 语言,也是收获了很多。
    hetech
        10
    hetech  
       2020-05-06 18:40:24 +08:00   ❤️ 1
    最近在阅读《编程语言实现模式》,这本书总结了众多的模式,拿来当参考书相当不错。手写 parser 太累了,ANTLR 是更好的选择,后续打算试试 ANTLR + graalvm 。解释器写成了,Java 也基本入门了。😂
    kwoktung
        11
    kwoktung  
       2020-05-06 20:36:49 +08:00
    现在是不是进入了人均 手写解释器的时代了:) 最近也在看极客时间的编译原理,学习学习 UPUPUP
    CismonX
        12
    CismonX  
       2020-05-06 20:43:00 +08:00
    https://www.v2ex.com/t/643109

    这是我的初学练手项目,一个 Unlambda 的 compiler + runtime 。作为一个 esolang,Unlambda 的语法非常简单,所以比 Javacript 这种通用型语言更适合新人练手。欢迎交流!
    yuyuko
        13
    yuyuko  
       2020-05-07 05:06:00 +08:00 via iPhone
    @GeruzoniAnsasu 我记得主流编译器(cpp)基本都是手写递归下降,手写有啥奇怪的。。。。
    Mohanson
        14
    Mohanson  
       2020-05-07 12:52:47 +08:00 via Android
    @Jirajine 做下去后发现局限性很大,ts 因为 js 包袱仍然是动态语言,做静态编译势必舍弃很多语法特性,导致大部分现有 npm 包无法正常使用
    damingxing
        15
    damingxing  
       2020-05-07 15:15:24 +08:00
    楼主大牛!
    c0011
        16
    c0011  
       2020-05-08 17:19:26 +08:00
    楼主能总结下都看了哪些书或者视频吗?
    JustSong
        17
    JustSong  
    OP
       2020-05-08 17:47:26 +08:00 via Android
    @c0011 龙书,斯坦福的那个编译原理课,以及 https://github.com/rspivak/lsbasi,最后代码的结构参考了 https://github.com/Xiang1993/jack-compiler (前两个是当初学这门课的时候看的,我感觉就这个项目而言,直接看后两个就好)
    c0011
        18
    c0011  
       2020-05-09 17:19:14 +08:00
    @JustSong 谢谢了
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2827 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 04:44 · PVG 12:44 · LAX 20:44 · JFK 23:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.