补全:program 是 stmt*
(每道题开头都有同一段:T() 是上一站 lexer 的替身——源码里 token 之间用空格分开,它切成 (kind, text, line, col);show() 把树写成一行:二元运算全加括号,语句之间用 |。) 贯穿的源码(接 c
树和一排差在哪
同样是 1 + 2 * 3,token 流是一排五个,AST 是一棵树。树多出来的东西是【0】。
括号去哪了
( 1 + 2 ) * 3 的 AST 里没有括号节点。因为【0】。
一个节点存什么
这条路线用元组当节点:("bin", "+", 左, 右)、("let", 名字, 表达式)。一个节点至少要存的是【0】。
手搭一棵树再打出来
(每道题开头都有同一段:T() 是上一站 lexer 的替身——源码里 token 之间用空格分开,它切成 (kind, text, line, col);show() 把树写成一行:二元运算全加括号,语句之间用 |。) 先不用 parse
数节点、量深度
(每道题开头都有同一段:T() 是上一站 lexer 的替身——源码里 token 之间用空格分开,它切成 (kind, text, line, col);show() 把树写成一行:二元运算全加括号,语句之间用 |。) 用完整 parse
补全:把二元运算写出来
(每道题开头都有同一段:T() 是上一站 lexer 的替身——源码里 token 之间用空格分开,它切成 (kind, text, line, col);show() 把树写成一行:二元运算全加括号,语句之间用 |。) show 少了 b
补全:数一数整棵树
(每道题开头都有同一段:T() 是上一站 lexer 的替身——源码里 token 之间用空格分开,它切成 (kind, text, line, col);show() 把树写成一行:二元运算全加括号,语句之间用 |。) 贯穿的源码(接 c
补全:树上找名字
(每道题开头都有同一段:T() 是上一站 lexer 的替身——源码里 token 之间用空格分开,它切成 (kind, text, line, col);show() 把树写成一行:二元运算全加括号,语句之间用 |。) 贯穿的源码(接 c
乘法为什么先于加法
玩具语言的文法(八节共用):program := stmt*;stmt := "let" IDENT "=" expr ";" | IDENT "=" expr