grammar.lalrpop 1.8 KB

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