grammar.lalrpop 2.0 KB

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