grammar.lalrpop 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. use std::str::FromStr;
  2. grammar;
  3. match {
  4. "<",
  5. ">",
  6. "|",
  7. ":",
  8. ",",
  9. ";",
  10. ":=",
  11. "::=",
  12. "puts",
  13. "case",
  14. "let",
  15. "in",
  16. r"[a-z][A-Za-z0-9_-]*",
  17. r"[A-Z][A-Za-z0-9_-]*",
  18. r"[0-9]+",
  19. }
  20. use crate::ast::*;
  21. pub Stmts: Vec<Stmt> = {
  22. <mut stmts:(<Stmt> ";")*> <stmt:Stmt?> => match stmt {
  23. None => stmts,
  24. Some(stmt) => {
  25. stmts.push(stmt);
  26. stmts
  27. }
  28. },
  29. };
  30. pub Stmt: Stmt = {
  31. "puts" <Expr> => Stmt::Puts(<>),
  32. <Name> ":=" <Expr> => Stmt::Assn(<>),
  33. };
  34. pub Name: String = {
  35. r"[a-z][A-Za-z0-9_-]*" => <>.to_owned(),
  36. };
  37. pub Expr: Expr = {
  38. <Literal> => Expr::Lit(<>),
  39. <Name> => Expr::Var(<>),
  40. "<" <mut es:(<Expr> ",")*> <e:Expr> ">" => {
  41. es.push(e);
  42. Expr::Tup(es)
  43. },
  44. "let" <name:Name> ":=" <e1:Expr> "in" <e2:Expr> =>
  45. Expr::Let(name, Box::new(e1), Box::new(e2)),
  46. };
  47. pub Num: i64 = {
  48. r"[0-9]+" => i64::from_str(<>).unwrap(),
  49. };
  50. pub Literal: Literal = {
  51. <Num> => Literal::Num(<>),
  52. r"[A-Z][A-Za-z0-9_-]*" => Literal::Atom(<>.to_owned()),
  53. };