[譯]用javascript實現一門程式語言-AST的介紹

Alongite發表於2018-08-11

目錄

  1. 用javascript實現一門程式語言-前言
  2. 用javascript實現一門程式語言-語言構想
  3. 用javascript實現一門程式語言-寫一個解析器
  4. 用javascript實現一門程式語言-字元輸入流
  5. 用javascript實現一門程式語言-詞法分析
  6. 用javascript實現一門程式語言-AST的介紹

AST

就像前面提到的,解析器將會為程式構建一個準確的語義意義的結構.我們的AST節點是普通的javascript物件,包含一個type屬性,其他屬性根據type不同而不同.

型別 AST節點
num { type: "num", value: NUMBER }
str { type: "str", value: STRING }
bool { type: "bool", value: true or false }
var { type: "var", value: NAME }
lambda { type: "lambda", vars: [ NAME... ], body: AST }
call { type: "call", func: AST, args: [ AST... ] }
if { type: "if", cond: AST, then: AST, else: AST }
assign { type: "assign", operator: "=", left: AST, right: AST }
binary { type: "binary", operator: OPERATOR, left: AST, right: AST }
prog { type: "prog", prog: [ AST... ] }
let { type: "let", vars: [ VARS... ], body: AST }

例子

  • Numbers("num")
    123.5
    複製程式碼
    { type: "num", value: 123.5 }
    複製程式碼
  • Strings("str")
    "Hello world"
    複製程式碼
    { type: "str", value: "Hello world" }
    複製程式碼
  • Booleans("bool")
    true
    false
    複製程式碼
    { type: "bool", value: true }
    { type: "bool", value: false }
    複製程式碼
  • Identifiers("var")
    foo
    複製程式碼
    { type: "var", value: "foo" }
    複製程式碼
  • Functions("lambda")
    lambda (x) 10
    λ (x) 10
    複製程式碼
    {
        type: "lambda",
        vars: [ "x" ],
        body: { type: "num" , value: 10}
    }
    複製程式碼
  • Functions calls("call")
    foo(a, 1)
    複製程式碼
    {
        type: "call",
        func: {
            type: "var", value: "foo"
        },
        args: [
            { type: "var", value: "a" },
            { type: "num", value: 1 }
        ]
    }
    複製程式碼
  • Conditionals("if")
    if foo then bar else baz
    
    -->
    
    {
        type: "if",
        "cond": { type: "var", value: "foo" },
        "then": { type: "var", value: "bar" },
        "else": { type: "var", value: "baz" }
    }
    複製程式碼
    if foo then bar
    
    -->
    
    {
        type: "if",
        "cond": { type: "var", value: "foo" },
        "then": { type: "var", value: "bar" }
    }
    複製程式碼
  • Assignment("assign")
    a = 10
    
    --> 
    
    {
        type: "assign",
        operator: "=",
        left: { type: "var", value: "a" },
        right: { type: "num", value: 10 }
    }
    複製程式碼
  • Binary expressions("binary")
    z + y * z
    
    -->
    
    {
        type: "binary",
        operator: "+",
        left: { type: "var", value: "x" },
        right: {
            type: "binary",
            operator: "*",
            left: { type: "var", value: "y" },
            right: { type: "var", value: "z" }
        }
    }
    複製程式碼
  • Sequences("prog")
    {
        a = 5;
        b = a * 2;
        a + b;
    }
    
    --> 
    
    {
        type: "prog",
        prog: [
            {
                type: "assign",
                operator: "=",
                left: { type: "var", value: "a" },
                right: { type: "num", value: 1 }
            },
            {
                "type": "assign",
                "operator": "=",
                "left": { "type": "var", "value": "b" },
                "right": {
                    "type": "binary",
                    "operator": "*",
                    "left": { "type": "var", "value": "a" },
                    "right": { "type": "num", "value": 2 }
                }
            },
            {
                "type": "binary",
                "operator": "+",
                "left": { "type": "var", "value": "a" },
                "right": { "type": "var", "value": "b" }
            }
        ]
    }
    複製程式碼
  • Block scoped variables("let")
    let (a = 10, b = a * 10) {
        a + b;
    }
    
    --> 
    
    {
        "type": "let",
        "vars": [
            {
                "name": "a",
                "def": { "type": "num", "value": 10 }
            },
            {
                "name": "b",
                "def": {
                    "type": "binary",
                    "operator": "*",
                    "left": { "type": "var", "value": "a" },
                    "right": { "type": "num", "value": 10 }
                }
            }
        ],
        "body": {
            "type": "binary",
            "operator": "+",
            "left": { "type": "var", "value": "a" },
            "right": { "type": "var", "value": "b" }
        }
    }
    複製程式碼

原文連結: lisperator.net/pltut/parse…

相關文章