/ compiler / parser-lossless / src / grammar.lalrpop
grammar.lalrpop
  1  
  2  grammar<'a>(handler: &adl_errors::Handler);
  3  
  4  use std::iter;
  5  
  6  use adl_errors::ParserError;
  7  
  8  use crate::tokens::{IdVariants, LalrToken, Token};
  9  use crate::{ExpressionKind, IntegerTypeKind, LiteralKind, StatementKind, SyntaxKind, SyntaxNode, TypeKind};
 10  use crate::check_identifier;
 11  
 12  Nonsemantic: SyntaxNode<'a> = {
 13      Whitespace => SyntaxNode::new_token(SyntaxKind::Whitespace, <>, vec![]),
 14      Linebreak => SyntaxNode::new_token(SyntaxKind::Linebreak, <>, vec![]),
 15      CommentLine => SyntaxNode::new_token(SyntaxKind::CommentLine, <>, vec![]),
 16      CommentBlock => SyntaxNode::new_token(SyntaxKind::CommentBlock, <>, vec![]),
 17  }
 18  
 19  NamedPrimitiveType: SyntaxNode<'a> = {
 20      <name:Bool> <ys:Nonsemantic*> => SyntaxNode::new_token(TypeKind::Boolean.into(), name, ys),
 21      <name:Address> <ys:Nonsemantic*> => SyntaxNode::new_token(TypeKind::Address.into(), name, ys),
 22      <name:String> <ys:Nonsemantic*> => SyntaxNode::new_token(TypeKind::String.into(), name, ys),
 23      <name:Signature> <ys:Nonsemantic*> => SyntaxNode::new_token(TypeKind::Signature.into(), name, ys),
 24      <name:Field> <ys:Nonsemantic*> => SyntaxNode::new_token(TypeKind::Field.into(), name, ys),
 25      <name:Group> <ys:Nonsemantic*> => SyntaxNode::new_token(TypeKind::Group.into(), name, ys),
 26      <name:Scalar> <ys:Nonsemantic*> => SyntaxNode::new_token(TypeKind::Scalar.into(), name, ys),
 27      <name:U8> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::U8.into(), name, ys),
 28      <name:U16> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::U16.into(), name, ys),
 29      <name:U32> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::U32.into(), name, ys),
 30      <name:U64> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::U64.into(), name, ys),
 31      <name:U128> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::U128.into(), name, ys),
 32      <name:I8> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::I8.into(), name, ys),
 33      <name:I16> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::I16.into(), name, ys),
 34      <name:I32> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::I32.into(), name, ys),
 35      <name:I64> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::I64.into(), name, ys),
 36      <name:I128> <ys:Nonsemantic*> => SyntaxNode::new_token(IntegerTypeKind::I128.into(), name, ys),
 37  }
 38  
 39  // Produce an Identifier token whose validity has been checked.
 40  CheckedIdentifier: LalrToken<'a> = {
 41      <Identifier> => {
 42          check_identifier(&<>, handler);
 43          <>
 44      }
 45  }
 46  
 47  // We sometimes want to re-lex identifiers as paths.
 48  #[inline]
 49  Path: LalrToken<'a> = {
 50      <RealPath>,
 51  
 52      <mut i:Identifier> => {
 53          i.token = Token::IdVariants(IdVariants::Path);
 54          i
 55      },
 56  }
 57  
 58  Type3: SyntaxNode<'a> = {
 59      NamedPrimitiveType,
 60  
 61      <name:WithTrivia<Locator>> => {
 62          SyntaxNode::new(TypeKind::Composite, [name])
 63      },
 64  
 65      <name:WithTrivia<Path>> <c:(ConstArgumentList)?> => {
 66          SyntaxNode::new(TypeKind::Composite, iter::once(name).chain(c))
 67      },
 68  
 69      <l:WithTrivia<LeftSquare>> <t:Type> <s:WithTrivia<Semicolon>> <i:Expr> <r:WithTrivia<RightSquare>> => {
 70          SyntaxNode::new(TypeKind::Array, [l, t, s, i, r])
 71      },
 72  
 73      <WithTrivia<Future>> => {
 74          SyntaxNode::new(TypeKind::Future, [<>])
 75      },
 76  
 77      <fut:WithTrivia<Future>> <l:WithTrivia<Lt>> <f:WithTrivia<Fn>> <lparen:WithTrivia<LeftParen>>
 78      <ts:CommaMaybe<Type>> <rparen:WithTrivia<RightParen>> <r:WithTrivia<Gt>> => {
 79          SyntaxNode::new(TypeKind::Future, [fut, l, f, lparen].into_iter().chain(ts).chain([rparen, r]))
 80      },
 81  }
 82  
 83  // All types excluding tuples and unit
 84  // These types can potentially be wrapped in an optional.
 85  Type2: SyntaxNode<'a> = {
 86      Type3,
 87  
 88      <inner:Type3> <q:WithTrivia<Question>> => {
 89          SyntaxNode::new(TypeKind::Optional, [inner, q])
 90      },
 91  }
 92  
 93  Type1: SyntaxNode<'a> = {
 94      Type3,
 95  
 96      <l:WithTrivia<LeftParen>> <items:CommaTwo<Type>> <r:WithTrivia<RightParen>> => {
 97          SyntaxNode::new(TypeKind::Tuple, iter::once(l).chain(items).chain([r]))
 98      },
 99  
