use crate::ast::*; use crate::lexer::*; grammar<'input>(ast: &mut ASTArena); extern { type Location = usize; type Error = LexerError; enum Token<'input> { "<" => Token::LAngle, ">" => Token::RAngle, "(" => Token::LPar, ")" => Token::RPar, "{" => Token::LCurl, "}" => Token::RCurl, "|" => Token::Pipe, ":" => Token::Colon, "," => Token::Comma, ";" => Token::Semi, "." => Token::Dot, ".." => Token::DotDot, "=>" => Token::Arrow, ":=" => Token::Assn, "::=" => Token::LitAssn, "puts" => Token::Puts, "case" => Token::Case, "let" => Token::Let, "in" => Token::In, "var" => Token::Var(<&'input str>), "atom" => Token::Atom(<&'input str>), "num" => Token::Num(), "str" => Token::Str() } } 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.iter().map(|x| x.to_string()).collect()), }; pub Name: Name = { "var" => ast.add_string(<>), }; 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" ":=" "in" "{" "}" => Expr::Let(name, Box::new(e1), Box::new(e2)), "{" ";")*> "}" => { cs.push(c); Expr::Fun(cs) }, "(" ")" => e, }; pub Case: Case = { "=>" => Case { pat, expr }, }; pub Pat: Pat = { => Pat::Lit(<>), => Pat::Var(<>), "<" ",")*> ">" => { ps.push(p); Pat::Tup(ps) }, }; pub Literal: Literal = { "num" => Literal::Num(<>), "str" => Literal::Str(<>), "atom" => Literal::Atom(ast.add_string(<>)), };