grammar.lalrpop 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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::DotDot,
  20. "=>" => Token::Arrow,
  21. ":=" => Token::Assn,
  22. "::=" => Token::LitAssn,
  23. "puts" => Token::Puts,
  24. "case" => Token::Case,
  25. "let" => Token::Let,
  26. "in" => Token::In,
  27. "fix" => Token::Fix,
  28. "var" => Token::Var(<&'input str>),
  29. "atom" => Token::Atom(<&'input str>),
  30. "num" => Token::Num(<i64>),
  31. "str" => Token::Str(<String>)
  32. }
  33. }
  34. pub Stmts: Vec<Stmt> = {
  35. <mut stmts:(<Stmt> ";")*> <stmt:Stmt?> => match stmt {
  36. None => stmts,
  37. Some(stmt) => {
  38. stmts.push(stmt);
  39. stmts
  40. }
  41. },
  42. };
  43. pub Stmt: Stmt = {
  44. "puts" <Expr> => Stmt::Puts(<>),
  45. <fixed:"fix"?> <name:Name> ":=" <expr:Expr> => Stmt::Assn(fixed.is_some(), name, expr),
  46. <fixed:"fix"?> <name:Name> "::=" <strs:(<"var">)*> =>
  47. Stmt::LitAssn(fixed.is_some(), name, strs.iter().map(|x| x.to_string()).collect()),
  48. "fix" <Name> => Stmt::Fix(<>),
  49. };
  50. pub Name: Name = {
  51. "var" => ast.add_string(<>),
  52. };
  53. pub Expr: Expr = {
  54. <mut ts:(<Choice> "|")*> <t:Choice> => {
  55. if ts.len() == 0 {
  56. t.value
  57. } else {
  58. ts.push(t);
  59. Expr::Chc(ts)
  60. }
  61. }
  62. };
  63. pub Choice: Choice = {
  64. <weight:"num"> ":" <value:Term> => Choice {
  65. weight: Some(weight),
  66. value
  67. },
  68. <value:Term> => Choice {
  69. weight: None,
  70. value
  71. }
  72. };
  73. pub Term: Expr = {
  74. <mut bs:(<Branch>)*> => {
  75. if bs.len() == 1 {
  76. bs.pop().unwrap()
  77. } else {
  78. Expr::Cat(<>)
  79. }
  80. }
  81. };
  82. pub Branch: Expr = {
  83. <l:Branch> "." <r:Subbranch> => Expr::Ap(Box::new(l), Box::new(r)),
  84. <Subbranch> => <>,
  85. };
  86. pub Subbranch: Expr = {
  87. <l:Subbranch> ".." <r:Leaf> => Expr::Range(Box::new(l), Box::new(r)),
  88. <Leaf> => <>,
  89. }
  90. pub Leaf: Expr = {
  91. <Literal> => Expr::Lit(<>),
  92. <Name> => Expr::Var(<>),
  93. "<" <mut es:(<Expr> ",")*> <e:Expr> ">" => {
  94. es.push(e);
  95. Expr::Tup(es)
  96. },
  97. "let" <name:Name> ":=" <e1:Expr> "in" "{" <e2:Expr> "}" =>
  98. Expr::Let(name, Box::new(e1), Box::new(e2)),
  99. "{" <mut cs:(<Case> ";")*> <c:Case> "}" => {
  100. cs.push(c);
  101. Expr::Fun(cs)
  102. },
  103. "(" <e:Expr> ")" => e,
  104. };
  105. pub Case: Case = {
  106. <pat:Pat> "=>" <expr:Expr> => Case { pat, expr },
  107. };
  108. pub Pat: Pat = {
  109. <Literal> => Pat::Lit(<>),
  110. <Name> => Pat::Var(<>),
  111. "<" <mut ps:(<Pat> ",")*> <p:Pat> ">" => {
  112. ps.push(p);
  113. Pat::Tup(ps)
  114. },
  115. };
  116. pub Literal: Literal = {
  117. "num" => Literal::Num(<>),
  118. "str" => Literal::Str(<>),
  119. "atom" => Literal::Atom(ast.add_string(<>)),
  120. };