123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- use crate::ast::*;
- use crate::lexer::*;
- grammar<'input>;
- 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::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(<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(<>),
- <Name> ":=" <Expr> => Stmt::Assn(<>),
- <name:Name> "::=" <strs:(<Name>)*> => Stmt::LitAssn(name, strs),
- };
- pub Name: String = {
- "var" => <>.to_owned(),
- };
- pub Expr: Expr = {
- <mut ts:(<Choice> "|")*> <t:Choice> => {
- 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 = {
- (<Branch>)* => 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> "{" <e2:Expr> "}" =>
- Expr::Let(name, Box::new(e1), Box::new(e2)),
- "(" <e:Expr> ")" => e,
- };
- pub Literal: Literal = {
- "num" => Literal::Num(<>),
- "str" => Literal::Str(<>),
- "atom" => Literal::Atom(<>.to_owned()),
- };
|