Skip to main content

cairo_lang_syntax_codegen/
cairo_spec.rs

1use crate::spec::{EnumBuilder, Node, NodesAggregator, StructBuilder};
2
3/// The syntax specification of Cairo.
4pub fn get_spec() -> Vec<Node> {
5    NodesAggregator::default()
6        .add_list("Trivia", "Trivium")
7        .add_enum(
8            EnumBuilder::new("Trivium")
9                .node_with_explicit_kind("SingleLineComment", "TokenSingleLineComment")
10                .node_with_explicit_kind("SingleLineDocComment", "TokenSingleLineDocComment")
11                .node_with_explicit_kind("SingleLineInnerComment", "TokenSingleLineInnerComment")
12                .node_with_explicit_kind("Whitespace", "TokenWhitespace")
13                .node_with_explicit_kind("Newline", "TokenNewline")
14                .node_with_explicit_kind("Skipped", "TokenSkipped")
15                .node("SkippedNode"),
16        )
17        // --- Expressions ---
18        .add_enum(
19            EnumBuilder::new("Expr")
20                .include_missing()
21                .node("Path")
22                .node_with_explicit_kind("Literal", "TerminalLiteralNumber")
23                .node_with_explicit_kind("ShortString", "TerminalShortString")
24                .node_with_explicit_kind("String", "TerminalString")
25                .node_with_explicit_kind("False", "TerminalFalse")
26                .node_with_explicit_kind("True", "TerminalTrue")
27                .node("Parenthesized")
28                .node("Unary")
29                .node("Binary")
30                .node_with_explicit_kind("Tuple", "ExprListParenthesized")
31                .node("FunctionCall")
32                .node("StructCtorCall")
33                .node("Block")
34                .node("Match")
35                .node("If")
36                .node("Loop")
37                .node("While")
38                .node("For")
39                .node("Closure")
40                .node("ErrorPropagate")
41                .node("FieldInitShorthand")
42                .node("Indexed")
43                .node("InlineMacro")
44                .node("FixedSizeArray")
45                .node_with_explicit_kind("Underscore", "TerminalUnderscore"),
46        )
47        .add_separated_list("ExprList", "Expr", "TerminalComma")
48        .add_struct(
49            StructBuilder::new("Arg")
50                .node("modifiers", "ModifierList")
51                .node("arg_clause", "ArgClause"),
52        )
53        .add_enum(
54            EnumBuilder::new("ArgClause").node("Unnamed").node("Named").node("FieldInitShorthand"),
55        )
56        .add_struct(
57            StructBuilder::new("ArgClauseNamed")
58                .node("name", "TerminalIdentifier")
59                .node("colon", "TerminalColon")
60                .node("value", "Expr"),
61        )
62        .add_struct(StructBuilder::new("ArgClauseUnnamed").node("value", "Expr"))
63        .add_struct(
64            StructBuilder::new("ArgClauseFieldInitShorthand")
65                .node("colon", "TerminalColon")
66                .node("name", "ExprFieldInitShorthand"),
67        )
68        .add_struct(StructBuilder::new("ExprFieldInitShorthand").node("name", "TerminalIdentifier"))
69        .add_separated_list("ArgList", "Arg", "TerminalComma")
70        .add_enum(EnumBuilder::new("PathSegment").node("Simple").node("WithGenericArgs"))
71        .add_struct(StructBuilder::new("PathSegmentSimple").node("ident", "TerminalIdentifier"))
72        .add_option("TerminalColonColon")
73        .add_struct(
74            StructBuilder::new("PathSegmentWithGenericArgs")
75                .node("ident", "TerminalIdentifier")
76                .node("separator", "OptionTerminalColonColon")
77                .node("generic_args", "GenericArgs"),
78        )
79        .add_struct(
80            StructBuilder::new("ExprPath")
81                .node("dollar", "OptionTerminalDollar")
82                .node("segments", "ExprPathInner"),
83        )
84        .add_option("TerminalDollar")
85        .add_separated_list("ExprPathInner", "PathSegment", "TerminalColonColon")
86        .add_struct(
87            StructBuilder::new("ExprParenthesized")
88                .node("lparen", "TerminalLParen")
89                .node("expr", "Expr")
90                .node("rparen", "TerminalRParen"),
91        )
92        .add_struct(
93            StructBuilder::new("ExprUnary").node("op", "UnaryOperator").node("expr", "Expr"),
94        )
95        .add_enum(
96            EnumBuilder::new("UnaryOperator")
97                .node_with_explicit_kind("Not", "TerminalNot")
98                .node_with_explicit_kind("BitNot", "TerminalBitNot")
99                .node_with_explicit_kind("Minus", "TerminalMinus")
100                .node_with_explicit_kind("At", "TerminalAt")
101                .node_with_explicit_kind("Desnap", "TerminalMul")
102                .node_with_explicit_kind("Reference", "TerminalAnd"),
103        )
104        .add_struct(
105            StructBuilder::new("ExprBinary")
106                .node("lhs", "Expr")
107                .node("op", "BinaryOperator")
108                .node("rhs", "Expr"),
109        )
110        .add_enum(
111            EnumBuilder::new("BinaryOperator")
112                .node_with_explicit_kind("Dot", "TerminalDot")
113                .node_with_explicit_kind("Not", "TerminalNot")
114                .node_with_explicit_kind("Mul", "TerminalMul")
115                .node_with_explicit_kind("MulEq", "TerminalMulEq")
116                .node_with_explicit_kind("Div", "TerminalDiv")
117                .node_with_explicit_kind("DivEq", "TerminalDivEq")
118                .node_with_explicit_kind("Mod", "TerminalMod")
119                .node_with_explicit_kind("ModEq", "TerminalModEq")
120                .node_with_explicit_kind("Plus", "TerminalPlus")
121                .node_with_explicit_kind("PlusEq", "TerminalPlusEq")
122                .node_with_explicit_kind("Minus", "TerminalMinus")
123                .node_with_explicit_kind("MinusEq", "TerminalMinusEq")
124                .node_with_explicit_kind("EqEq", "TerminalEqEq")
125                .node_with_explicit_kind("Neq", "TerminalNeq")
126                .node_with_explicit_kind("Eq", "TerminalEq")
127                .node_with_explicit_kind("And", "TerminalAnd")
128                .node_with_explicit_kind("AndAnd", "TerminalAndAnd")
129                .node_with_explicit_kind("Or", "TerminalOr")
130                .node_with_explicit_kind("OrOr", "TerminalOrOr")
131                .node_with_explicit_kind("Xor", "TerminalXor")
132                .node_with_explicit_kind("LE", "TerminalLE")
133                .node_with_explicit_kind("GE", "TerminalGE")
134                .node_with_explicit_kind("LT", "TerminalLT")
135                .node_with_explicit_kind("GT", "TerminalGT")
136                .node_with_explicit_kind("DotDot", "TerminalDotDot")
137                .node_with_explicit_kind("DotDotEq", "TerminalDotDotEq"),
138        )
139        .add_struct(
140            StructBuilder::new("ExprListParenthesized")
141                .node("lparen", "TerminalLParen")
142                .node("expressions", "ExprList")
143                .node("rparen", "TerminalRParen"),
144        )
145        .add_struct(
146            StructBuilder::new("ExprFunctionCall")
147                .node("path", "ExprPath")
148                .node("arguments", "ArgListParenthesized"),
149        )
150        .add_struct(
151            StructBuilder::new("ArgListParenthesized")
152                .node("lparen", "TerminalLParen")
153                .node("arguments", "ArgList")
154                .node("rparen", "TerminalRParen"),
155        )
156        .add_option("ArgListParenthesized")
157        .add_struct(
158            StructBuilder::new("ExprStructCtorCall")
159                .node("path", "ExprPath")
160                .node("arguments", "StructArgListBraced"),
161        )
162        .add_struct(
163            StructBuilder::new("StructArgListBraced")
164                .node("lbrace", "TerminalLBrace")
165                .node("arguments", "StructArgList")
166                .node("rbrace", "TerminalRBrace"),
167        )
168        .add_struct(
169            StructBuilder::new("ExprBlock")
170                .node("lbrace", "TerminalLBrace")
171                .node("statements", "StatementList")
172                .node("rbrace", "TerminalRBrace"),
173        )
174        .add_struct(
175            StructBuilder::new("ExprMatch")
176                .node("match_kw", "TerminalMatch")
177                // TODO(yuval): change to SimpleExpr
178                .node("expr", "Expr")
179                .node("lbrace", "TerminalLBrace")
180                .node("arms", "MatchArms")
181                .node("rbrace", "TerminalRBrace"),
182        )
183        .add_separated_list("MatchArms", "MatchArm", "TerminalComma")
184        .add_struct(
185            StructBuilder::new("MatchArm")
186                .node("patterns", "PatternListOr")
187                .node("arrow", "TerminalMatchArrow")
188                .node("expression", "Expr"),
189        )
190        .add_struct(
191            StructBuilder::new("ExprIf")
192                .node("if_kw", "TerminalIf")
193                .node("conditions", "ConditionListAnd")
194                .node("if_block", "ExprBlock")
195                .node("else_clause", "OptionElseClause"),
196        )
197        .add_separated_list("ConditionListAnd", "Condition", "TerminalAndAnd")
198        .add_enum(EnumBuilder::new("Condition").node("Let").node("Expr"))
199        .add_struct(
200            StructBuilder::new("ConditionLet")
201                .node("let_kw", "TerminalLet")
202                .node("patterns", "PatternListOr")
203                .node("eq", "TerminalEq")
204                .node("expr", "Expr"),
205        )
206        .add_struct(StructBuilder::new("ConditionExpr").node("expr", "Expr"))
207        .add_enum(
208            EnumBuilder::new("BlockOrIf")
209                .node_with_explicit_kind("Block", "ExprBlock")
210                .node_with_explicit_kind("If", "ExprIf"),
211        )
212        .add_struct(
213            StructBuilder::new("ExprLoop")
214                .node("loop_kw", "TerminalLoop")
215                .node("body", "ExprBlock"),
216        )
217        .add_struct(
218            StructBuilder::new("ExprWhile")
219                .node("while_kw", "TerminalWhile")
220                .node("conditions", "ConditionListAnd")
221                .node("body", "ExprBlock"),
222        )
223        .add_struct(
224            StructBuilder::new("ExprFor")
225                .node("for_kw", "TerminalFor")
226                .key_node("pattern", "Pattern")
227                .key_node("identifier", "TerminalIdentifier")
228                .node("expr", "Expr")
229                .node("body", "ExprBlock"),
230        )
231        .add_struct(
232            StructBuilder::new("ElseClause")
233                .node("else_kw", "TerminalElse")
234                .node("else_block_or_if", "BlockOrIf"),
235        )
236        .add_option("ElseClause")
237        .add_struct(
238            StructBuilder::new("ExprErrorPropagate")
239                .node("expr", "Expr")
240                .node("op", "TerminalQuestionMark"),
241        )
242        .add_struct(
243            StructBuilder::new("ExprIndexed")
244                .node("expr", "Expr")
245                .node("lbrack", "TerminalLBrack")
246                .node("index_expr", "Expr")
247                .node("rbrack", "TerminalRBrack"),
248        )
249        .add_struct(
250            StructBuilder::new("ExprFixedSizeArray")
251                .node("lbrack", "TerminalLBrack")
252                .node("exprs", "ExprList")
253                .node("size", "OptionFixedSizeArraySize")
254                .node("rbrack", "TerminalRBrack"),
255        )
256        .add_struct(
257            StructBuilder::new("FixedSizeArraySize")
258                .node("semicolon", "TerminalSemicolon")
259                .node("size", "Expr"),
260        )
261        .add_option("FixedSizeArraySize")
262        .add_struct(
263            StructBuilder::new("ExprClosure")
264                .node("params", "ClosureParams")
265                .node("ret_ty", "OptionReturnTypeClause")
266                .node("optional_no_panic", "OptionTerminalNoPanic")
267                .node("expr", "Expr"),
268        )
269        .add_struct(
270            StructBuilder::new("ClosureParams")
271                .node("leftor", "TerminalOr")
272                .node("params", "ParamList")
273                .node("rightor", "TerminalOr"),
274        )
275        // --- Struct ctor ---
276        .add_struct(
277            StructBuilder::new("StructArgExpr").node("colon", "TerminalColon").node("expr", "Expr"),
278        )
279        .add_option("StructArgExpr")
280        .add_struct(
281            StructBuilder::new("StructArgSingle")
282                .key_node("identifier", "TerminalIdentifier")
283                .node("arg_expr", "OptionStructArgExpr"),
284        )
285        .add_struct(
286            StructBuilder::new("StructArgTail")
287                .node("dotdot", "TerminalDotDot")
288                .node("expression", "Expr"),
289        )
290        .add_enum(
291            EnumBuilder::new("StructArg")
292                .node_with_explicit_kind("StructArgSingle", "StructArgSingle")
293                .node_with_explicit_kind("StructArgTail", "StructArgTail"),
294        )
295        .add_separated_list("StructArgList", "StructArg", "TerminalComma")
296        .add_struct(
297            StructBuilder::new("ArgListBraced")
298                .node("lbrace", "TerminalLBrace")
299                .node("arguments", "ArgList")
300                .node("rbrace", "TerminalRBrace"),
301        )
302        .add_struct(
303            StructBuilder::new("ArgListBracketed")
304                .node("lbrack", "TerminalLBrack")
305                .node("arguments", "ArgList")
306                .node("rbrack", "TerminalRBrack"),
307        )
308        .add_enum(
309            EnumBuilder::new("WrappedArgList")
310                .include_missing()
311                .node_with_explicit_kind("BracketedArgList", "ArgListBracketed")
312                .node_with_explicit_kind("ParenthesizedArgList", "ArgListParenthesized")
313                .node_with_explicit_kind("BracedArgList", "ArgListBraced"),
314        )
315        // ---Patterns ---
316        .add_enum(
317            EnumBuilder::new("Pattern")
318                .node_with_explicit_kind("Underscore", "TerminalUnderscore")
319                .node_with_explicit_kind("Literal", "TerminalLiteralNumber")
320                .node_with_explicit_kind("False", "TerminalFalse")
321                .node_with_explicit_kind("True", "TerminalTrue")
322                .node_with_explicit_kind("ShortString", "TerminalShortString")
323                .node_with_explicit_kind("String", "TerminalString")
324                .node("Identifier")
325                .node("Struct")
326                .node("Tuple")
327                .node("Enum")
328                .node("FixedSizeArray")
329                .node_with_explicit_kind("Path", "ExprPath"),
330        )
331        .add_struct(
332            StructBuilder::new("PatternIdentifier")
333                .node("modifiers", "ModifierList")
334                .key_node("name", "TerminalIdentifier"),
335        )
336        .add_struct(
337            StructBuilder::new("PatternStruct")
338                // TODO(spapini): Use SimplePath instead - which is not an expr.
339                .node("path", "ExprPath")
340                .node("lbrace", "TerminalLBrace")
341                .node("params", "PatternStructParamList")
342                .node("rbrace", "TerminalRBrace"),
343        )
344        .add_separated_list("PatternStructParamList", "PatternStructParam", "TerminalComma")
345        .add_struct(
346            StructBuilder::new("PatternTuple")
347                .node("lparen", "TerminalLParen")
348                .node("patterns", "PatternList")
349                .node("rparen", "TerminalRParen"),
350        )
351        .add_struct(
352            StructBuilder::new("PatternFixedSizeArray")
353                .node("lbrack", "TerminalLBrack")
354                .node("patterns", "PatternList")
355                .node("rbrack", "TerminalRBrack"),
356        )
357        .add_separated_list("PatternList", "Pattern", "TerminalComma")
358        .add_separated_list("PatternListOr", "Pattern", "TerminalOr")
359        .add_enum(
360            EnumBuilder::new("PatternStructParam")
361                .node_with_explicit_kind("Single", "PatternIdentifier")
362                .node("WithExpr")
363                .node_with_explicit_kind("Tail", "TerminalDotDot"),
364        )
365        .add_struct(
366            StructBuilder::new("PatternStructParamWithExpr")
367                .node("modifiers", "ModifierList")
368                .node("name", "TerminalIdentifier")
369                .node("colon", "TerminalColon")
370                .node("pattern", "Pattern"),
371        )
372        .add_struct(
373            StructBuilder::new("PatternEnum")
374                .node("path", "ExprPath")
375                .node("pattern", "OptionPatternEnumInnerPattern"),
376        )
377        .add_struct(
378            StructBuilder::new("PatternEnumInnerPattern")
379                .node("lparen", "TerminalLParen")
380                .node("pattern", "Pattern")
381                .node("rparen", "TerminalRParen"),
382        )
383        .add_option("PatternEnumInnerPattern")
384        // --- Type clauses ---
385        // TODO(yuval): support SimpleExpr instead of Expr
386        .add_struct(
387            StructBuilder::new("TypeClause").node("colon", "TerminalColon").node("ty", "Expr"),
388        )
389        .add_option("TypeClause")
390        .add_struct(
391            StructBuilder::new("ReturnTypeClause")
392                .node("arrow", "TerminalArrow")
393                .node("ty", "Expr"),
394        )
395        .add_option("ReturnTypeClause")
396        // --- Statements ---
397        .add_enum(
398            EnumBuilder::new("Statement")
399                .include_missing()
400                .node("Let")
401                .node("Expr")
402                .node("Continue")
403                .node("Return")
404                .node("Break")
405                .node("Item"),
406        )
407        .add_list("StatementList", "Statement")
408        .add_struct(
409            StructBuilder::new("StatementLet")
410                .node("attributes", "AttributeList")
411                .node("let_kw", "TerminalLet")
412                .key_node("pattern", "Pattern")
413                .node("type_clause", "OptionTypeClause")
414                .node("eq", "TerminalEq")
415                .node("rhs", "Expr")
416                .node("let_else_clause", "OptionLetElseClause")
417                .node("semicolon", "TerminalSemicolon"),
418        )
419        .add_struct(
420            StructBuilder::new("LetElseClause")
421                .node("else_kw", "TerminalElse")
422                .node("else_block", "ExprBlock"),
423        )
424        .add_option("LetElseClause")
425        .add_option("TerminalSemicolon")
426        .add_struct(
427            StructBuilder::new("StatementExpr")
428                .node("attributes", "AttributeList")
429                .node("expr", "Expr")
430                .node("semicolon", "OptionTerminalSemicolon"),
431        )
432        .add_struct(
433            StructBuilder::new("StatementContinue")
434                .node("attributes", "AttributeList")
435                .node("continue_kw", "TerminalContinue")
436                .node("semicolon", "TerminalSemicolon"),
437        )
438        .add_struct(StructBuilder::new("ExprClause").node("expr", "Expr"))
439        .add_option("ExprClause")
440        .add_struct(
441            StructBuilder::new("StatementReturn")
442                .node("attributes", "AttributeList")
443                .node("return_kw", "TerminalReturn")
444                .node("expr_clause", "OptionExprClause")
445                .node("semicolon", "TerminalSemicolon"),
446        )
447        .add_struct(
448            StructBuilder::new("StatementBreak")
449                .node("attributes", "AttributeList")
450                .node("break_kw", "TerminalBreak")
451                .node("expr_clause", "OptionExprClause")
452                .node("semicolon", "TerminalSemicolon"),
453        )
454        .add_struct(StructBuilder::new("StatementItem").node("item", "ModuleItem"))
455        // --- Functions ---
456        .add_struct(
457            StructBuilder::new("Param")
458                .node("modifiers", "ModifierList")
459                .key_node("name", "TerminalIdentifier")
460                .node("type_clause", "OptionTypeClause"),
461        )
462        .add_list("ModifierList", "Modifier")
463        .add_enum(
464            EnumBuilder::new("Modifier")
465                .node_with_explicit_kind("Ref", "TerminalRef")
466                .node_with_explicit_kind("Mut", "TerminalMut"),
467        )
468        .add_separated_list("ParamList", "Param", "TerminalComma")
469        .add_struct(
470            StructBuilder::new("ImplicitsClause")
471                .node("implicits_kw", "TerminalImplicits")
472                .node("lparen", "TerminalLParen")
473                .node("implicits", "ImplicitsList")
474                .node("rparen", "TerminalRParen"),
475        )
476        .add_separated_list("ImplicitsList", "ExprPath", "TerminalComma")
477        .add_option("ImplicitsClause")
478        .add_option("TerminalNoPanic")
479        .add_option("TerminalConst")
480        // TODO(spapini): Add generic params.
481        // This is an unnamed signature, e.g. "() -> Type".
482        .add_struct(
483            StructBuilder::new("FunctionSignature")
484                .node("lparen", "TerminalLParen")
485                .node("parameters", "ParamList")
486                .node("rparen", "TerminalRParen")
487                .node("ret_ty", "OptionReturnTypeClause")
488                .node("implicits_clause", "OptionImplicitsClause")
489                .node("optional_no_panic", "OptionTerminalNoPanic"),
490        )
491        // --- Struct Members ---
492        // Struct member and enum variant have the same structure.
493        .add_struct(
494            StructBuilder::new("Member")
495                .node("attributes", "AttributeList")
496                .node("visibility", "Visibility")
497                .key_node("name", "TerminalIdentifier")
498                .node("type_clause", "TypeClause"),
499        )
500        .add_separated_list("MemberList", "Member", "TerminalComma")
501        .add_struct(
502            StructBuilder::new("Variant")
503                .node("attributes", "AttributeList")
504                .key_node("name", "TerminalIdentifier")
505                .node("type_clause", "OptionTypeClause"),
506        )
507        .add_separated_list("VariantList", "Variant", "TerminalComma")
508        // --- Items ---
509        .add_enum(
510            EnumBuilder::new("ModuleItem")
511                .include_missing()
512                .node_with_explicit_kind("Constant", "ItemConstant")
513                .node_with_explicit_kind("Module", "ItemModule")
514                .node_with_explicit_kind("Use", "ItemUse")
515                .node_with_explicit_kind("FreeFunction", "FunctionWithBody")
516                .node_with_explicit_kind("ExternFunction", "ItemExternFunction")
517                .node_with_explicit_kind("ExternType", "ItemExternType")
518                .node_with_explicit_kind("Trait", "ItemTrait")
519                .node_with_explicit_kind("Impl", "ItemImpl")
520                .node_with_explicit_kind("ImplAlias", "ItemImplAlias")
521                .node_with_explicit_kind("Struct", "ItemStruct")
522                .node_with_explicit_kind("Enum", "ItemEnum")
523                .node_with_explicit_kind("TypeAlias", "ItemTypeAlias")
524                .node_with_explicit_kind("InlineMacro", "ItemInlineMacro")
525                .node_with_explicit_kind("MacroDeclaration", "ItemMacroDeclaration")
526                .node_with_explicit_kind("HeaderDoc", "ItemHeaderDoc"),
527        )
528        .add_list("ModuleItemList", "ModuleItem")
529        .add_struct(
530            StructBuilder::new("Attribute")
531                .node("hash", "TerminalHash")
532                .node("lbrack", "TerminalLBrack")
533                .node("attr", "ExprPath")
534                .node("arguments", "OptionArgListParenthesized")
535                .node("rbrack", "TerminalRBrack"),
536        )
537        .add_list("AttributeList", "Attribute")
538        .add_struct(StructBuilder::new("VisibilityDefault"))
539        .add_struct(
540            StructBuilder::new("VisibilityPubArgumentClause")
541                .node("lparen", "TerminalLParen")
542                .node("argument", "TerminalIdentifier")
543                .node("rparen", "TerminalRParen"),
544        )
545        .add_option("VisibilityPubArgumentClause")
546        .add_struct(
547            StructBuilder::new("VisibilityPub")
548                .node("pub_kw", "TerminalPub")
549                .node("argument_clause", "OptionVisibilityPubArgumentClause"),
550        )
551        .add_enum(EnumBuilder::new("Visibility").node("Default").node("Pub"))
552        .add_struct(
553            StructBuilder::new("ItemModule")
554                .node("attributes", "AttributeList")
555                .node("visibility", "Visibility")
556                .node("module_kw", "TerminalModule")
557                .key_node("name", "TerminalIdentifier")
558                .node("body", "MaybeModuleBody"),
559        )
560        .add_enum(
561            EnumBuilder::new("MaybeModuleBody")
562                .node_with_explicit_kind("Some", "ModuleBody")
563                .node_with_explicit_kind("None", "TerminalSemicolon"),
564        )
565        .add_struct(
566            StructBuilder::new("ModuleBody")
567                .node("lbrace", "TerminalLBrace")
568                .node("items", "ModuleItemList")
569                .node("rbrace", "TerminalRBrace"),
570        )
571        .add_struct(
572            StructBuilder::new("FunctionDeclaration")
573                .node("optional_const", "OptionTerminalConst")
574                .node("function_kw", "TerminalFunction")
575                .key_node("name", "TerminalIdentifier")
576                .node("generic_params", "OptionWrappedGenericParamList")
577                .node("signature", "FunctionSignature"),
578        )
579        .add_struct(
580            StructBuilder::new("ItemConstant")
581                .node("attributes", "AttributeList")
582                .node("visibility", "Visibility")
583                .node("const_kw", "TerminalConst")
584                .key_node("name", "TerminalIdentifier")
585                .node("type_clause", "TypeClause")
586                .node("eq", "TerminalEq")
587                .node("value", "Expr")
588                .node("semicolon", "TerminalSemicolon"),
589        )
590        .add_struct(
591            StructBuilder::new("FunctionWithBody")
592                .node("attributes", "AttributeList")
593                .node("visibility", "Visibility")
594                // TODO(ilya): Use only the name as key node.
595                .key_node("declaration", "FunctionDeclaration")
596                .node("body", "ExprBlock"),
597        )
598        .add_struct(
599            StructBuilder::new("ItemExternFunction")
600                .node("attributes", "AttributeList")
601                .node("visibility", "Visibility")
602                .node("extern_kw", "TerminalExtern")
603                // TODO(ilya): Use only the name as key node.
604                .key_node("declaration", "FunctionDeclaration")
605                .node("semicolon", "TerminalSemicolon"),
606        )
607        .add_struct(
608            StructBuilder::new("ItemExternType")
609                .node("attributes", "AttributeList")
610                .node("visibility", "Visibility")
611                .node("extern_kw", "TerminalExtern")
612                .node("type_kw", "TerminalType")
613                .key_node("name", "TerminalIdentifier")
614                .node("generic_params", "OptionWrappedGenericParamList")
615                .node("semicolon", "TerminalSemicolon"),
616        )
617        .add_struct(
618            StructBuilder::new("ItemTrait")
619                .node("attributes", "AttributeList")
620                .node("visibility", "Visibility")
621                .node("trait_kw", "TerminalTrait")
622                .key_node("name", "TerminalIdentifier")
623                .node("generic_params", "OptionWrappedGenericParamList")
624                .node("body", "MaybeTraitBody"),
625        )
626        .add_enum(
627            EnumBuilder::new("MaybeTraitBody")
628                .node_with_explicit_kind("Some", "TraitBody")
629                .node_with_explicit_kind("None", "TerminalSemicolon"),
630        )
631        .add_struct(
632            StructBuilder::new("TraitBody")
633                .node("lbrace", "TerminalLBrace")
634                .node("items", "TraitItemList")
635                .node("rbrace", "TerminalRBrace"),
636        )
637        .add_list("TraitItemList", "TraitItem")
638        .add_enum(
639            EnumBuilder::new("TraitItem")
640                .include_missing()
641                .node("Function")
642                .node("Type")
643                .node("Constant")
644                .node("Impl"),
645        )
646        .add_struct(
647            StructBuilder::new("TraitItemFunction")
648                .node("attributes", "AttributeList")
649                // TODO(ilya): Use only the name as key node.
650                .key_node("declaration", "FunctionDeclaration")
651                .node("body", "MaybeTraitFunctionBody"),
652        )
653        .add_struct(
654            StructBuilder::new("TraitItemType")
655                .node("attributes", "AttributeList")
656                .node("type_kw", "TerminalType")
657                .key_node("name", "TerminalIdentifier")
658                .node("generic_params", "OptionWrappedGenericParamList")
659                .node("semicolon", "TerminalSemicolon"),
660        )
661        .add_struct(
662            StructBuilder::new("TraitItemConstant")
663                .node("attributes", "AttributeList")
664                .node("const_kw", "TerminalConst")
665                .key_node("name", "TerminalIdentifier")
666                .node("type_clause", "TypeClause")
667                .node("semicolon", "TerminalSemicolon"),
668        )
669        .add_struct(
670            StructBuilder::new("TraitItemImpl")
671                .node("attributes", "AttributeList")
672                .node("impl_kw", "TerminalImpl")
673                .key_node("name", "TerminalIdentifier")
674                .node("colon", "TerminalColon")
675                .node("trait_path", "ExprPath")
676                .node("semicolon", "TerminalSemicolon"),
677        )
678        .add_enum(
679            EnumBuilder::new("MaybeTraitFunctionBody")
680                .node_with_explicit_kind("Some", "ExprBlock")
681                .node_with_explicit_kind("None", "TerminalSemicolon"),
682        )
683        .add_struct(
684            StructBuilder::new("ItemImpl")
685                .node("attributes", "AttributeList")
686                .node("visibility", "Visibility")
687                .node("impl_kw", "TerminalImpl")
688                .key_node("name", "TerminalIdentifier")
689                .node("generic_params", "OptionWrappedGenericParamList")
690                .node("of_kw", "TerminalOf")
691                .node("trait_path", "ExprPath")
692                .node("body", "MaybeImplBody"),
693        )
694        // Empty struct, which is used for separating the first comments in a file or module from
695        // the rest of the items. This is needed to prevent the first comments from being
696        // moved by the formatter.
697        .add_struct(StructBuilder::new("ItemHeaderDoc").node("empty", "TerminalEmpty"))
698        .add_enum(
699            EnumBuilder::new("MaybeImplBody")
700                .node_with_explicit_kind("Some", "ImplBody")
701                .node_with_explicit_kind("None", "TerminalSemicolon"),
702        )
703        .add_struct(
704            StructBuilder::new("ImplBody")
705                .node("lbrace", "TerminalLBrace")
706                .node("items", "ImplItemList")
707                .node("rbrace", "TerminalRBrace"),
708        )
709        .add_list("ImplItemList", "ImplItem")
710        .add_enum(
711            EnumBuilder::new("ImplItem")
712                .include_missing()
713                .node_with_explicit_kind("Function", "FunctionWithBody")
714                .node_with_explicit_kind("Type", "ItemTypeAlias")
715                .node_with_explicit_kind("Constant", "ItemConstant")
716                .node_with_explicit_kind("Impl", "ItemImplAlias")
717                // These are not supported semantically.
718                .node_with_explicit_kind("Module", "ItemModule")
719                .node_with_explicit_kind("Use", "ItemUse")
720                .node_with_explicit_kind("ExternFunction", "ItemExternFunction")
721                .node_with_explicit_kind("ExternType", "ItemExternType")
722                .node_with_explicit_kind("Trait", "ItemTrait")
723                .node_with_explicit_kind("Struct", "ItemStruct")
724                .node_with_explicit_kind("Enum", "ItemEnum"),
725        )
726        .add_struct(
727            StructBuilder::new("ItemImplAlias")
728                .node("attributes", "AttributeList")
729                .node("visibility", "Visibility")
730                .node("impl_kw", "TerminalImpl")
731                .key_node("name", "TerminalIdentifier")
732                .node("generic_params", "OptionWrappedGenericParamList")
733                .node("eq", "TerminalEq")
734                .node("impl_path", "ExprPath")
735                .node("semicolon", "TerminalSemicolon"),
736        )
737        .add_struct(
738            StructBuilder::new("ItemStruct")
739                .node("attributes", "AttributeList")
740                .node("visibility", "Visibility")
741                .node("struct_kw", "TerminalStruct")
742                .key_node("name", "TerminalIdentifier")
743                .node("generic_params", "OptionWrappedGenericParamList")
744                .node("lbrace", "TerminalLBrace")
745                .node("members", "MemberList")
746                .node("rbrace", "TerminalRBrace"),
747        )
748        .add_struct(
749            StructBuilder::new("ItemEnum")
750                .node("attributes", "AttributeList")
751                .node("visibility", "Visibility")
752                .node("enum_kw", "TerminalEnum")
753                .key_node("name", "TerminalIdentifier")
754                .node("generic_params", "OptionWrappedGenericParamList")
755                .node("lbrace", "TerminalLBrace")
756                .node("variants", "VariantList")
757                .node("rbrace", "TerminalRBrace"),
758        )
759        .add_struct(
760            StructBuilder::new("ItemTypeAlias")
761                .node("attributes", "AttributeList")
762                .node("visibility", "Visibility")
763                .node("type_kw", "TerminalType")
764                .key_node("name", "TerminalIdentifier")
765                .node("generic_params", "OptionWrappedGenericParamList")
766                .node("eq", "TerminalEq")
767                .node("ty", "Expr")
768                .node("semicolon", "TerminalSemicolon"),
769        )
770        .add_struct(
771            StructBuilder::new("ItemUse")
772                .node("attributes", "AttributeList")
773                .node("visibility", "Visibility")
774                .node("use_kw", "TerminalUse")
775                .node("dollar", "OptionTerminalDollar")
776                .key_node("use_path", "UsePath")
777                .node("semicolon", "TerminalSemicolon"),
778        )
779        .add_enum(
780            EnumBuilder::new("UsePath").node("Leaf").node("Single").node("Multi").node("Star"),
781        )
782        .add_struct(
783            StructBuilder::new("UsePathLeaf")
784                .key_node("ident", "PathSegment")
785                .key_node("alias_clause", "OptionAliasClause"),
786        )
787        .add_struct(
788            StructBuilder::new("UsePathSingle")
789                .node("ident", "PathSegment")
790                .node("colon_colon", "TerminalColonColon")
791                .node("use_path", "UsePath"),
792        )
793        .add_struct(
794            StructBuilder::new("UsePathMulti")
795                .node("lbrace", "TerminalLBrace")
796                .node("use_paths", "UsePathList")
797                .node("rbrace", "TerminalRBrace"),
798        )
799        .add_struct(StructBuilder::new("UsePathStar").node("star", "TerminalMul"))
800        .add_separated_list("UsePathList", "UsePath", "TerminalComma")
801        .add_struct(
802            StructBuilder::new("AliasClause")
803                .node("as_kw", "TerminalAs")
804                .key_node("alias", "TerminalIdentifier"),
805        )
806        .add_option("AliasClause")
807        // --- Generics ---
808        .add_enum(EnumBuilder::new("GenericArg").node("Unnamed").node("Named"))
809        .add_struct(
810            StructBuilder::new("GenericArgNamed")
811                .node("name", "TerminalIdentifier")
812                .node("colon", "TerminalColon")
813                .node("value", "Expr"),
814        )
815        .add_struct(StructBuilder::new("GenericArgUnnamed").node("value", "Expr"))
816        .add_struct(
817            StructBuilder::new("GenericArgs")
818                .node("langle", "TerminalLT")
819                .node("generic_args", "GenericArgList")
820                .node("rangle", "TerminalGT"),
821        )
822        .add_separated_list("GenericArgList", "GenericArg", "TerminalComma")
823        .add_struct(
824            StructBuilder::new("AssociatedItemConstraint")
825                .node("item", "TerminalIdentifier")
826                .node("colon", "TerminalColon")
827                .node("value", "Expr"),
828        )
829        .add_struct(
830            StructBuilder::new("AssociatedItemConstraints")
831                .node("lbrack", "TerminalLBrack")
832                .node("associated_item_constraints", "AssociatedItemConstraintList")
833                .node("rbrack", "TerminalRBrack"),
834        )
835        .add_separated_list(
836            "AssociatedItemConstraintList",
837            "AssociatedItemConstraint",
838            "TerminalComma",
839        )
840        .add_option("AssociatedItemConstraints")
841        .add_option("WrappedGenericParamList")
842        .add_struct(
843            StructBuilder::new("WrappedGenericParamList")
844                .node("langle", "TerminalLT")
845                .node("generic_params", "GenericParamList")
846                .node("rangle", "TerminalGT"),
847        )
848        .add_separated_list("GenericParamList", "GenericParam", "TerminalComma")
849        // TODO(spapini): Remove this indirection.
850        .add_enum(
851            EnumBuilder::new("GenericParam")
852                .node("Type")
853                .node("Const")
854                .node("ImplNamed")
855                .node("ImplAnonymous")
856                .node("NegativeImpl"),
857        )
858        .add_struct(StructBuilder::new("GenericParamType").key_node("name", "TerminalIdentifier"))
859        .add_struct(
860            StructBuilder::new("GenericParamConst")
861                .node("const_kw", "TerminalConst")
862                .key_node("name", "TerminalIdentifier")
863                .node("colon", "TerminalColon")
864                .node("ty", "Expr"),
865        )
866        .add_struct(
867            StructBuilder::new("GenericParamImplNamed")
868                .node("impl_kw", "TerminalImpl")
869                .key_node("name", "TerminalIdentifier")
870                .node("colon", "TerminalColon")
871                .node("trait_path", "ExprPath")
872                .node("type_constrains", "OptionAssociatedItemConstraints"),
873        )
874        .add_struct(
875            StructBuilder::new("GenericParamImplAnonymous")
876                .node("plus", "TerminalPlus")
877                .node("trait_path", "ExprPath")
878                .node("type_constrains", "OptionAssociatedItemConstraints"),
879        )
880        .add_struct(
881            StructBuilder::new("GenericParamNegativeImpl")
882                .node("minus", "TerminalMinus")
883                .node("trait_path", "ExprPath"),
884        )
885        // --- Macros ---
886        // The structure of a token tree is:
887        // TokenTree: TokenNode | WrappedTokenTree
888        // Where WrappedTokenTree is:
889        // WrappedTokenTree: (TokenTree*) | {TokenTree*} | [TokenTree*]
890        // TokenTree* is represented as TokenList.
891        .add_list("TokenList", "TokenTree")
892        .add_struct(StructBuilder::new("TokenTreeLeaf").node("leaf", "TokenNode"))
893        .add_struct(StructBuilder::new("TokenTreeNode").node("subtree", "WrappedTokenTree"))
894        // TODO(Dean): Remove TokenTreeRepetition and TokenTreeParam (it's redundant).
895        .add_struct(
896            StructBuilder::new("TokenTreeRepetition")
897                .node("dollar", "TerminalDollar")
898                .node("lparen", "TerminalLParen")
899                .node("elements", "TokenList")
900                .node("rparen", "TerminalRParen")
901                .node("separator", "OptionTerminalComma")
902                .node("operator", "MacroRepetitionOperator"),
903        )
904        .add_struct(
905            StructBuilder::new("TokenTreeParam")
906                .node("dollar", "TerminalDollar")
907                .node("name", "TerminalIdentifier"),
908        )
909        .add_enum(
910            EnumBuilder::new("TokenTree")
911                .include_missing()
912                .node_with_explicit_kind("Token", "TokenTreeLeaf")
913                .node_with_explicit_kind("Subtree", "TokenTreeNode")
914                .node_with_explicit_kind("Repetition", "TokenTreeRepetition")
915                .node_with_explicit_kind("Param", "TokenTreeParam"),
916        )
917        .add_enum(
918            EnumBuilder::new("WrappedTokenTree")
919                .include_missing()
920                .node_with_explicit_kind("Parenthesized", "ParenthesizedTokenTree")
921                .node_with_explicit_kind("Braced", "BracedTokenTree")
922                .node_with_explicit_kind("Bracketed", "BracketedTokenTree"),
923        )
924        .add_struct(
925            StructBuilder::new("ParenthesizedTokenTree")
926                .node("lparen", "TerminalLParen")
927                .node("tokens", "TokenList")
928                .node("rparen", "TerminalRParen"),
929        )
930        .add_struct(
931            StructBuilder::new("BracedTokenTree")
932                .node("lbrace", "TerminalLBrace")
933                .node("tokens", "TokenList")
934                .node("rbrace", "TerminalRBrace"),
935        )
936        .add_struct(
937            StructBuilder::new("BracketedTokenTree")
938                .node("lbrack", "TerminalLBrack")
939                .node("tokens", "TokenList")
940                .node("rbrack", "TerminalRBrack"),
941        )
942        .add_struct(
943            StructBuilder::new("ExprInlineMacro")
944                .node("path", "ExprPath")
945                .node("bang", "TerminalNot")
946                .node("arguments", "TokenTreeNode"),
947        )
948        .add_struct(
949            StructBuilder::new("ItemInlineMacro")
950                .node("attributes", "AttributeList")
951                .node("path", "ExprPath")
952                .node("bang", "TerminalNot")
953                .node("arguments", "TokenTreeNode")
954                .node("semicolon", "TerminalSemicolon"),
955        )
956        .add_struct(
957            StructBuilder::new("ItemMacroDeclaration")
958                .node("attributes", "AttributeList")
959                .node("visibility", "Visibility")
960                .node("macro_kw", "TerminalMacro")
961                .key_node("name", "TerminalIdentifier")
962                .node("lbrace", "TerminalLBrace")
963                .node("rules", "MacroRulesList")
964                .node("rbrace", "TerminalRBrace"),
965        )
966        .add_list("MacroRulesList", "MacroRule")
967        .add_struct(
968            StructBuilder::new("MacroRule")
969                .node("lhs", "WrappedMacro")
970                .node("fat_arrow", "TerminalMatchArrow")
971                .node("rhs", "BracedMacro")
972                .node("semicolon", "TerminalSemicolon"),
973        )
974        .add_struct(
975            StructBuilder::new("ParamKind")
976                .node("colon", "TerminalColon")
977                .node("kind", "MacroParamKind"),
978        )
979        .add_option("ParamKind")
980        .add_struct(
981            StructBuilder::new("MacroParam")
982                .node("dollar", "TerminalDollar")
983                .node("name", "TerminalIdentifier")
984                .node("kind", "OptionParamKind"),
985        )
986        .add_struct(
987            StructBuilder::new("MacroRepetition")
988                .node("dollar", "TerminalDollar")
989                .node("lparen", "TerminalLParen")
990                .node("elements", "MacroElements")
991                .node("rparen", "TerminalRParen")
992                // TODO(Dean): Add support for more kinds of separators.
993                .node("separator", "OptionTerminalComma")
994                .node("operator", "MacroRepetitionOperator"),
995        )
996        .add_option("TerminalComma")
997        .add_enum(
998            EnumBuilder::new("MacroRepetitionOperator")
999                .node_with_explicit_kind("ZeroOrOne", "TerminalQuestionMark")
1000                .node_with_explicit_kind("OneOrMore", "TerminalPlus")
1001                .node_with_explicit_kind("ZeroOrMore", "TerminalMul")
1002                .include_missing(),
1003        )
1004        // TODO(Gil): Add support for more kinds of macro rule parameters.
1005        .add_struct(StructBuilder::new("ParamIdent").node("ident", "TerminalIdentifier"))
1006        .add_struct(StructBuilder::new("ParamExpr").node("expr", "TerminalIdentifier"))
1007        .add_enum(
1008            EnumBuilder::new("MacroParamKind")
1009                .node_with_explicit_kind("Identifier", "ParamIdent")
1010                .node_with_explicit_kind("Expr", "ParamExpr")
1011                .include_missing(),
1012        )
1013        .add_enum(
1014            EnumBuilder::new("MacroElement")
1015                .node_with_explicit_kind("Token", "TokenTreeLeaf")
1016                .node_with_explicit_kind("Param", "MacroParam")
1017                .node_with_explicit_kind("Subtree", "MacroWrapper")
1018                .node_with_explicit_kind("Repetition", "MacroRepetition"),
1019        )
1020        .add_list("MacroElements", "MacroElement")
1021        .add_struct(StructBuilder::new("MacroWrapper").node("subtree", "WrappedMacro"))
1022        .add_enum(
1023            EnumBuilder::new("WrappedMacro")
1024                .node_with_explicit_kind("Parenthesized", "ParenthesizedMacro")
1025                .node_with_explicit_kind("Braced", "BracedMacro")
1026                .node_with_explicit_kind("Bracketed", "BracketedMacro"),
1027        )
1028        .add_struct(
1029            StructBuilder::new("ParenthesizedMacro")
1030                .node("lparen", "TerminalLParen")
1031                .node("elements", "MacroElements")
1032                .node("rparen", "TerminalRParen"),
1033        )
1034        .add_struct(
1035            StructBuilder::new("BracedMacro")
1036                .node("lbrace", "TerminalLBrace")
1037                .node("elements", "MacroElements")
1038                .node("rbrace", "TerminalRBrace"),
1039        )
1040        .add_struct(
1041            StructBuilder::new("BracketedMacro")
1042                .node("lbrack", "TerminalLBrack")
1043                .node("elements", "MacroElements")
1044                .node("rbrack", "TerminalRBrack"),
1045        )
1046        .add_struct(
1047            StructBuilder::new("LegacyExprInlineMacro")
1048                .node("path", "ExprPath")
1049                .node("bang", "TerminalNot")
1050                .node("arguments", "WrappedArgList"),
1051        )
1052        .add_struct(
1053            StructBuilder::new("LegacyItemInlineMacro")
1054                .node("attributes", "AttributeList")
1055                .node("path", "ExprPath")
1056                .node("bang", "TerminalNot")
1057                .node("arguments", "WrappedArgList")
1058                .node("semicolon", "TerminalSemicolon"),
1059        )
1060        // --- Skipped nodes ---
1061        // A wrapper for the skipped node enum as the enum nodes (Trivium) can't have enum as a
1062        // child directly.
1063        .add_struct(StructBuilder::new("TriviumSkippedNode").node("node", "SkippedNode"))
1064        // An enum of all nodes that can be skipped while parsing, new nodes can be added here if
1065        // needed to be skipped.
1066        .add_enum(
1067            EnumBuilder::new("SkippedNode")
1068                .node_with_explicit_kind("AttributeList", "AttributeList")
1069                .node_with_explicit_kind("VisibilityPub", "VisibilityPub")
1070                .node_with_explicit_kind("ExprPath", "ExprPath"),
1071        )
1072        // --- Tokens + Terminals ---
1073        .add_token_and_terminal("Identifier")
1074        .add_token_and_terminal("LiteralNumber")
1075        .add_token_and_terminal("ShortString")
1076        .add_token_and_terminal("String")
1077        .add_keyword_token_and_terminal("As")
1078        .add_keyword_token_and_terminal("Const")
1079        .add_keyword_token_and_terminal("Else")
1080        .add_keyword_token_and_terminal("Enum")
1081        .add_keyword_token_and_terminal("Extern")
1082        .add_keyword_token_and_terminal("False")
1083        .add_keyword_token_and_terminal("Function")
1084        .add_keyword_token_and_terminal("If")
1085        .add_keyword_token_and_terminal("While")
1086        .add_keyword_token_and_terminal("For")
1087        .add_keyword_token_and_terminal("Loop")
1088        .add_keyword_token_and_terminal("Impl")
1089        .add_keyword_token_and_terminal("Implicits")
1090        .add_keyword_token_and_terminal("Let")
1091        .add_keyword_token_and_terminal("Macro")
1092        .add_keyword_token_and_terminal("Match")
1093        .add_keyword_token_and_terminal("Module")
1094        .add_keyword_token_and_terminal("Mut")
1095        .add_keyword_token_and_terminal("NoPanic")
1096        .add_keyword_token_and_terminal("Of")
1097        .add_keyword_token_and_terminal("Ref")
1098        .add_keyword_token_and_terminal("Continue")
1099        .add_keyword_token_and_terminal("Return")
1100        .add_keyword_token_and_terminal("Break")
1101        .add_keyword_token_and_terminal("Struct")
1102        .add_keyword_token_and_terminal("Trait")
1103        .add_keyword_token_and_terminal("True")
1104        .add_keyword_token_and_terminal("Type")
1105        .add_keyword_token_and_terminal("Use")
1106        .add_keyword_token_and_terminal("Pub")
1107        .add_token_and_terminal("And")
1108        .add_token_and_terminal("AndAnd")
1109        .add_token_and_terminal("Arrow")
1110        .add_token_and_terminal("At")
1111        .add_token_and_terminal("BadCharacters")
1112        .add_token_and_terminal("Colon")
1113        .add_token_and_terminal("ColonColon")
1114        .add_token_and_terminal("Comma")
1115        .add_token_and_terminal("Div")
1116        .add_token_and_terminal("DivEq")
1117        .add_token_and_terminal("Dollar")
1118        .add_token_and_terminal("Dot")
1119        .add_token_and_terminal("DotDot")
1120        .add_token_and_terminal("DotDotEq")
1121        .add_token_and_terminal("EndOfFile")
1122        .add_token_and_terminal("Eq")
1123        .add_token_and_terminal("EqEq")
1124        .add_token_and_terminal("GE")
1125        .add_token_and_terminal("GT")
1126        .add_token_and_terminal("Hash")
1127        .add_token_and_terminal("LBrace")
1128        .add_token_and_terminal("LBrack")
1129        .add_token_and_terminal("LE")
1130        .add_token_and_terminal("LParen")
1131        .add_token_and_terminal("LT")
1132        .add_token_and_terminal("MatchArrow")
1133        .add_token_and_terminal("Minus")
1134        .add_token_and_terminal("MinusEq")
1135        .add_token_and_terminal("Mod")
1136        .add_token_and_terminal("ModEq")
1137        .add_token_and_terminal("Mul")
1138        .add_token_and_terminal("MulEq")
1139        .add_token_and_terminal("Neq")
1140        .add_token_and_terminal("Not")
1141        .add_token_and_terminal("BitNot")
1142        .add_token_and_terminal("Or")
1143        .add_token_and_terminal("OrOr")
1144        .add_token_and_terminal("Plus")
1145        .add_token_and_terminal("PlusEq")
1146        .add_token_and_terminal("QuestionMark")
1147        .add_token_and_terminal("RBrace")
1148        .add_token_and_terminal("RBrack")
1149        .add_token_and_terminal("RParen")
1150        .add_token_and_terminal("Semicolon")
1151        .add_token_and_terminal("Underscore")
1152        .add_token_and_terminal("Xor")
1153        // --- Meta ---
1154        .add_struct(
1155            StructBuilder::new("SyntaxFile")
1156                .node("items", "ModuleItemList")
1157                .node("eof", "TerminalEndOfFile"),
1158        )
1159        .add_token_and_terminal("Empty")
1160        .add_token("SingleLineComment")
1161        .add_token("SingleLineInnerComment")
1162        .add_token("SingleLineDocComment")
1163        .add_token("Whitespace")
1164        .add_token("Newline")
1165        .add_token("Missing")
1166        .add_token("Skipped")
1167        .add_all_tokens_enum("TokenNode")
1168        .get()
1169}