use std::str::FromStr; grammar; match { "<", ">", "(", ")", "{", "}", "|", ":", ",", ";", ".", ":=", "::=", "puts", "case", "let", "in", r"[a-z][A-Za-z0-9_-]*", r"[A-Z][A-Za-z0-9_-]*", r"[0-9]+", r"'([^'\\]|\\.)*'", r"\s*" => {}, r"\(\*([^*]|\*[^)])*\*\)" => {}, } use crate::ast::*; pub Stmts: Vec = { ";")*> => match stmt { None => stmts, Some(stmt) => { stmts.push(stmt); stmts } }, }; pub Stmt: Stmt = { "puts" => Stmt::Puts(<>), ":=" => Stmt::Assn(<>), }; pub Name: String = { r"[a-z][A-Za-z0-9_-]*" => <>.to_owned(), }; pub Expr: Expr = { "|")*> => { ts.push(t); Expr::Chc(ts) } }; pub Choice: Choice = { ":" => Choice { weight: Some(weight), value }, => Choice { weight: None, value } }; pub Term: Expr = { ()* => Expr::Cat(<>), }; pub Branch: Expr = { "." => Expr::Ap(Box::new(l), Box::new(r)), => <>, }; pub Leaf: Expr = { => Expr::Lit(<>), => Expr::Var(<>), "<" ",")*> ">" => { es.push(e); Expr::Tup(es) }, "let" ":=" "{" "}" => Expr::Let(name, Box::new(e1), Box::new(e2)), "(" ")" => e, }; pub Num: i64 = { r"[0-9]+" => i64::from_str(<>).unwrap(), }; pub Literal: Literal = { => Literal::Num(<>), r"'([^'\\]|\\.)*'" => Literal::from_str_literal(<>), r"[A-Z][A-Za-z0-9_-]*" => Literal::Atom(<>.to_owned()), };