100      // Tuple type with one element - special case for error reporting.
101      <l:WithTrivia<LeftParen>> <e:Type> <c:WithTrivia<Comma>?> <r:WithTrivia<RightParen>> => {
102          let node = SyntaxNode::new(TypeKind::Tuple, [l, e].into_iter().chain(c).chain([r]));
103          handler.emit_err(ParserError::tuple_must_have_at_least_two_elements("type", node.span));
104          node
105      },
106  
107      <l:WithTrivia<LeftParen>> <r:WithTrivia<RightParen>> => {
108          SyntaxNode::new(TypeKind::Unit, [l, r])
109      },
110  }
111  
112  // Storage variables can have any type (some exceptions apply during semantic checking) in addition to the vector type
113  StorageType: SyntaxNode<'a> = {
114      Type,
115  
116      <l:WithTrivia<LeftSquare>> <t:Type> <r:WithTrivia<RightSquare>> => {
117          SyntaxNode::new(TypeKind::Vector, [l, t, r])
118      }
119  }
120  
121  // All types including tuples and unit
122  // These types can potentially be wrapped in an optional.
123  Type: SyntaxNode<'a> = {
124      Type1,
125  
126      <inner:Type1> <q:WithTrivia<Question>> => {
127          SyntaxNode::new(TypeKind::Optional, [inner, q])
128      },
129  }
130  
131  CommaList<T>: Vec<SyntaxNode<'a>> = {
132      <items: (<T> <WithTrivia<Comma>>)+> <item:T> => {
133          let mut result_items = Vec::with_capacity(2 * items.len() + 1);
134          result_items.extend(items.into_iter().flat_map(|(t, c)| [t, c]).chain([item]));
135          result_items
136      }
137  }
138  
139  CommaExpressions: Vec<SyntaxNode<'a>> = CommaList<Expr>;
140  
141  // Sequence of zero or more comma-delimited items, optionally
142  // with trailing comma.
143  #[inline]
144  CommaMaybe<T>: Vec<SyntaxNode<'a>> = {
145      <items: (<T> <WithTrivia<Comma>>)*> <item:(<T>)?> => {
146          let mut result_items = Vec::with_capacity(2 * items.len() + 1);
147          result_items.extend(items.into_iter().flat_map(|(t, c)| [t, c]).chain(item));
148          result_items
149      }
150  }
151  
152  // Comma delimited list of at least two items, with optional trailing comma.
153  #[inline]
154  CommaOne<T>: Vec<SyntaxNode<'a>> = {
155      <item0:T> <items:(<WithTrivia<Comma>> <T>)*> <c1:(WithTrivia<Comma>)?> => {
156          iter::once(item0).chain(items.into_iter().flat_map(|(x, y)| [x, y])).chain(c1).collect()
157      },
158  }
159  
160  // Comma delimited list of at least two items, with optional trailing comma.
161  #[inline]
162  CommaTwo<T>: Vec<SyntaxNode<'a>> = {
163      <item0:T> <c0:WithTrivia<Comma>> <item1:T> <items:(<WithTrivia<Comma>> <T>)*> <c1:(WithTrivia<Comma>)?> => {
164          [item0, c0, item1].into_iter().chain(items.into_iter().flat_map(|(x, y)| [x, y])).chain(c1).collect()
165      },
166  }
167  
168  CommaInitializersMaybe = CommaMaybe<StructMemberInitializer>;
169  
170  FunctionIdentifier: SyntaxNode<'a> = {
171      WithTrivia<Path>,
172      WithTrivia<Locator>,
173      WithTrivia<Intrinsic>,
174  }
175  
176  WithTrivia<T>: SyntaxNode<'a> = {
177      <t:T> <xs:Nonsemantic*> => SyntaxNode::new_token(SyntaxKind::Token, t, xs),
178  }
179  
180  NoTrivia<T>: SyntaxNode<'a> = {
181      <t:T> => SyntaxNode::new_token(SyntaxKind::Token, t, Vec::new()),
182  }
183  
184  StructMemberInitializer: SyntaxNode<'a> = {
185      <name:WithTrivia<Identifier>> <c:WithTrivia<Colon>> <e:Expr> => {
186          SyntaxNode::new(SyntaxKind::StructMemberInitializer, [name, c, e])
187      },
188  
189      <name:WithTrivia<Identifier>> => {
190          SyntaxNode::new(SyntaxKind::StructMemberInitializer, [name])
191      },
192  }
193  
194  ExprStruct: SyntaxNode<'a> = {
195      // Struct initializer.
196      <name:FunctionIdentifier> <c:(ConstArgumentList)?> <l:WithTrivia<LeftCurly>> <inits:CommaInitializersMaybe> <r:WithTrivia<RightCurly>> => {
197          // For now the initializer name can't be external.
198          if name.text.contains(".alpha") {
199              handler.emit_err(ParserError::cannot_define_external_record(name.span));
200          }
201          SyntaxNode::new(ExpressionKind::Struct, iter::once(name).chain(c).chain([l]).chain(inits).chain([r]))
202      },
203  }
204  
205  ExprNever: SyntaxNode<'a> = {
206      <Never> => panic!("The Never token is never produced."),
207  }
208  
209  // Expressions.
210  //
211  // Unfortunately we can't just make one big Expr nonterminal. The problem is that there are some
212  // places where an expression can't contain a struct init due to parsing ambiguities.
213  // Namely this is the case in condition of `if` statements and the loop bounds of a `for` loop.
214  //
215  // Thus we need to handle operator precedence and associativity manually, threading through macros
216  // two nonterminals - `ExprStruct` which is a struct initializer, and `ExprNever` which is never produced.
217  //
218  // It's possible there is a shorter way to implement this than writing a separate nonterminal for each
219  // precedence level, but this seems a straightforward way for now.
220  Expr0: SyntaxNode<'a> = {
221      // Literal.
222      <s:StaticString> <xs:Nonsemantic*> => SyntaxNode::new_token(LiteralKind::String.into(), s, xs),
223      <lit:True> <xs:Nonsemantic*> => SyntaxNode::new_token(LiteralKind::Boolean.into(), lit, xs),
224      <lit:False> <xs:Nonsemantic*> => SyntaxNode::new_token(LiteralKind::Boolean.into(), lit, xs),
225      <lit:None> <xs:Nonsemantic*> => SyntaxNode::new_token(LiteralKind::None.into(), lit, xs),
226      <lit:AddressLiteral> <xs:Nonsemantic*> => SyntaxNode::new_token(LiteralKind::Address.into(), lit, xs),
227      <lit:ProgramId> <xs:Nonsemantic*> => SyntaxNode::new_token(LiteralKind::Address.into(), lit, xs),
228      <i:Integer> <s:Field> <xs:Nonsemantic*> => {
229          if i.text.starts_with("0x") || i.text.starts_with("0o") || i.text.starts_with("0b") {
230              handler.emit_err(ParserError::hexbin_literal_nonintegers(i.span));
231          }
232          SyntaxNode::suffixed_literal(i, s, xs)
233      },
234      <i:Integer> <s:Group> <xs:Nonsemantic*> => {
235          if i.text.starts_with("0x") || i.text.starts_with("0o") || i.text.starts_with("0b") {
236              handler.emit_err(ParserError::hexbin_literal_nonintegers(i.span));
237          }
238          SyntaxNode::suffixed_literal(i, s, xs)
239      },
240      <i:Integer> <s:Scalar> <xs:Nonsemantic*> => {
241          if i.text.starts_with("0x") || i.text.starts_with("0o") || i.text.starts_with("0b") {
242              handler.emit_err(ParserError::hexbin_literal_nonintegers(i.span));
243          }
244          SyntaxNode::suffixed_literal(i, s, xs)
245      },
246      <i: Integer> <s: I8> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
247      <i: Integer> <s: I16> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
248      <i: Integer> <s: I32> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
249      <i: Integer> <s: I64> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
250      <i: Integer> <s: I128> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
251      <i: Integer> <s: U8> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
252      <i: Integer> <s: U16> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
253      <i: Integer> <s: U32> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
254      <i: Integer> <s: U64> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
255      <i: Integer> <s: U128> <xs:Nonsemantic*> => SyntaxNode::suffixed_literal(i, s, xs),
256      <i: Integer> <xs:Nonsemantic*> => SyntaxNode::new_token(LiteralKind::Unsuffixed.into(), i, xs),
257  
258      // Variable or Associated Constant.
259      <WithTrivia<Path>> => {
260          if matches!(
261              crate::two_path_components(<>.text),
262              Some(("group", "GEN")),
263          ) {
264              // It's an associated constant.
265              SyntaxNode::new(ExpressionKind::AssociatedConstant, [<>])
266          } else {
267              // It's a variable.
268              SyntaxNode::new(ExpressionKind::Path, [<>])
269          }
270      },
271  
272      // Locator.
273      <WithTrivia<Locator>> => SyntaxNode::new(ExpressionKind::Locator, [<>]),
274  
275      // Parenthesized expression.
276      <l:WithTrivia<LeftParen>> <e:Expr> <r:WithTrivia<RightParen>> => {
277          SyntaxNode::new(ExpressionKind::Parenthesized, [l, e, r])
278      },
279  
280      // Function call or associated function call.
281      <name:FunctionIdentifier> <c:(ConstArgumentList)?> <l:WithTrivia<LeftParen>> <exprs:CommaMaybe<Expr>> <r:WithTrivia<RightParen>> => {
282          let kind = if matches!(
283              crate::two_path_components(name.text),
284              Some(
285                  (
286                      "BHP256" | "BHP512" |"BHP768" | "BHP1024" | "ChaCha" | "Keccak256" | "Keccak384" | "Keccak512" |
287                      "Pedersen64" | "Pedersen128" | "Poseidon2" | "Poseidon4" | "Poseidon8" | "SHA3_256" | "SHA3_384" |
288                      "SHA3_512" | "Mapping" | "Program" | "signature" | "Future" | "CheatCode" | "group" | "ECDSA" | 
289                      "Serialize" | "Deserialize",
290                      _
291                  )
292              )
293          ) {
294              ExpressionKind::AssociatedFunctionCall
295          } else if name.text.starts_with("_") {
296              ExpressionKind::Intrinsic
297          } else {
298              ExpressionKind::Call
299          };
300  
301          SyntaxNode::new(kind, iter::once(name).chain(c).chain([l]).chain(exprs).chain([r]))
302      },
303  
304      // Tuple expression.
305      <l:WithTrivia<LeftParen>> <exprs:CommaTwo<Expr>> <r:WithTrivia<RightParen>> => {
306          SyntaxNode::new(ExpressionKind::Tuple, iter::once(l).chain(exprs).chain([r]))
307      },
308  
309      // Tuple expression with one element - special case for error reporting.
310      <l:WithTrivia<LeftParen>> <e:Expr> <c:WithTrivia<Comma>> <r:WithTrivia<RightParen>> => {
311          let node = SyntaxNode::new(ExpressionKind::Tuple, [l, e, c, r]);
312          handler.emit_err(ParserError::tuple_must_have_at_least_two_elements("expression", node.span));
313          node
314      },
315  
316      // Tuple expression with zero elements - special case for error reporting.
317      <l:WithTrivia<LeftParen>> <c:WithTrivia<Comma>?> <r:WithTrivia<RightParen>> => {
318          let node = SyntaxNode::new(ExpressionKind::Tuple, iter::once(l).chain(c).chain([r]));
319          handler.emit_err(ParserError::tuple_must_have_at_least_two_elements("expression", node.span));
320          node
321      },
322  
323      // Array expression.
324      <l:WithTrivia<LeftSquare>> <exprs:CommaOne<Expr>> <r:WithTrivia<RightSquare>> => {
325          SyntaxNode::new(ExpressionKind::Array, iter::once(l).chain(exprs).chain([r]))
326      },
327  
328      // Empty array expression.
329      <l:WithTrivia<LeftSquare>> (WithTrivia<Comma>)? <r:WithTrivia<RightSquare>> => {
330          SyntaxNode::new(ExpressionKind::Array, iter::once(l).chain([r]))
331      },
332  
333      // Repeat expression.
334      <l:WithTrivia<LeftSquare>> <expr:Expr> <s:WithTrivia<Semicolon>> <c:Expr> <r:WithTrivia<RightSquare>> => {
335          SyntaxNode::new(ExpressionKind::Repeat, [l, expr, s, c, r])
336      },
337  
338      // Special access.
339      <x:WithTrivia<Block>> <d:WithTrivia<Dot>> <y:WithTrivia<Identifier>> => {
340          SyntaxNode::new(ExpressionKind::SpecialAccess, [x, d, y])
341      },
342      <x:WithTrivia<SelfLower>> <d:WithTrivia<Dot>> <y:WithTrivia<Identifier>> => {
343          SyntaxNode::new(ExpressionKind::SpecialAccess, [x, d, y])
344      },
345      // `address` is otherwise a keyword, so special case it.
346      <x:WithTrivia<SelfLower>> <d:WithTrivia<Dot>> <y:WithTrivia<Address>> => {
347          SyntaxNode::new(ExpressionKind::SpecialAccess, [x, d, y])
348      },
349      <x:WithTrivia<Network>> <d:WithTrivia<Dot>> <y:WithTrivia<Identifier>> => {
350          SyntaxNode::new(ExpressionKind::SpecialAccess, [x, d, y])
351      },
352  
353      // async block.
354      <a:WithTrivia<Async>> <b:BlockStatement> => {
355          SyntaxNode::new(ExpressionKind::Async, [a, b])
356      }
357  }
358  
359  Expr1<S>: SyntaxNode<'a> = {
360      S,
361  
362      Expr0,
363  
364      // Tuple access.
365      <x:Expr1<S>> <d:WithTrivia<Dot>> <i:WithTrivia<Integer>> => {
366          SyntaxNode::new(ExpressionKind::TupleAccess, [x, d, i])
367      },
368      // Array access.
369      <x:Expr1<S>> <l:WithTrivia<LeftSquare>> <index:Expr> <r:WithTrivia<RightSquare>> => {
370          SyntaxNode::new(ExpressionKind::ArrayAccess, [x, l, index, r])
371      },
372      // Member access.
373      <x:Expr1<S>> <d:WithTrivia<Dot>> <i:WithTrivia<Identifier>> => {
374          SyntaxNode::new(ExpressionKind::MemberAccess, [x, d, i])
375      },
376      // Method call.
377      <x:Expr1<S>> <d:WithTrivia<Dot>> <name:WithTrivia<Identifier>> <l:WithTrivia<LeftParen>> <exprs:CommaMaybe<Expr>> <r:WithTrivia<RightParen>> => {
378          SyntaxNode::new(ExpressionKind::MethodCall, [x, d, name, l].into_iter().chain(exprs).chain([r]))
379      },
380  }
381  
382  Op2: SyntaxNode<'a> = {
383      WithTrivia<Not>,
384      WithTrivia<Sub>,
385  }
386  
387  Expr2<S>: SyntaxNode<'a> = {
388      Expr1<S>,
389  
390      // Unary operations.
391      <op:Op2> <x:Expr2<S>> => SyntaxNode::new(ExpressionKind::Unary, [op, x]),
392  }
393  
394  Expr3<S>: SyntaxNode<'a> = {
395      Expr2<S>,
396  
397      <l:Expr3<S>> <a:WithTrivia<As>> <t:NamedPrimitiveType> => {
398          SyntaxNode::new(ExpressionKind::Cast, [l, a, t])
399      },
400  }
401  
402  Expr4<S>: SyntaxNode<'a> = {
403      Expr3<S>,
404  
405      // Right associative - recurse on the right.
406      <l:Expr3<S>> <op:WithTrivia<Pow>> <r:Expr4<S>> => SyntaxNode::binary_expression(l, op, r),
407  }
408  
409  LeftAssociativeBinary<Parent, Op>: SyntaxNode<'a> = {
410      Parent,
411  
412      // Left associative.
413      <l:Parent> <rest:(<Op> <Parent>)+> => {
414          rest.into_iter().fold(l, |acc, (op, e)| {
415              SyntaxNode::new(ExpressionKind::Binary, [acc, op, e])
416          })
417      }
418  }
419  
420  Op5: SyntaxNode<'a> = {
421      WithTrivia<Mul>,
422      WithTrivia<Div>,
423      WithTrivia<Rem>,
424  }
425  
426  Expr5<S>: SyntaxNode<'a> = LeftAssociativeBinary<Expr4<S>, Op5>;
427  
428  Op6: SyntaxNode<'a> = {
429      WithTrivia<Add>,
430      WithTrivia<Sub>,
431  }
432  
433  Expr6<S>: SyntaxNode<'a> = LeftAssociativeBinary<Expr5<S>, Op6>;
434  
435  Op7: SyntaxNode<'a> = {
436      WithTrivia<Shl>,
437      WithTrivia<Shr>,
438  }
439  
440  Expr7<S>: SyntaxNode<'a> = LeftAssociativeBinary<Expr6<S>, Op7>;
441  
442  Expr8<S>: SyntaxNode<'a> = LeftAssociativeBinary<Expr7<S>, WithTrivia<BitAnd>>;
443  
444  Expr9<S>: SyntaxNode<'a> = LeftAssociativeBinary<Expr8<S>, WithTrivia<BitXor>>;
445  
446  Expr10<S>: SyntaxNode<'a> = LeftAssociativeBinary<Expr9<S>, WithTrivia<BitOr>>;
447  
448  Op11: SyntaxNode<'a> = {
449      WithTrivia<Lt>,
450      WithTrivia<Gt>,
451      WithTrivia<LtEq>,
452      WithTrivia<GtEq>,
453  }
454  
455  Expr11<S>: SyntaxNode<'a> = {
456      Expr10<S>,
457  
458      // Not associative - we could potentially make a special case to give a clearer
459      // error message if a user tries something like `a < b < c`.
460      <l:Expr10<S>> <op:Op11> <r:Expr10<S>> => {
461          SyntaxNode::new(ExpressionKind::Binary, [l, op, r])
462      }
463  }
464  
465  Op12: SyntaxNode<'a> = {
466      WithTrivia<Eq>,
467      WithTrivia<NotEq>,
468  }
469  
470  Expr12<S>: SyntaxNode<'a> = {
471      Expr11<S>,
472  
473      // Not associative - we could potentially make a special case to give a clearer
474      // error message if a user tries something like `a == b == c`.
475      <l:Expr11<S>> <op:Op12> <r:Expr11<S>> => {
476          SyntaxNode::new(ExpressionKind::Binary, [l, op, r])
477      }
478  }
479  
480  Expr13<S>: SyntaxNode<'a> = LeftAssociativeBinary<Expr12<S>, WithTrivia<And>>;
481  
482  Expr14<S>: SyntaxNode<'a> = LeftAssociativeBinary<Expr13<S>, WithTrivia<Or>>;
483  
484  Expr15<S>: SyntaxNode<'a> = {
485      Expr14<S>,
486  
487      // Ternary conditional.
488      // <cond:Expr13<S>> <q:WithTrivia<Question>> <a:Expr> <c:WithTrivia<Colon>> <b:Expr13<S>> => {
489      //     SyntaxNode::new(ExpressionKind::Ternary, [cond, q, a, c, b])
490      // },
491      <cond:Expr14<S>> <q:WithTrivia<Question>> <a:Expr15<S>> <c:WithTrivia<Colon>> <b:Expr15<S>> => {
492          SyntaxNode::new(ExpressionKind::Ternary, [cond, q, a, c, b])
493      },
494  }
495  
496  
497  // An expression, including struct inits.
498  pub Expr: SyntaxNode<'a> = Expr15<ExprStruct>;
499  
500  // An expression, exluding struct inits in key places.
501  ExprNoS: SyntaxNode<'a> = Expr15<ExprNever>;
502  
503  ConstParameter: SyntaxNode<'a> = {
504      <v:WithTrivia<Identifier>> <c:WithTrivia<Colon>> <t:Type> => {
505          SyntaxNode::new(SyntaxKind::ConstParameter, [v, c, t])
506      },
507  }
508  
509  ConstParameterList: SyntaxNode<'a> = {
510      <c:NoTrivia<DoubleColon>> <l:WithTrivia<LeftSquare>> <ps:CommaMaybe<ConstParameter>> <r:WithTrivia<RightSquare>> => {
511          SyntaxNode::new(SyntaxKind::ConstParameterList, [c, l].into_iter().chain(ps).chain([r]))
512      },
513  }
514  
515   ArrayOrNamedPrimitiveType: SyntaxNode<'a> = {
516      <NamedPrimitiveType>,
517      <l:WithTrivia<LeftSquare>> <t:ArrayOrNamedPrimitiveType> <s:WithTrivia<Semicolon>> <i:Expr> <r:WithTrivia<RightSquare>> => {
518          SyntaxNode::new(TypeKind::Array, [l, t, s, i, r])
519      },
520  }
521  
522  GenericArgument: SyntaxNode<'a> = {
523      <Expr>,
524      <ArrayOrNamedPrimitiveType>,
525  }
526  
527  ConstArgumentList: SyntaxNode<'a> = {
528      <c:NoTrivia<DoubleColon>> <l:WithTrivia<LeftSquare>> <ps:CommaMaybe<GenericArgument>> <r:WithTrivia<RightSquare>> => {
529          SyntaxNode::new(SyntaxKind::ConstArgumentList, [c, l].into_iter().chain(ps).chain([r]))
530      },
531  }
532  
533  BlockStatement: SyntaxNode<'a> = {
534      <l:WithTrivia<LeftCurly>> <stmts:Statement*> <r:WithTrivia<RightCurly>> => {
535          SyntaxNode::new(StatementKind::Block, iter::once(l).chain(stmts).chain([r]))
536      },
537  }
538  
539  ConditionalStatement: SyntaxNode<'a> = {
540      <i:WithTrivia<If>> <c:ExprNoS> <b:BlockStatement> => {
541          SyntaxNode::new(StatementKind::Conditional, [i, c, b])
542      },
543  
544      <i:WithTrivia<If>> <c:ExprNoS> <b:BlockStatement> <e:WithTrivia<Else>> <b2:BlockStatement> => {
545          SyntaxNode::new(StatementKind::Conditional, [i, c, b, e, b2])
546      },
547  
548      <i:WithTrivia<If>> <c:ExprNoS> <b:BlockStatement> <e:WithTrivia<Else>> <c2:ConditionalStatement> => {
549          SyntaxNode::new(StatementKind::Conditional, [i, c, b, e, c2])
550      },
551  }
552  
553  AssignmentOperator: LalrToken<'a> = {
554      Assign,
555      AddAssign,
556      SubAssign,
557      MulAssign,
558      DivAssign,
559      RemAssign,
560      PowAssign,
561      ShlAssign,
562      ShrAssign,
563      BitAndAssign,
564      BitOrAssign,
565      BitXorAssign,
566      AndAssign,
567      OrAssign,
568  }
569  
570  pub Statement: SyntaxNode<'a> = {
571      // Expression statement.
572      <e:Expr> <s:WithTrivia<Semicolon>> => {
573          SyntaxNode::new(StatementKind::Expression, [e, s])
574      },
575  
576      // Return.
577      <r:WithTrivia<Return>> <e:Expr> <s:WithTrivia<Semicolon>> => {
578          SyntaxNode::new(StatementKind::Return, [r, e, s])
579      },
580  
581      <r: WithTrivia<Return>> <s:WithTrivia<Semicolon>> => {
582          SyntaxNode::new(StatementKind::Return, [r, s])
583      },
584  
585      // Single place definition, typed.
586      <l:WithTrivia<Let>> <i:WithTrivia<CheckedIdentifier>> <c:WithTrivia<Colon>> <t:Type> <a:WithTrivia<Assign>> <e:Expr> <s:WithTrivia<Semicolon>> => {
587          SyntaxNode::new(StatementKind::Definition, [l, i, c, t, a, e, s])
588      },
589  
590      // Single place definition, no type.
591      <l:WithTrivia<Let>> <i:WithTrivia<CheckedIdentifier>> <a:WithTrivia<Assign>> <e:Expr> <s:WithTrivia<Semicolon>> => {
592          SyntaxNode::new(StatementKind::Definition, [l, i, a, e, s])
593      },
594  
595      // Multiple place definition, typed.
596      <l:WithTrivia<Let>> <lp:WithTrivia<LeftParen>> <is:CommaList<WithTrivia<CheckedIdentifier>>> <rp:WithTrivia<RightParen>>
597      <c:WithTrivia<Colon>> <t:Type> <a:WithTrivia<Assign>> <e:Expr> <s:WithTrivia<Semicolon>> => {
598          SyntaxNode::new(
599              StatementKind::Definition,
600              [l, lp].into_iter().chain(is).chain([rp, c, t, a, e, s]),
601          )
602      },
603  
604      // Multiple place definition, no type.
605      <l:WithTrivia<Let>> <lp:WithTrivia<LeftParen>> <is:CommaList<WithTrivia<CheckedIdentifier>>> <rp:WithTrivia<RightParen>>
606      <a:WithTrivia<Assign>> <e:Expr> <s:WithTrivia<Semicolon>> => {
607          SyntaxNode::new(
608              StatementKind::Definition,
609              [l, lp].into_iter().chain(is).chain([rp, a, e, s]),
610          )
611      },
612  
613      // Constant.
614      <l:WithTrivia<Const>> <i:WithTrivia<CheckedIdentifier>> <c:WithTrivia<Colon>> <t:Type> <a:WithTrivia<Assign>> <e:Expr> <s:WithTrivia<Semicolon>> => {
615          SyntaxNode::new(StatementKind::Const, [l, i, c, t, a, e, s])
616      },
617  
618      BlockStatement,
619  
620      ConditionalStatement,
621  
622      // Assignment.
623      <lhs:Expr> <a:WithTrivia<AssignmentOperator>> <rhs:Expr> <s:WithTrivia<Semicolon>> => {
624          SyntaxNode::new(StatementKind::Assign, [lhs, a, rhs, s])
625      },
626  
627      // Loop - no type.
628      <f:WithTrivia<For>> <i:WithTrivia<CheckedIdentifier>> <n:WithTrivia<In>> <low:ExprNoS> <d:WithTrivia<DotDot>> <hi:ExprNoS> <b:BlockStatement> => {
629          SyntaxNode::new(StatementKind::Iteration, [f, i, n, low, d, hi, b])
630      },
631  
632      // Loop - type.
633      <f:WithTrivia<For>> <i:WithTrivia<CheckedIdentifier>> <c:WithTrivia<Colon>> <t:Type> <n:WithTrivia<In>> <low:ExprNoS> <d:WithTrivia<DotDot>> <hi:ExprNoS> <b:BlockStatement> => {
634          SyntaxNode::new(StatementKind::Iteration, [f, i, c, t, n, low, d, hi, b])
635      },
636  
637      // Assert.
638      <a:WithTrivia<Assert>> <l:WithTrivia<LeftParen>> <e:Expr> <r:WithTrivia<RightParen>> <s:WithTrivia<Semicolon>> => {
639          SyntaxNode::new(StatementKind::Assert, [a, l, e, r, s])
640      },
641  
642      // AssertEq.
643      <a:WithTrivia<AssertEq>> <l:WithTrivia<LeftParen>> <e0:Expr> <c:WithTrivia<Comma>> <e1:Expr> <r:WithTrivia<RightParen>> <s:WithTrivia<Semicolon>> => {
644          SyntaxNode::new(StatementKind::AssertEq, [a, l, e0, c, e1, r, s])
645      },
646  
647      // AssertNeq.
648      <a:WithTrivia<AssertNeq>> <l:WithTrivia<LeftParen>> <e0:Expr> <c:WithTrivia<Comma>> <e1:Expr> <r:WithTrivia<RightParen>> <s:WithTrivia<Semicolon>> => {
649          SyntaxNode::new(StatementKind::AssertNeq, [a, l, e0, c, e1, r, s])
650      },
651  }
652  
653  PrivacyKeyword: LalrToken<'a> = {
654      Constant,
655      Private,
656      Public,
657  }
658  
659  Parameter: SyntaxNode<'a> = {
660      <p:WithTrivia<PrivacyKeyword>?> <v:WithTrivia<CheckedIdentifier>> <c:WithTrivia<Colon>> <t:Type> => {
661          SyntaxNode::new(SyntaxKind::Parameter, p.into_iter().chain([v, c, t]))
662      },
663  }
664  
665  ParameterList: SyntaxNode<'a> = {
666      <l:WithTrivia<LeftParen>> <x:CommaMaybe<Parameter>> <r:WithTrivia<RightParen>> => {
667          SyntaxNode::new(SyntaxKind::ParameterList, iter::once(l).chain(x).chain([r]))
668      },
669  }
670  
671  FunctionKind: LalrToken<'a> = {
672      Function,
673      Inline,
674      Script,
675      Transition,
676  }
677  
678  FunctionOutput: SyntaxNode<'a> = {
679      <p:WithTrivia<PrivacyKeyword>?> <t:Type> => {
680          SyntaxNode::new(SyntaxKind::FunctionOutput, p.into_iter().chain([t]))
681      },
682  }
683  
684  FunctionOutputs: SyntaxNode<'a> = {
685      <p:WithTrivia<PrivacyKeyword>?> <t:Type2> => {
686          SyntaxNode::new(SyntaxKind::FunctionOutput, p.into_iter().chain([t]))
687      },
688  
689      <l:WithTrivia<LeftParen>> <o:CommaMaybe<FunctionOutput>> <r:WithTrivia<RightParen>> => {
690          SyntaxNode::new(SyntaxKind::FunctionOutputs, iter::once(l).chain(o).chain([r]))
691      },
692  }
693  
694  AnnotationKey: LalrToken<'a> = {
695      Identifier,
696      Mapping,
697      Address,
698  }
699  
700  AnnotationName: LalrToken<'a> = {
701      Identifier,
702      // The old parser allows the keyword `program` as an annotation name.
703      Program,
704  }
705  
706  AnnotationMember: SyntaxNode<'a> = {
707      <key:WithTrivia<AnnotationKey>> <a:WithTrivia<Assign>> <value:WithTrivia<StaticString>> => {
708          SyntaxNode::new(SyntaxKind::AnnotationMember, [key, a, value])
709      },
710  }
711  
712  AnnotationList: SyntaxNode<'a> = {
713      <l:WithTrivia<LeftParen>> <c:CommaMaybe<AnnotationMember>> <r:WithTrivia<RightParen>> => {
714          SyntaxNode::new(SyntaxKind::AnnotationList, iter::once(l).chain(c).chain([r]))
715      }
716  }
717  
718  Annotation: SyntaxNode<'a> = {
719      <at:NoTrivia<At>> <n:WithTrivia<AnnotationName>> <list:(AnnotationList)?> => {
720          SyntaxNode::new(SyntaxKind::Annotation, [at, n].into_iter().chain(list))
721      }
722  }
723  
724  // Items.
725  
726  FunctionDeclarationMacro<FunctionKindKind>: SyntaxNode<'a> = {
727       // With a return type.
728      <anns:(Annotation)*> <a:WithTrivia<Async>?> <k:WithTrivia<FunctionKindKind>> <name:WithTrivia<CheckedIdentifier>> <c:(<ConstParameterList>)?> <p:ParameterList> <arrow:WithTrivia<Arrow>> <t:FunctionOutputs> <b:BlockStatement> => {
729          SyntaxNode::new(SyntaxKind::Function, anns.into_iter().chain(a).chain([k, name]).chain(c).chain([p, arrow, t, b]))
730      },
731  
732      // No return type.
733      <anns:(Annotation)*> <a:WithTrivia<Async>?> <k:WithTrivia<FunctionKindKind>> <name:WithTrivia<CheckedIdentifier>> <c:(<ConstParameterList>)?> <p:ParameterList> <b:BlockStatement> => {
734          SyntaxNode::new(SyntaxKind::Function, anns.into_iter().chain(a).chain([k, name]).chain(c).chain([p, b]))
735      },
736  }
737  
738  InlineDeclaration: SyntaxNode<'a> = FunctionDeclarationMacro<Inline>;
739  
740  FunctionDeclaration: SyntaxNode<'a> = FunctionDeclarationMacro<FunctionKind>;
741  
742  ConstructorDeclaration: SyntaxNode<'a> = {
743      <anns:(Annotation)*> <a:WithTrivia<Async>> <c:WithTrivia<Constructor>> <l:WithTrivia<LeftParen>> <r:WithTrivia<RightParen>> <b:BlockStatement> => {
744          SyntaxNode::new(SyntaxKind::Constructor, anns.into_iter().chain([a, c, l, r, b]))
745      },
746  }
747  
748  StructComponentKeyword: LalrToken<'a> = {
749      <Constant> => <>,
750      <Private> => <>,
751      <Public> => <>,
752  }
753  
754  StructMemberDeclaration: SyntaxNode<'a> = {
755      <k:WithTrivia<StructComponentKeyword>?> <i:WithTrivia<CheckedIdentifier>> <c:WithTrivia<Colon>> <t:Type> => {
756          SyntaxNode::new(SyntaxKind::StructMemberDeclaration, k.into_iter().chain([i, c, t]))
757      },
758  }
759  
760  StructMemberDeclarationList: SyntaxNode<'a> = {
761      <l:WithTrivia<LeftCurly>> <v:CommaMaybe<StructMemberDeclaration>> <r:WithTrivia<RightCurly>> => {
762          SyntaxNode::new(SyntaxKind::StructMemberDeclarationList, iter::once(l).chain(v).chain([r]))
763      },
764  }
765  
766  StructDeclaration: SyntaxNode<'a> = {
767      <s:WithTrivia<Struct>> <i:WithTrivia<CheckedIdentifier>> <c:ConstParameterList?> <m:StructMemberDeclarationList> => {
768          SyntaxNode::new(SyntaxKind::StructDeclaration, [s, i].into_iter().chain(c).chain([m]))
769      },
770  }
771  
772  RecordDeclaration: SyntaxNode<'a> = {
773      // We allow a const parameter list so we can later give an error.
774      <r:WithTrivia<Record>> <i:WithTrivia<CheckedIdentifier>> <c:ConstParameterList?> <m:StructMemberDeclarationList> => {
775          SyntaxNode::new(SyntaxKind::StructDeclaration, [r, i].into_iter().chain(c).chain([m]))
776      },
777  }
778  
779  GlobalConst: SyntaxNode<'a> = {
780      <l:WithTrivia<Const>> <i:WithTrivia<CheckedIdentifier>> <c:WithTrivia<Colon>> <t:Type> <a:WithTrivia<Assign>> <e:Expr> <s:WithTrivia<Semicolon>> => {
781          SyntaxNode::new(SyntaxKind::GlobalConst, [l, i, c, t, a, e, s])
782      },
783  }
784  
785  MappingDeclaration: SyntaxNode<'a> = {
786      <m:WithTrivia<Mapping>> <i:WithTrivia<CheckedIdentifier>> <c:WithTrivia<Colon>> <k:Type> <a:WithTrivia<BigArrow>> <v:Type> <s:WithTrivia<Semicolon>> => {
787          SyntaxNode::new(SyntaxKind::Mapping, [m, i, c, k, a, v, s])
788      }
789  }
790  
791  StorageDeclaration: SyntaxNode<'a> = {
792      <m:WithTrivia<Storage>> <i:WithTrivia<CheckedIdentifier>> <c:WithTrivia<Colon>> <t:StorageType> <s:WithTrivia<Semicolon>> => {
793          SyntaxNode::new(SyntaxKind::Storage, [m, i, c, t, s])
794      }
795  }
796  
797  Item: SyntaxNode<'a> = {
798      ConstructorDeclaration,
799      FunctionDeclaration,
800      GlobalConst,
801      MappingDeclaration,
802      StorageDeclaration,
803      RecordDeclaration,
804      StructDeclaration,
805  }
806  
807  ProgramDeclaration: SyntaxNode<'a> = {
808      <p:WithTrivia<Program>> <pid:WithTrivia<ProgramId>> <l:WithTrivia<LeftCurly>> <is:Item*> <r:WithTrivia<RightCurly>> => {
809          SyntaxNode::new(SyntaxKind::ProgramDeclaration, [p, pid, l].into_iter().chain(is).chain([r]))
810      },
811  
812      // For error reporting purposes we catch attempts to declare programs with networks other than `.alpha`.
813      <p:WithTrivia<Program>> <name:NoTrivia<Identifier>> <d:NoTrivia<Dot>> <net:WithTrivia<Identifier>> <l:WithTrivia<LeftCurly>> <is:Item*> <r:WithTrivia<RightCurly>> => {
814          handler.emit_err(ParserError::invalid_network(net.span));
815          SyntaxNode::new(SyntaxKind::ProgramDeclaration, [p, name, d, net, l].into_iter().chain(is).chain([r]))
816      },
817  }
818  
819  ImportDeclaration: SyntaxNode<'a> = {
820      <i:WithTrivia<Import>> <pid:WithTrivia<ProgramId>> <s:WithTrivia<Semicolon>> => {
821          SyntaxNode::new(SyntaxKind::Import, [i, pid, s])
822      },
823  }
824  
825  pub MainContents: SyntaxNode<'a> = {
826      <ns:Nonsemantic*> <is:ImportDeclaration*> <p:ProgramDeclaration> => {
827          SyntaxNode::new(SyntaxKind::MainContents, ns.into_iter().chain(is).chain([p]))
828      },
829  }
830  
831  ModuleItem: SyntaxNode<'a> = {
832      InlineDeclaration,
833      GlobalConst,
834      StructDeclaration,
835  }
836  
837  pub ModuleContents: SyntaxNode<'a> = {
838      <ns:Nonsemantic*> <is:ModuleItem*> => {
839          SyntaxNode::new(SyntaxKind::ModuleContents, ns.into_iter().chain(is))
840      },
841  }
842  
843  extern {
844      type Location = usize;
845      type Error = &'static str;
846  
847      enum LalrToken<'a> {
848          Whitespace => LalrToken { token: Token::Whitespace, .. },
849          Linebreak => LalrToken { token: Token::Linebreak, .. },
850  
851          CommentLine => LalrToken { token: Token::CommentLine, .. },
852          CommentBlock => LalrToken { token: Token::CommentBlock, .. },
853  
854          Identifier => LalrToken { token: Token::IdVariants(IdVariants::Identifier), .. },
855          Intrinsic => LalrToken { token: Token::IdVariants(IdVariants::Intrinsic), .. },
856          ProgramId => LalrToken { token: Token::IdVariants(IdVariants::ProgramId), .. },
857          Locator => LalrToken { token: Token::IdVariants(IdVariants::Locator), .. },
858          RealPath => LalrToken { token: Token::IdVariants(IdVariants::Path), .. },
859  
860          AddressLiteral => LalrToken { token: Token::AddressLiteral, .. },
861  
862          Integer => LalrToken { token: Token::Integer, .. },
863          StaticString => LalrToken { token: Token::StaticString, .. },
864  
865          // Symbols
866          Assign => LalrToken { token: Token::Assign, .. },
867          Not => LalrToken { token: Token::Not, .. },
868          And => LalrToken { token: Token::And, .. },
869          Or => LalrToken { token: Token::Or, .. },
870          AndAssign => LalrToken { token: Token::AndAssign, .. },
871          OrAssign => LalrToken { token: Token::OrAssign, .. },
872          BitAnd => LalrToken { token: Token::BitAnd, .. },
873          BitAndAssign => LalrToken { token: Token::BitAndAssign, .. },
874          BitOr => LalrToken { token: Token::BitOr, .. },
875          BitOrAssign => LalrToken { token: Token::BitOrAssign, .. },
876          BitXor => LalrToken { token: Token::BitXor, .. },
877          BitXorAssign => LalrToken { token: Token::BitXorAssign, .. },
878          Eq => LalrToken { token: Token::Eq, .. },
879          NotEq => LalrToken { token: Token::NotEq, .. },
880          Lt => LalrToken { token: Token::Lt, .. },
881          LtEq => LalrToken { token: Token::LtEq, .. },
882          Gt => LalrToken { token: Token::Gt, .. },
883          GtEq => LalrToken { token: Token::GtEq, .. },
884          Add => LalrToken { token: Token::Add, .. },
885          AddAssign => LalrToken { token: Token::AddAssign, .. },
886          Sub => LalrToken { token: Token::Sub, .. },
887          SubAssign => LalrToken { token: Token::SubAssign, .. },
888          Mul => LalrToken { token: Token::Mul, .. },
889          MulAssign => LalrToken { token: Token::MulAssign, .. },
890          Div => LalrToken { token: Token::Div, .. },
891          DivAssign => LalrToken { token: Token::DivAssign, .. },
892          Pow => LalrToken { token: Token::Pow, .. },
893          PowAssign => LalrToken { token: Token::PowAssign, .. },
894          Rem => LalrToken { token: Token::Rem, .. },
895          RemAssign => LalrToken { token: Token::RemAssign, .. },
896          Shl => LalrToken { token: Token::Shl, .. },
897          ShlAssign => LalrToken { token: Token::ShlAssign, .. },
898          Shr => LalrToken { token: Token::Shr, .. },
899          ShrAssign => LalrToken { token: Token::ShrAssign, .. },
900          LeftParen => LalrToken { token: Token::LeftParen, .. },
901          RightParen => LalrToken { token: Token::RightParen, .. },
902          LeftSquare => LalrToken { token: Token::LeftSquare, .. },
903          RightSquare => LalrToken { token: Token::RightSquare, .. },
904          LeftCurly => LalrToken { token: Token::LeftCurly, .. },
905          RightCurly => LalrToken { token: Token::RightCurly, .. },
906          Comma => LalrToken { token: Token::Comma, .. },
907          Dot => LalrToken { token: Token::Dot, .. },
908          DotDot => LalrToken { token: Token::DotDot, .. },
909          Semicolon => LalrToken { token: Token::Semicolon, .. },
910          Colon => LalrToken { token: Token::Colon, .. },
911          DoubleColon => LalrToken{ token: Token::DoubleColon, .. },
912          Question => LalrToken{ token: Token::Question, .. },
913          Arrow => LalrToken{ token: Token::Arrow, .. },
914          BigArrow => LalrToken{ token: Token::BigArrow, .. },
915          At => LalrToken{ token: Token::At, .. },
916          Underscore => LalrToken { token: Token::Underscore, .. },
917  
918          // Keywords
919          True => LalrToken { token: Token::True, .. },
920          False => LalrToken { token: Token::False, .. },
921          None => LalrToken { token: Token::None, .. },
922          Address => LalrToken { token: Token::Address, .. },
923          Bool => LalrToken { token: Token::Bool, .. },
924          Field => LalrToken { token: Token::Field, .. },
925          Group => LalrToken { token: Token::Group, .. },
926          Record => LalrToken { token: Token::Record, .. },
927          Scalar => LalrToken { token: Token::Scalar, .. },
928          Signature => LalrToken { token: Token::Signature, .. },
929          Struct => LalrToken { token: Token::Struct, .. },
930          String => LalrToken { token: Token::String, .. },
931  
932          I8 => LalrToken { token: Token::I8, .. },
933          I16 => LalrToken { token: Token::I16, .. },
934          I32 => LalrToken { token: Token::I32, .. },
935          I64 => LalrToken { token: Token::I64, .. },
936          I128 => LalrToken { token: Token::I128, .. },
937          U8 => LalrToken { token: Token::U8, .. },
938          U16 => LalrToken { token: Token::U16, .. },
939          U32 => LalrToken { token: Token::U32, .. },
940          U64 => LalrToken { token: Token::U64, .. },
941          U128 => LalrToken { token: Token::U128, .. },
942  
943          Alpha => LalrToken { token: Token::Alpha, .. },
944          Delta => LalrToken { token: Token::Delta, .. },
945          As => LalrToken { token: Token::As, .. },
946          Assert => LalrToken { token: Token::Assert, .. },
947          AssertEq => LalrToken { token: Token::AssertEq, .. },
948          AssertNeq => LalrToken { token: Token::AssertNeq, .. },
949          Async => LalrToken { token: Token::Async, .. },
950          Block => LalrToken { token: Token::Block, .. },
951          Const => LalrToken { token: Token::Const, .. },
952          Constant => LalrToken { token: Token::Constant, .. },
953          Constructor => LalrToken { token: Token::Constructor, .. },
954          Else => LalrToken { token: Token::Else, .. },
955          Fn => LalrToken { token: Token::Fn, .. },
956          For => LalrToken { token: Token::For, .. },
957          Function => LalrToken { token: Token::Function, .. },
958          Future => LalrToken { token: Token::Future, .. },
959          If => LalrToken { token: Token::If, .. },
960          Import => LalrToken { token: Token::Import, .. },
961          In => LalrToken { token: Token::In, .. },
962          Inline => LalrToken { token: Token::Inline, .. },
963          Let => LalrToken { token: Token::Let, .. },
964          Mapping => LalrToken { token: Token::Mapping, .. },
965          Storage => LalrToken { token: Token::Storage, .. },
966          Network => LalrToken { token: Token::Network, .. },
967          Private => LalrToken { token: Token::Private, .. },
968          Program => LalrToken { token: Token::Program, .. },
969          Public => LalrToken { token: Token::Public, .. },
970          Return => LalrToken { token: Token::Return, .. },
971          Script => LalrToken { token: Token::Script, .. },
972          SelfLower => LalrToken { token: Token::SelfLower, .. },
973          Transition => LalrToken { token: Token::Transition, .. },
974  
975          Never => LalrToken { token: Token::Never, .. },
976      }
977  }