grammar.lalrpop 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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"[a-z][A-Za-z0-9_-]*",
  22. r"[A-Z][A-Za-z0-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. };
  42. pub Name: String = {
  43. r"[a-z][A-Za-z0-9_-]*" => <>.to_owned(),
  44. };
  45. pub Expr: Expr = {
  46. <mut ts:(<Choice> "|")*> <t:Choice> => {
  47. ts.push(t);
  48. Expr::Chc(ts)
  49. }
  50. };
  51. pub Choice: Choice = {
  52. <weight:Num> ":" <value:Term> => Choice {
  53. weight: Some(weight),
  54. value
  55. },
  56. <value:Term> => Choice {
  57. weight: None,
  58. value
  59. }
  60. };
  61. pub Term: Expr = {
  62. (<Branch>)* => Expr::Cat(<>),
  63. };
  64. pub Branch: Expr = {
  65. <l:Branch> "." <r:Leaf> => Expr::Ap(Box::new(l), Box::new(r)),
  66. <Leaf> => <>,
  67. };
  68. pub Leaf: Expr = {
  69. <Literal> => Expr::Lit(<>),
  70. <Name> => Expr::Var(<>),
  71. "<" <mut es:(<Expr> ",")*> <e:Expr> ">" => {
  72. es.push(e);
  73. Expr::Tup(es)
  74. },
  75. "let" <name:Name> ":=" <e1:Expr> "{" <e2:Expr> "}" =>
  76. Expr::Let(name, Box::new(e1), Box::new(e2)),
  77. "(" <e:Expr> ")" => e,
  78. };
  79. pub Num: i64 = {
  80. r"[0-9]+" => i64::from_str(<>).unwrap(),
  81. };
  82. pub Literal: Literal = {
  83. <Num> => Literal::Num(<>),
  84. r"'([^'\\]|\\.)*'" => Literal::from_str_literal(<>),
  85. r"[A-Z][A-Za-z0-9_-]*" => Literal::Atom(<>.to_owned()),
  86. };