目录
- 用javascript实现一门编程语言-前言
- 用javascript实现一门编程语言-语言构想
- 用javascript实现一门编程语言-写一个解析器
- 用javascript实现一门编程语言-字符输入流
- 用javascript实现一门编程语言-词法分析
- 用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" } } }