123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- use std::str::FromStr;
- grammar;
- match {
- "<",
- ">",
- "(",
- ")",
- "{",
- "}",
- "|",
- ":",
- ",",
- ";",
- ".",
- ":=",
- "::=",
- "puts",
- "case",
- "let",
- "in",
- r"[a-z][A-Za-z0-9_-]*",
- r"[A-Z][A-Za-z0-9_-]*",
- r"[0-9]+",
- r"'([^'\\]|\\.)*'",
- r"\s*" => {},
- r"\(\*([^*]|\*[^)])*\*\)" => {},
- }
- use crate::ast::*;
- 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(<>),
- };
- pub Name: String = {
- r"[a-z][A-Za-z0-9_-]*" => <>.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:Leaf> => Expr::Ap(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 Num: i64 = {
- r"[0-9]+" => i64::from_str(<>).unwrap(),
- };
- pub Literal: Literal = {
- <Num> => Literal::Num(<>),
- r"'([^'\\]|\\.)*'" => Literal::from_str_literal(<>),
- r"[A-Z][A-Za-z0-9_-]*" => Literal::Atom(<>.to_owned()),
- };
|