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

用 C++ 写了个 Javascript 解释器

  •  
  •   JustSong div style="vertical-align: text-bottom; width: 14px; height: 14px; display: inline-block; background-image: url('/static/img/social_github.png'); background-size: 14px 14px; margin-right: 5px;">
    songquanpeng 2020-05-06 09:51:23 +08:00 5614 次点击
    这是一个创建于 1988 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    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
    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     Solana     1084 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 23:17 PVG 07:17 LAX 16:17 JFK 19:17
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86