写点什么

赋值语句

作者:Miracle
  • 2025-09-30
    四川
  • 本文字数:1692 字

    阅读完需:约 6 分钟

准备了这么久。总算要开始解析我们最开始的目标那个。let age 等于 10 了。开始干点真正有趣的事情了。


let age = 10 我们定义 两种 最基本的 Statement 类型


表达式本身


和表达式赋值


用现代编程语言的观点这个可以认为是一个,都是表达式求值。第二个语句呢实际上是表达式求值的结果跟一个符号绑定,这两个其实是一件事。区别仅仅在于最后的是要不要跟一个符号绑定?


加上一个默认的空语句 我们的 Stmt 结构如下


#[derive(Debug, Default, Clone)]pub enum Stmt {  	#[default]  	Empty,  	Expr(Expr),  	Let{ pat: Pattern, expr: Expr }}
复制代码


学到这里,你应该很了解 chumsky 了 所以下面的解析器显然就是小 Case


看看效果吧


我们的测试代码如下

const STMT: &str = r#"let name = "zhu";"#;
fn main() -> Result<()> { println!("sizeof {}", std::mem::size_of::<Dynamic>()); let stmt_parser = parser::stmt::stmt_parser(expr_parser()); println!("{:?}", stmt_parser.parse(STMT)); Ok(())}
复制代码


运行结果如下


😃👏



接下来我们再增加一些最基础语句,比如说那个代码块。以花括号包括在其中的语句的列表。然后 if then else 。这是 条件判断 花括号然后后面是一个可选的 else 的花括号。然后还有一个循环。然后还有最基础的流程。就是 break。continue goto 在现代语句的语言中已经去掉了,所以我们 就不支持 goto


let assign_stmt = pattern_parser().then_ignore(just('=').padded_by(rust_ws()).labelled("'='"))    .then(expr_parser.clone()).then_ignore(just(';').padded_by(rust_ws()).labelled("';'"))    .validate(|(pat, value), span, emit| {        if !pat.is_valid_lvalue() {            emit.emit(Rich::custom(span.span(),format!("Invalid assignment pattern: {:?} cannot be used as an lvalue", pat)));            Stmt::Assign { pat, value }        } else { Stmt::Assign { pat, value } }    }).labelled("assignment statement").boxed();
let break_stmt = just("break").padded_by(rust_ws()).then_ignore(just(';').padded_by(rust_ws()).labelled("';'")) .to(Stmt::Break).labelled("break statement");
let continue_stmt = just("continue").padded_by(rust_ws()).then_ignore(just(';').padded_by(rust_ws()).labelled("';'")) .to(Stmt::Continue).labelled("continue statement");
let block = stmt.repeated().collect::<Vec<Stmt>>().delimited_by(just('{').padded_by(rust_ws()),just('}') .padded_by(rust_ws())).map(Stmt::Block).labelled("block").boxed();
let if_stmt = recursive(|if_stmt| { just("if").padded_by(rust_ws()).ignore_then(expr_parser.clone().labelled("condition")).then(block.clone()).then( just("else").padded_by(rust_ws()).ignore_then( if_stmt.clone().map(|stmt| Stmt::Block(vec![stmt])).or(block.clone()) ).or_not(), ).map(|((cond, then_blk), else_blk)| { let then_stmts = if let Stmt::Block(v) = then_blk { v } else { vec![] }; let else_stmts = else_blk.map(|b| if let Stmt::Block(v) = b { v } else { vec![] }); Stmt::If { cond, then_branch: then_stmts, else_branch: else_stmts, } }).labelled("if statement").boxed()});
let while_stmt = just("while").padded_by(rust_ws()).ignore_then( expr_parser.clone().labelled("condition") ) .then(block.clone()).map(|(cond, body_blk)| { let body = if let Stmt::Block(v) = body_blk { v } else { vec![] }; Stmt::While { cond, body } }).labelled("while statement").boxed();
choice(( let_stmt, expr_stmt, assign_stmt, block, if_stmt, while_stmt, break_stmt, continue_stmt, just(';').padded_by(rust_ws()).to(Stmt::Empty).labelled("empty statement"),)).labelled("statement")
复制代码


用户头像

Miracle

关注

三十年资深码农 2019-10-25 加入

还未添加个人简介

评论

发布
暂无评论
赋值语句_Miracle_InfoQ写作社区