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::Underscore, ".." => Token::DotDot, "=>" => Token::Arrow, ":=" => Token::Assn, "::=" => Token::LitAssn, "puts" => Token::Puts, "case" => Token::Case, "let" => Token::Let, "in" => Token::In, "fix" => Token::Fix, "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(fixed.is_some(), name, expr), "::=" )*> => Stmt::LitAssn( fixed.is_some(), name, strs, ), "fix" => Stmt::Fix(<>), }; pub AtomLit: String = { "var" => <>.to_string(), "atom" => <>.to_string(), }; pub Name: Name = { "var" => ast.add_string(<>), }; pub Expr: ExprRef = { "|")*> => { if ts.len() == 0 { t.value } else { ts.push(t); ast.add_expr(Expr::Chc(ts)) } } }; pub Choice: Choice = { ":" => Choice { weight: Some(weight), value }, => Choice { weight: None, value } }; pub Term: ExprRef = { )*> => { match bs.len() { 0 => ast.expr_nil(), 1 => bs.pop().unwrap(), _ => ast.add_expr(Expr::Cat(<>)), } } }; pub Branch: ExprRef = { "." => ast.add_expr(Expr::Ap(l, r)), => <>, }; pub Subbranch: ExprRef = { ".." => ast.add_expr(Expr::Range(l, r)), => <>, } pub Leaf: ExprRef = { => ast.add_expr(Expr::Lit(<>)), => ast.add_expr(Expr::Var(<>)), "<" ",")*> ">" => { if es.len() == 0 && e == ast.expr_nil() { ast.add_expr(Expr::Tup(Vec::new())) } else { es.push(e); ast.add_expr(Expr::Tup(es)) } }, "let" ":=" "in" "{" "}" => ast.add_expr(Expr::Let(name, e1, e2)), "{" ";")*> "}" => { cs.push(c); ast.add_expr(Expr::Fun(cs)) }, "(" ")" => e, }; pub Case: Case = { "=>" => Case { pat, expr }, }; pub Pat: Pat = { "_" => Pat::Wildcard, => Pat::Lit(<>), => Pat::Var(<>), "<" ">" => Pat::Tup(Vec::new()), "<" ",")*> ">" => { ps.push(p); Pat::Tup(ps) }, }; pub Literal: Literal = { "num" => Literal::Num(<>), "str" => Literal::Str(<>), "atom" => Literal::Atom(ast.add_string(<>)), };