grammar.lalrpop 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. use crate::ast::*;
  2. use crate::lexer::*;
  3. grammar<'input>(ast: &mut ASTArena);
  4. extern {
  5. type Location = usize;
  6. type Error = LexerError;
  7. enum Token<'input> {
  8. "<" => Token::LAngle,
  9. ">" => Token::RAngle,
  10. "(" => Token::LPar,
  11. ")" => Token::RPar,
  12. "{" => Token::LCurl,
  13. "}" => Token::RCurl,
  14. "|" => Token::Pipe,
  15. ":" => Token::Colon,
  16. "," => Token::Comma,
  17. ";" => Token::Semi,
  18. "." => Token::Dot,
  19. "_" => Token::Underscore,
  20. ".." => Token::DotDot,
  21. "=>" => Token::Arrow,
  22. ":=" => Token::Assn,
  23. "::=" => Token::LitAssn,
  24. "puts" => Token::Puts,
  25. "case" => Token::Case,
  26. "let" => Token::Let,
  27. "in" => Token::In,
  28. "fix" => Token::Fix,
  29. "var" => Token::Var(<&'input str>),
  30. "atom" => Token::Atom(<&'input str>),
  31. "num" => Token::Num(<i64>),
  32. "str" => Token::Str(<String>)
  33. }
  34. }
  35. pub Stmts: Vec<Stmt> = {
  36. <mut stmts:(<Stmt> ";")*> <stmt:Stmt?> => match stmt {
  37. None => stmts,
  38. Some(stmt) => {
  39. stmts.push(stmt);
  40. stmts
  41. }
  42. },
  43. };
  44. pub Stmt: Stmt = {
  45. "puts" <Expr> => Stmt::Puts(<>),
  46. <fixed:"fix"?> <name:Name> ":=" <expr:Expr> => Stmt::Assn(fixed.is_some(), name, expr),
  47. <fixed:"fix"?> <name:Name> "::=" <strs:(<AtomLit>)*> =>
  48. Stmt::LitAssn(
  49. fixed.is_some(),
  50. name,
  51. strs,
  52. ),
  53. "fix" <Name> => Stmt::Fix(<>),
  54. };
  55. pub AtomLit: String = {
  56. "var" => <>.to_string(),
  57. "atom" => <>.to_string(),
  58. };
  59. pub Name: Name = {
  60. "var" => ast.add_string(<>),
  61. };
  62. pub Expr: ExprRef = {
  63. <mut ts:(<Choice> "|")*> <t:Choice> => {
  64. if ts.len() == 0 {
  65. t.value
  66. } else {
  67. ts.push(t);
  68. ast.add_expr(Expr::Chc(ts))
  69. }
  70. }
  71. };
  72. pub Choice: Choice = {
  73. <weight:"num"> ":" <value:Term> => Choice {
  74. weight: Some(weight),
  75. value
  76. },
  77. <value:Term> => Choice {
  78. weight: None,
  79. value
  80. }
  81. };
  82. pub Term: ExprRef = {
  83. <mut bs:(<Branch>)*> => {
  84. match bs.len() {
  85. 0 => ast.expr_nil(),
  86. 1 => bs.pop().unwrap(),
  87. _ => ast.add_expr(Expr::Cat(<>)),
  88. }
  89. }
  90. };
  91. pub Branch: ExprRef = {
  92. <l:Branch> "." <r:Subbranch> => ast.add_expr(Expr::Ap(l, r)),
  93. <Subbranch> => <>,
  94. };
  95. pub Subbranch: ExprRef = {
  96. <l:Subbranch> ".." <r:Leaf> => ast.add_expr(Expr::Range(l, r)),
  97. <Leaf> => <>,
  98. }
  99. pub Leaf: ExprRef = {
  100. <Literal> => ast.add_expr(Expr::Lit(<>)),
  101. <Name> => ast.add_expr(Expr::Var(<>)),
  102. "<" <mut es:(<Expr> ",")*> <e:Expr> ">" => {
  103. if es.len() == 0 && e == ast.expr_nil() {
  104. ast.add_expr(Expr::Tup(Vec::new()))
  105. } else {
  106. es.push(e);
  107. ast.add_expr(Expr::Tup(es))
  108. }
  109. },
  110. "let" <name:Name> ":=" <e1:Expr> "in" "{" <e2:Expr> "}" =>
  111. ast.add_expr(Expr::Let(name, e1, e2)),
  112. "{" <mut cs:(<Case> ";")*> <c:Case> "}" => {
  113. cs.push(c);
  114. ast.add_expr(Expr::Fun(cs))
  115. },
  116. "(" <e:Expr> ")" => e,
  117. };
  118. pub Case: Case = {
  119. <pat:Pat> "=>" <expr:Expr> => Case { pat, expr },
  120. };
  121. pub Pat: Pat = {
  122. "_" => Pat::Wildcard,
  123. <Literal> => Pat::Lit(<>),
  124. <Name> => Pat::Var(<>),
  125. "<" ">" => Pat::Tup(Vec::new()),
  126. "<" <mut ps:(<Pat> ",")*> <p:Pat> ">" => {
  127. ps.push(p);
  128. Pat::Tup(ps)
  129. },
  130. };
  131. pub Literal: Literal = {
  132. "num" => Literal::Num(<>),
  133. "str" => Literal::Str(<>),
  134. "atom" => Literal::Atom(ast.add_string(<>)),
  135. };