grammar.lalrpop 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. use std::str::FromStr;
  2. grammar;
  3. match {
  4. "<",
  5. ">",
  6. "(",
  7. ")",
  8. "{",
  9. "}",
  10. "|",
  11. ":",
  12. ",",
  13. ";",
  14. ":=",
  15. "::=",
  16. "puts",
  17. "case",
  18. "let",
  19. "in",
  20. r"[a-z][A-Za-z0-9_-]*",
  21. r"[A-Z][A-Za-z0-9_-]*",
  22. r"[0-9]+",
  23. r"'([^'\\]|\\.)*'",
  24. r"\s*" => {},
  25. r"\(\*([^*]|\*[^)])*\*\)" => {},
  26. }
  27. use crate::ast::*;
  28. pub Stmts: Vec<Stmt> = {
  29. <mut stmts:(<Stmt> ";")*> <stmt:Stmt?> => match stmt {
  30. None => stmts,
  31. Some(stmt) => {
  32. stmts.push(stmt);
  33. stmts
  34. }
  35. },
  36. };
  37. pub Stmt: Stmt = {
  38. "puts" <Expr> => Stmt::Puts(<>),
  39. <Name> ":=" <Expr> => Stmt::Assn(<>),
  40. };
  41. pub Name: String = {
  42. r"[a-z][A-Za-z0-9_-]*" => <>.to_owned(),
  43. };
  44. pub Expr: Expr = {
  45. <mut ts:(<Choice> "|")*> <t:Choice> => {
  46. ts.push(t);
  47. Expr::Chc(ts)
  48. }
  49. };
  50. pub Choice: Choice = {
  51. <weight:Num> ":" <value:Term> => Choice {
  52. weight: Some(weight),
  53. value
  54. },
  55. <value:Term> => Choice {
  56. weight: None,
  57. value
  58. }
  59. };
  60. pub Term: Expr = {
  61. (<Leaf>)* => Expr::Cat(<>),
  62. };
  63. pub Leaf: Expr = {
  64. <Literal> => Expr::Lit(<>),
  65. <Name> => Expr::Var(<>),
  66. "<" <mut es:(<Expr> ",")*> <e:Expr> ">" => {
  67. es.push(e);
  68. Expr::Tup(es)
  69. },
  70. "let" <name:Name> ":=" <e1:Expr> "{" <e2:Expr> "}" =>
  71. Expr::Let(name, Box::new(e1), Box::new(e2)),
  72. "(" <e:Expr> ")" => e,
  73. };
  74. pub Num: i64 = {
  75. r"[0-9]+" => i64::from_str(<>).unwrap(),
  76. };
  77. pub Literal: Literal = {
  78. <Num> => Literal::Num(<>),
  79. r"'([^'\\]|\\.)*'" => Literal::from_str_literal(<>),
  80. r"[A-Z][A-Za-z0-9_-]*" => Literal::Atom(<>.to_owned()),
  81. };