use std::str::FromStr; grammar; match { "<", ">", "(", ")", "{", "}", "|", ":", ",", ";", ".", "..", ":=", "::=", "puts", "case", "let", "in", r"\p{Ll}(\pL|[0-9_-])*", r"\p{Lu}(\pL|[0-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(<>), "::=" )*> => Stmt::LitAssn(name, strs), }; pub Name: String = { r"\p{Ll}(\pL|[0-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 Subbranch: Expr = { ".." => Expr::Range(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"\p{Lu}(\pL|[0-9_-])*" => Literal::Atom(<>.to_owned()), };