123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- 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,
- "fix" => Token::Fix,
- "var" => Token::Var(<&'input str>),
- "atom" => Token::Atom(<&'input str>),
- "num" => Token::Num(<i64>),
- "str" => Token::Str(<String>)
- }
- }
- pub Stmts: Vec<Stmt> = {
- <mut stmts:(<Stmt> ";")*> <stmt:Stmt?> => match stmt {
- None => stmts,
- Some(stmt) => {
- stmts.push(stmt);
- stmts
- }
- },
- };
- pub Stmt: Stmt = {
- "puts" <Expr> => Stmt::Puts(<>),
- <fixed:"fix"?> <name:Name> ":=" <expr:Expr> => Stmt::Assn(fixed.is_some(), name, expr),
- <fixed:"fix"?> <name:Name> "::=" <strs:(<"var">)*> =>
- Stmt::LitAssn(fixed.is_some(), name, strs.iter().map(|x| x.to_string()).collect()),
- "fix" <Name> => Stmt::Fix(<>),
- };
- pub Name: Name = {
- "var" => ast.add_string(<>),
- };
- pub Expr: Expr = {
- <mut ts:(<Choice> "|")*> <t:Choice> => {
- if ts.len() == 0 {
- t.value
- } else {
- ts.push(t);
- Expr::Chc(ts)
- }
- }
- };
- pub Choice: Choice = {
- <weight:"num"> ":" <value:Term> => Choice {
- weight: Some(weight),
- value
- },
- <value:Term> => Choice {
- weight: None,
- value
- }
- };
- pub Term: Expr = {
- <mut bs:(<Branch>)*> => {
- if bs.len() == 1 {
- bs.pop().unwrap()
- } else {
- Expr::Cat(<>)
- }
- }
- };
- pub Branch: Expr = {
- <l:Branch> "." <r:Subbranch> => Expr::Ap(Box::new(l), Box::new(r)),
- <Subbranch> => <>,
- };
- pub Subbranch: Expr = {
- <l:Subbranch> ".." <r:Leaf> => Expr::Range(Box::new(l), Box::new(r)),
- <Leaf> => <>,
- }
- pub Leaf: Expr = {
- <Literal> => Expr::Lit(<>),
- <Name> => Expr::Var(<>),
- "<" <mut es:(<Expr> ",")*> <e:Expr> ">" => {
- es.push(e);
- Expr::Tup(es)
- },
- "let" <name:Name> ":=" <e1:Expr> "in" "{" <e2:Expr> "}" =>
- Expr::Let(name, Box::new(e1), Box::new(e2)),
- "{" <mut cs:(<Case> ";")*> <c:Case> "}" => {
- cs.push(c);
- Expr::Fun(cs)
- },
- "(" <e:Expr> ")" => e,
- };
- pub Case: Case = {
- <pat:Pat> "=>" <expr:Expr> => Case { pat, expr },
- };
- pub Pat: Pat = {
- <Literal> => Pat::Lit(<>),
- <Name> => Pat::Var(<>),
- "<" <mut ps:(<Pat> ",")*> <p:Pat> ">" => {
- ps.push(p);
- Pat::Tup(ps)
- },
- };
- pub Literal: Literal = {
- "num" => Literal::Num(<>),
- "str" => Literal::Str(<>),
- "atom" => Literal::Atom(ast.add_string(<>)),
- };
|