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")
评论