1 module graphql.parser;
2 
3 import std.typecons : RefCounted, refCounted;
4 import std.format : format;
5 import graphql.ast;
6 import graphql.tokenmodule;
7 
8 import graphql.lexer;
9 
10 import graphql.exception;
11 
12 @safe:
13 
14 struct Parser {
15 	import std.array : appender;
16 
17 	import std.format : formattedWrite;
18 
19 	Lexer lex;
20 
21 	this(Lexer lex) {
22 		this.lex = lex;
23 	}
24 
25 	bool firstDocument() const pure @nogc @safe {
26 		return this.firstDefinitions();
27 	}
28 
29 	Document parseDocument() {
30 		try {
31 			return this.parseDocumentImpl();
32 		} catch(ParseException e) {
33 			throw new ParseException(
34 				"While parsing a Document an Exception was thrown.",
35 				e, __FILE__, __LINE__
36 			);
37 		}
38 	}
39 
40 	Document parseDocumentImpl() {
41 		string[] subRules;
42 		subRules = ["Defi"];
43 		if(this.firstDefinitions()) {
44 			Definitions defs = this.parseDefinitions();
45 
46 			return new Document(DocumentEnum.Defi
47 				, defs
48 			);
49 		}
50 		auto app = appender!string();
51 		formattedWrite(app, 
52 			"Found a '%s' while looking for", 
53 			this.lex.front
54 		);
55 		throw new ParseException(app.data,
56 			__FILE__, __LINE__,
57 			subRules,
58 			["directive -> Definition","enum_ -> Definition","extend -> Definition","fragment -> Definition","input -> Definition","interface_ -> Definition","lcurly -> Definition","mutation -> Definition","query -> Definition","scalar -> Definition","schema -> Definition","subscription -> Definition","type -> Definition","union_ -> Definition"]
59 		);
60 
61 	}
62 
63 	bool firstDefinitions() const pure @nogc @safe {
64 		return this.firstDefinition();
65 	}
66 
67 	Definitions parseDefinitions() {
68 		try {
69 			return this.parseDefinitionsImpl();
70 		} catch(ParseException e) {
71 			throw new ParseException(
72 				"While parsing a Definitions an Exception was thrown.",
73 				e, __FILE__, __LINE__
74 			);
75 		}
76 	}
77 
78 	Definitions parseDefinitionsImpl() {
79 		string[] subRules;
80 		subRules = ["Def", "Defs"];
81 		if(this.firstDefinition()) {
82 			Definition def = this.parseDefinition();
83 			subRules = ["Defs"];
84 			if(this.firstDefinitions()) {
85 				Definitions follow = this.parseDefinitions();
86 
87 				return new Definitions(DefinitionsEnum.Defs
88 					, def
89 					, follow
90 				);
91 			}
92 			return new Definitions(DefinitionsEnum.Def
93 				, def
94 			);
95 		}
96 		auto app = appender!string();
97 		formattedWrite(app, 
98 			"Found a '%s' while looking for", 
99 			this.lex.front
100 		);
101 		throw new ParseException(app.data,
102 			__FILE__, __LINE__,
103 			subRules,
104 			["directive -> TypeSystemDefinition","enum_ -> TypeSystemDefinition","extend -> TypeSystemDefinition","fragment -> FragmentDefinition","input -> TypeSystemDefinition","interface_ -> TypeSystemDefinition","lcurly -> OperationDefinition","mutation -> OperationDefinition","query -> OperationDefinition","scalar -> TypeSystemDefinition","schema -> TypeSystemDefinition","subscription -> OperationDefinition","type -> TypeSystemDefinition","union_ -> TypeSystemDefinition"]
105 		);
106 
107 	}
108 
109 	bool firstDefinition() const pure @nogc @safe {
110 		return this.firstOperationDefinition()
111 			 || this.firstFragmentDefinition()
112 			 || this.firstTypeSystemDefinition();
113 	}
114 
115 	Definition parseDefinition() {
116 		try {
117 			return this.parseDefinitionImpl();
118 		} catch(ParseException e) {
119 			throw new ParseException(
120 				"While parsing a Definition an Exception was thrown.",
121 				e, __FILE__, __LINE__
122 			);
123 		}
124 	}
125 
126 	Definition parseDefinitionImpl() {
127 		string[] subRules;
128 		subRules = ["O"];
129 		if(this.firstOperationDefinition()) {
130 			OperationDefinition op = this.parseOperationDefinition();
131 
132 			return new Definition(DefinitionEnum.O
133 				, op
134 			);
135 		} else if(this.firstFragmentDefinition()) {
136 			FragmentDefinition frag = this.parseFragmentDefinition();
137 
138 			return new Definition(DefinitionEnum.F
139 				, frag
140 			);
141 		} else if(this.firstTypeSystemDefinition()) {
142 			TypeSystemDefinition type = this.parseTypeSystemDefinition();
143 
144 			return new Definition(DefinitionEnum.T
145 				, type
146 			);
147 		}
148 		auto app = appender!string();
149 		formattedWrite(app, 
150 			"Found a '%s' while looking for", 
151 			this.lex.front
152 		);
153 		throw new ParseException(app.data,
154 			__FILE__, __LINE__,
155 			subRules,
156 			["lcurly -> SelectionSet","mutation -> OperationType","query -> OperationType","subscription -> OperationType","fragment","directive -> DirectiveDefinition","enum_ -> TypeDefinition","extend -> TypeExtensionDefinition","input -> TypeDefinition","interface_ -> TypeDefinition","scalar -> TypeDefinition","schema -> SchemaDefinition","type -> TypeDefinition","union_ -> TypeDefinition"]
157 		);
158 
159 	}
160 
161 	bool firstOperationDefinition() const pure @nogc @safe {
162 		return this.firstSelectionSet()
163 			 || this.firstOperationType();
164 	}
165 
166 	OperationDefinition parseOperationDefinition() {
167 		try {
168 			return this.parseOperationDefinitionImpl();
169 		} catch(ParseException e) {
170 			throw new ParseException(
171 				"While parsing a OperationDefinition an Exception was thrown.",
172 				e, __FILE__, __LINE__
173 			);
174 		}
175 	}
176 
177 	OperationDefinition parseOperationDefinitionImpl() {
178 		string[] subRules;
179 		subRules = ["SelSet"];
180 		if(this.firstSelectionSet()) {
181 			SelectionSet ss = this.parseSelectionSet();
182 
183 			return new OperationDefinition(OperationDefinitionEnum.SelSet
184 				, ss
185 			);
186 		} else if(this.firstOperationType()) {
187 			OperationType ot = this.parseOperationType();
188 			subRules = ["OT_N", "OT_N_D", "OT_N_V", "OT_N_VD"];
189 			if(this.lex.front.type == TokenType.name) {
190 				Token name = this.lex.front;
191 				this.lex.popFront();
192 				subRules = ["OT_N_V", "OT_N_VD"];
193 				if(this.firstVariableDefinitions()) {
194 					VariableDefinitions vd = this.parseVariableDefinitions();
195 					subRules = ["OT_N_VD"];
196 					if(this.firstDirectives()) {
197 						Directives d = this.parseDirectives();
198 						subRules = ["OT_N_VD"];
199 						if(this.firstSelectionSet()) {
200 							SelectionSet ss = this.parseSelectionSet();
201 
202 							return new OperationDefinition(OperationDefinitionEnum.OT_N_VD
203 								, ot
204 								, name
205 								, vd
206 								, d
207 								, ss
208 							);
209 						}
210 						auto app = appender!string();
211 						formattedWrite(app, 
212 							"Found a '%s' while looking for", 
213 							this.lex.front
214 						);
215 						throw new ParseException(app.data,
216 							__FILE__, __LINE__,
217 							subRules,
218 							["lcurly"]
219 						);
220 
221 					} else if(this.firstSelectionSet()) {
222 						SelectionSet ss = this.parseSelectionSet();
223 
224 						return new OperationDefinition(OperationDefinitionEnum.OT_N_V
225 							, ot
226 							, name
227 							, vd
228 							, ss
229 						);
230 					}
231 					auto app = appender!string();
232 					formattedWrite(app, 
233 						"Found a '%s' while looking for", 
234 						this.lex.front
235 					);
236 					throw new ParseException(app.data,
237 						__FILE__, __LINE__,
238 						subRules,
239 						["at -> Directive","lcurly"]
240 					);
241 
242 				} else if(this.firstDirectives()) {
243 					Directives d = this.parseDirectives();
244 					subRules = ["OT_N_D"];
245 					if(this.firstSelectionSet()) {
246 						SelectionSet ss = this.parseSelectionSet();
247 
248 						return new OperationDefinition(OperationDefinitionEnum.OT_N_D
249 							, ot
250 							, name
251 							, d
252 							, ss
253 						);
254 					}
255 					auto app = appender!string();
256 					formattedWrite(app, 
257 						"Found a '%s' while looking for", 
258 						this.lex.front
259 					);
260 					throw new ParseException(app.data,
261 						__FILE__, __LINE__,
262 						subRules,
263 						["lcurly"]
264 					);
265 
266 				} else if(this.firstSelectionSet()) {
267 					SelectionSet ss = this.parseSelectionSet();
268 
269 					return new OperationDefinition(OperationDefinitionEnum.OT_N
270 						, ot
271 						, name
272 						, ss
273 					);
274 				}
275 				auto app = appender!string();
276 				formattedWrite(app, 
277 					"Found a '%s' while looking for", 
278 					this.lex.front
279 				);
280 				throw new ParseException(app.data,
281 					__FILE__, __LINE__,
282 					subRules,
283 					["lparen","at -> Directive","lcurly"]
284 				);
285 
286 			} else if(this.firstVariableDefinitions()) {
287 				VariableDefinitions vd = this.parseVariableDefinitions();
288 				subRules = ["OT_VD"];
289 				if(this.firstDirectives()) {
290 					Directives d = this.parseDirectives();
291 					subRules = ["OT_VD"];
292 					if(this.firstSelectionSet()) {
293 						SelectionSet ss = this.parseSelectionSet();
294 
295 						return new OperationDefinition(OperationDefinitionEnum.OT_VD
296 							, ot
297 							, vd
298 							, d
299 							, ss
300 						);
301 					}
302 					auto app = appender!string();
303 					formattedWrite(app, 
304 						"Found a '%s' while looking for", 
305 						this.lex.front
306 					);
307 					throw new ParseException(app.data,
308 						__FILE__, __LINE__,
309 						subRules,
310 						["lcurly"]
311 					);
312 
313 				} else if(this.firstSelectionSet()) {
314 					SelectionSet ss = this.parseSelectionSet();
315 
316 					return new OperationDefinition(OperationDefinitionEnum.OT_V
317 						, ot
318 						, vd
319 						, ss
320 					);
321 				}
322 				auto app = appender!string();
323 				formattedWrite(app, 
324 					"Found a '%s' while looking for", 
325 					this.lex.front
326 				);
327 				throw new ParseException(app.data,
328 					__FILE__, __LINE__,
329 					subRules,
330 					["at -> Directive","lcurly"]
331 				);
332 
333 			} else if(this.firstDirectives()) {
334 				Directives d = this.parseDirectives();
335 				subRules = ["OT_D"];
336 				if(this.firstSelectionSet()) {
337 					SelectionSet ss = this.parseSelectionSet();
338 
339 					return new OperationDefinition(OperationDefinitionEnum.OT_D
340 						, ot
341 						, d
342 						, ss
343 					);
344 				}
345 				auto app = appender!string();
346 				formattedWrite(app, 
347 					"Found a '%s' while looking for", 
348 					this.lex.front
349 				);
350 				throw new ParseException(app.data,
351 					__FILE__, __LINE__,
352 					subRules,
353 					["lcurly"]
354 				);
355 
356 			} else if(this.firstSelectionSet()) {
357 				SelectionSet ss = this.parseSelectionSet();
358 
359 				return new OperationDefinition(OperationDefinitionEnum.OT
360 					, ot
361 					, ss
362 				);
363 			}
364 			auto app = appender!string();
365 			formattedWrite(app, 
366 				"Found a '%s' while looking for", 
367 				this.lex.front
368 			);
369 			throw new ParseException(app.data,
370 				__FILE__, __LINE__,
371 				subRules,
372 				["name","lparen","at -> Directive","lcurly"]
373 			);
374 
375 		}
376 		auto app = appender!string();
377 		formattedWrite(app, 
378 			"Found a '%s' while looking for", 
379 			this.lex.front
380 		);
381 		throw new ParseException(app.data,
382 			__FILE__, __LINE__,
383 			subRules,
384 			["lcurly","mutation","query","subscription"]
385 		);
386 
387 	}
388 
389 	bool firstSelectionSet() const pure @nogc @safe {
390 		return this.lex.front.type == TokenType.lcurly;
391 	}
392 
393 	SelectionSet parseSelectionSet() {
394 		try {
395 			return this.parseSelectionSetImpl();
396 		} catch(ParseException e) {
397 			throw new ParseException(
398 				"While parsing a SelectionSet an Exception was thrown.",
399 				e, __FILE__, __LINE__
400 			);
401 		}
402 	}
403 
404 	SelectionSet parseSelectionSetImpl() {
405 		string[] subRules;
406 		subRules = ["SS"];
407 		if(this.lex.front.type == TokenType.lcurly) {
408 			this.lex.popFront();
409 			subRules = ["SS"];
410 			if(this.firstSelections()) {
411 				Selections sel = this.parseSelections();
412 				subRules = ["SS"];
413 				if(this.lex.front.type == TokenType.rcurly) {
414 					this.lex.popFront();
415 
416 					return new SelectionSet(SelectionSetEnum.SS
417 						, sel
418 					);
419 				}
420 				auto app = appender!string();
421 				formattedWrite(app, 
422 					"Found a '%s' while looking for", 
423 					this.lex.front
424 				);
425 				throw new ParseException(app.data,
426 					__FILE__, __LINE__,
427 					subRules,
428 					["rcurly"]
429 				);
430 
431 			}
432 			auto app = appender!string();
433 			formattedWrite(app, 
434 				"Found a '%s' while looking for", 
435 				this.lex.front
436 			);
437 			throw new ParseException(app.data,
438 				__FILE__, __LINE__,
439 				subRules,
440 				["dots -> Selection","name -> Selection"]
441 			);
442 
443 		}
444 		auto app = appender!string();
445 		formattedWrite(app, 
446 			"Found a '%s' while looking for", 
447 			this.lex.front
448 		);
449 		throw new ParseException(app.data,
450 			__FILE__, __LINE__,
451 			subRules,
452 			["lcurly"]
453 		);
454 
455 	}
456 
457 	bool firstOperationType() const pure @nogc @safe {
458 		return this.lex.front.type == TokenType.query
459 			 || this.lex.front.type == TokenType.mutation
460 			 || this.lex.front.type == TokenType.subscription;
461 	}
462 
463 	OperationType parseOperationType() {
464 		try {
465 			return this.parseOperationTypeImpl();
466 		} catch(ParseException e) {
467 			throw new ParseException(
468 				"While parsing a OperationType an Exception was thrown.",
469 				e, __FILE__, __LINE__
470 			);
471 		}
472 	}
473 
474 	OperationType parseOperationTypeImpl() {
475 		string[] subRules;
476 		subRules = ["Query"];
477 		if(this.lex.front.type == TokenType.query) {
478 			Token tok = this.lex.front;
479 			this.lex.popFront();
480 
481 			return new OperationType(OperationTypeEnum.Query
482 				, tok
483 			);
484 		} else if(this.lex.front.type == TokenType.mutation) {
485 			Token tok = this.lex.front;
486 			this.lex.popFront();
487 
488 			return new OperationType(OperationTypeEnum.Mutation
489 				, tok
490 			);
491 		} else if(this.lex.front.type == TokenType.subscription) {
492 			Token tok = this.lex.front;
493 			this.lex.popFront();
494 
495 			return new OperationType(OperationTypeEnum.Sub
496 				, tok
497 			);
498 		}
499 		auto app = appender!string();
500 		formattedWrite(app, 
501 			"Found a '%s' while looking for", 
502 			this.lex.front
503 		);
504 		throw new ParseException(app.data,
505 			__FILE__, __LINE__,
506 			subRules,
507 			["query","mutation","subscription"]
508 		);
509 
510 	}
511 
512 	bool firstSelections() const pure @nogc @safe {
513 		return this.firstSelection();
514 	}
515 
516 	Selections parseSelections() {
517 		try {
518 			return this.parseSelectionsImpl();
519 		} catch(ParseException e) {
520 			throw new ParseException(
521 				"While parsing a Selections an Exception was thrown.",
522 				e, __FILE__, __LINE__
523 			);
524 		}
525 	}
526 
527 	Selections parseSelectionsImpl() {
528 		string[] subRules;
529 		subRules = ["Sel", "Sels", "Selsc"];
530 		if(this.firstSelection()) {
531 			Selection sel = this.parseSelection();
532 			subRules = ["Sels"];
533 			if(this.firstSelections()) {
534 				Selections follow = this.parseSelections();
535 
536 				return new Selections(SelectionsEnum.Sels
537 					, sel
538 					, follow
539 				);
540 			} else if(this.lex.front.type == TokenType.comma) {
541 				this.lex.popFront();
542 				subRules = ["Selsc"];
543 				if(this.firstSelections()) {
544 					Selections follow = this.parseSelections();
545 
546 					return new Selections(SelectionsEnum.Selsc
547 						, sel
548 						, follow
549 					);
550 				}
551 				auto app = appender!string();
552 				formattedWrite(app, 
553 					"Found a '%s' while looking for", 
554 					this.lex.front
555 				);
556 				throw new ParseException(app.data,
557 					__FILE__, __LINE__,
558 					subRules,
559 					["dots -> Selection","name -> Selection"]
560 				);
561 
562 			}
563 			return new Selections(SelectionsEnum.Sel
564 				, sel
565 			);
566 		}
567 		auto app = appender!string();
568 		formattedWrite(app, 
569 			"Found a '%s' while looking for", 
570 			this.lex.front
571 		);
572 		throw new ParseException(app.data,
573 			__FILE__, __LINE__,
574 			subRules,
575 			["dots","name -> Field"]
576 		);
577 
578 	}
579 
580 	bool firstSelection() const pure @nogc @safe {
581 		return this.firstField()
582 			 || this.lex.front.type == TokenType.dots;
583 	}
584 
585 	Selection parseSelection() {
586 		try {
587 			return this.parseSelectionImpl();
588 		} catch(ParseException e) {
589 			throw new ParseException(
590 				"While parsing a Selection an Exception was thrown.",
591 				e, __FILE__, __LINE__
592 			);
593 		}
594 	}
595 
596 	Selection parseSelectionImpl() {
597 		string[] subRules;
598 		subRules = ["Field"];
599 		if(this.firstField()) {
600 			Field field = this.parseField();
601 
602 			return new Selection(SelectionEnum.Field
603 				, field
604 			);
605 		} else if(this.lex.front.type == TokenType.dots) {
606 			this.lex.popFront();
607 			subRules = ["Spread"];
608 			if(this.firstFragmentSpread()) {
609 				FragmentSpread frag = this.parseFragmentSpread();
610 
611 				return new Selection(SelectionEnum.Spread
612 					, frag
613 				);
614 			} else if(this.firstInlineFragment()) {
615 				InlineFragment ifrag = this.parseInlineFragment();
616 
617 				return new Selection(SelectionEnum.IFrag
618 					, ifrag
619 				);
620 			}
621 			auto app = appender!string();
622 			formattedWrite(app, 
623 				"Found a '%s' while looking for", 
624 				this.lex.front
625 			);
626 			throw new ParseException(app.data,
627 				__FILE__, __LINE__,
628 				subRules,
629 				["name","at -> Directives","lcurly -> SelectionSet","on_"]
630 			);
631 
632 		}
633 		auto app = appender!string();
634 		formattedWrite(app, 
635 			"Found a '%s' while looking for", 
636 			this.lex.front
637 		);
638 		throw new ParseException(app.data,
639 			__FILE__, __LINE__,
640 			subRules,
641 			["name -> FieldName","dots"]
642 		);
643 
644 	}
645 
646 	bool firstFragmentSpread() const pure @nogc @safe {
647 		return this.lex.front.type == TokenType.name;
648 	}
649 
650 	FragmentSpread parseFragmentSpread() {
651 		try {
652 			return this.parseFragmentSpreadImpl();
653 		} catch(ParseException e) {
654 			throw new ParseException(
655 				"While parsing a FragmentSpread an Exception was thrown.",
656 				e, __FILE__, __LINE__
657 			);
658 		}
659 	}
660 
661 	FragmentSpread parseFragmentSpreadImpl() {
662 		string[] subRules;
663 		subRules = ["F", "FD"];
664 		if(this.lex.front.type == TokenType.name) {
665 			Token name = this.lex.front;
666 			this.lex.popFront();
667 			subRules = ["FD"];
668 			if(this.firstDirectives()) {
669 				Directives dirs = this.parseDirectives();
670 
671 				return new FragmentSpread(FragmentSpreadEnum.FD
672 					, name
673 					, dirs
674 				);
675 			}
676 			return new FragmentSpread(FragmentSpreadEnum.F
677 				, name
678 			);
679 		}
680 		auto app = appender!string();
681 		formattedWrite(app, 
682 			"Found a '%s' while looking for", 
683 			this.lex.front
684 		);
685 		throw new ParseException(app.data,
686 			__FILE__, __LINE__,
687 			subRules,
688 			["name"]
689 		);
690 
691 	}
692 
693 	bool firstInlineFragment() const pure @nogc @safe {
694 		return this.lex.front.type == TokenType.on_
695 			 || this.firstDirectives()
696 			 || this.firstSelectionSet();
697 	}
698 
699 	InlineFragment parseInlineFragment() {
700 		try {
701 			return this.parseInlineFragmentImpl();
702 		} catch(ParseException e) {
703 			throw new ParseException(
704 				"While parsing a InlineFragment an Exception was thrown.",
705 				e, __FILE__, __LINE__
706 			);
707 		}
708 	}
709 
710 	InlineFragment parseInlineFragmentImpl() {
711 		string[] subRules;
712 		subRules = ["TDS", "TS"];
713 		if(this.lex.front.type == TokenType.on_) {
714 			this.lex.popFront();
715 			subRules = ["TDS", "TS"];
716 			if(this.lex.front.type == TokenType.name) {
717 				Token tc = this.lex.front;
718 				this.lex.popFront();
719 				subRules = ["TDS"];
720 				if(this.firstDirectives()) {
721 					Directives dirs = this.parseDirectives();
722 					subRules = ["TDS"];
723 					if(this.firstSelectionSet()) {
724 						SelectionSet ss = this.parseSelectionSet();
725 
726 						return new InlineFragment(InlineFragmentEnum.TDS
727 							, tc
728 							, dirs
729 							, ss
730 						);
731 					}
732 					auto app = appender!string();
733 					formattedWrite(app, 
734 						"Found a '%s' while looking for", 
735 						this.lex.front
736 					);
737 					throw new ParseException(app.data,
738 						__FILE__, __LINE__,
739 						subRules,
740 						["lcurly"]
741 					);
742 
743 				} else if(this.firstSelectionSet()) {
744 					SelectionSet ss = this.parseSelectionSet();
745 
746 					return new InlineFragment(InlineFragmentEnum.TS
747 						, tc
748 						, ss
749 					);
750 				}
751 				auto app = appender!string();
752 				formattedWrite(app, 
753 					"Found a '%s' while looking for", 
754 					this.lex.front
755 				);
756 				throw new ParseException(app.data,
757 					__FILE__, __LINE__,
758 					subRules,
759 					["at -> Directive","lcurly"]
760 				);
761 
762 			}
763 			auto app = appender!string();
764 			formattedWrite(app, 
765 				"Found a '%s' while looking for", 
766 				this.lex.front
767 			);
768 			throw new ParseException(app.data,
769 				__FILE__, __LINE__,
770 				subRules,
771 				["name"]
772 			);
773 
774 		} else if(this.firstDirectives()) {
775 			Directives dirs = this.parseDirectives();
776 			subRules = ["DS"];
777 			if(this.firstSelectionSet()) {
778 				SelectionSet ss = this.parseSelectionSet();
779 
780 				return new InlineFragment(InlineFragmentEnum.DS
781 					, dirs
782 					, ss
783 				);
784 			}
785 			auto app = appender!string();
786 			formattedWrite(app, 
787 				"Found a '%s' while looking for", 
788 				this.lex.front
789 			);
790 			throw new ParseException(app.data,
791 				__FILE__, __LINE__,
792 				subRules,
793 				["lcurly"]
794 			);
795 
796 		} else if(this.firstSelectionSet()) {
797 			SelectionSet ss = this.parseSelectionSet();
798 
799 			return new InlineFragment(InlineFragmentEnum.S
800 				, ss
801 			);
802 		}
803 		auto app = appender!string();
804 		formattedWrite(app, 
805 			"Found a '%s' while looking for", 
806 			this.lex.front
807 		);
808 		throw new ParseException(app.data,
809 			__FILE__, __LINE__,
810 			subRules,
811 			["on_","at -> Directive","lcurly"]
812 		);
813 
814 	}
815 
816 	bool firstField() const pure @nogc @safe {
817 		return this.firstFieldName();
818 	}
819 
820 	Field parseField() {
821 		try {
822 			return this.parseFieldImpl();
823 		} catch(ParseException e) {
824 			throw new ParseException(
825 				"While parsing a Field an Exception was thrown.",
826 				e, __FILE__, __LINE__
827 			);
828 		}
829 	}
830 
831 	Field parseFieldImpl() {
832 		string[] subRules;
833 		subRules = ["F", "FA", "FAD", "FADS", "FAS", "FD", "FDS", "FS"];
834 		if(this.firstFieldName()) {
835 			FieldName name = this.parseFieldName();
836 			subRules = ["FA", "FAD", "FADS", "FAS"];
837 			if(this.firstArguments()) {
838 				Arguments args = this.parseArguments();
839 				subRules = ["FAD", "FADS"];
840 				if(this.firstDirectives()) {
841 					Directives dirs = this.parseDirectives();
842 					subRules = ["FADS"];
843 					if(this.firstSelectionSet()) {
844 						SelectionSet ss = this.parseSelectionSet();
845 
846 						return new Field(FieldEnum.FADS
847 							, name
848 							, args
849 							, dirs
850 							, ss
851 						);
852 					}
853 					return new Field(FieldEnum.FAD
854 						, name
855 						, args
856 						, dirs
857 					);
858 				} else if(this.firstSelectionSet()) {
859 					SelectionSet ss = this.parseSelectionSet();
860 
861 					return new Field(FieldEnum.FAS
862 						, name
863 						, args
864 						, ss
865 					);
866 				}
867 				return new Field(FieldEnum.FA
868 					, name
869 					, args
870 				);
871 			} else if(this.firstDirectives()) {
872 				Directives dirs = this.parseDirectives();
873 				subRules = ["FDS"];
874 				if(this.firstSelectionSet()) {
875 					SelectionSet ss = this.parseSelectionSet();
876 
877 					return new Field(FieldEnum.FDS
878 						, name
879 						, dirs
880 						, ss
881 					);
882 				}
883 				return new Field(FieldEnum.FD
884 					, name
885 					, dirs
886 				);
887 			} else if(this.firstSelectionSet()) {
888 				SelectionSet ss = this.parseSelectionSet();
889 
890 				return new Field(FieldEnum.FS
891 					, name
892 					, ss
893 				);
894 			}
895 			return new Field(FieldEnum.F
896 				, name
897 			);
898 		}
899 		auto app = appender!string();
900 		formattedWrite(app, 
901 			"Found a '%s' while looking for", 
902 			this.lex.front
903 		);
904 		throw new ParseException(app.data,
905 			__FILE__, __LINE__,
906 			subRules,
907 			["name"]
908 		);
909 
910 	}
911 
912 	bool firstFieldName() const pure @nogc @safe {
913 		return this.lex.front.type == TokenType.name;
914 	}
915 
916 	FieldName parseFieldName() {
917 		try {
918 			return this.parseFieldNameImpl();
919 		} catch(ParseException e) {
920 			throw new ParseException(
921 				"While parsing a FieldName an Exception was thrown.",
922 				e, __FILE__, __LINE__
923 			);
924 		}
925 	}
926 
927 	FieldName parseFieldNameImpl() {
928 		string[] subRules;
929 		subRules = ["A", "N"];
930 		if(this.lex.front.type == TokenType.name) {
931 			Token name = this.lex.front;
932 			this.lex.popFront();
933 			subRules = ["A"];
934 			if(this.lex.front.type == TokenType.colon) {
935 				this.lex.popFront();
936 				subRules = ["A"];
937 				if(this.lex.front.type == TokenType.name) {
938 					Token aka = this.lex.front;
939 					this.lex.popFront();
940 
941 					return new FieldName(FieldNameEnum.A
942 						, name
943 						, aka
944 					);
945 				}
946 				auto app = appender!string();
947 				formattedWrite(app, 
948 					"Found a '%s' while looking for", 
949 					this.lex.front
950 				);
951 				throw new ParseException(app.data,
952 					__FILE__, __LINE__,
953 					subRules,
954 					["name"]
955 				);
956 
957 			}
958 			return new FieldName(FieldNameEnum.N
959 				, name
960 			);
961 		}
962 		auto app = appender!string();
963 		formattedWrite(app, 
964 			"Found a '%s' while looking for", 
965 			this.lex.front
966 		);
967 		throw new ParseException(app.data,
968 			__FILE__, __LINE__,
969 			subRules,
970 			["name"]
971 		);
972 
973 	}
974 
975 	bool firstArguments() const pure @nogc @safe {
976 		return this.lex.front.type == TokenType.lparen;
977 	}
978 
979 	Arguments parseArguments() {
980 		try {
981 			return this.parseArgumentsImpl();
982 		} catch(ParseException e) {
983 			throw new ParseException(
984 				"While parsing a Arguments an Exception was thrown.",
985 				e, __FILE__, __LINE__
986 			);
987 		}
988 	}
989 
990 	Arguments parseArgumentsImpl() {
991 		string[] subRules;
992 		subRules = ["Empty", "List"];
993 		if(this.lex.front.type == TokenType.lparen) {
994 			this.lex.popFront();
995 			subRules = ["List"];
996 			if(this.firstArgumentList()) {
997 				ArgumentList arg = this.parseArgumentList();
998 				subRules = ["List"];
999 				if(this.lex.front.type == TokenType.rparen) {
1000 					this.lex.popFront();
1001 
1002 					return new Arguments(ArgumentsEnum.List
1003 						, arg
1004 					);
1005 				}
1006 				auto app = appender!string();
1007 				formattedWrite(app, 
1008 					"Found a '%s' while looking for", 
1009 					this.lex.front
1010 				);
1011 				throw new ParseException(app.data,
1012 					__FILE__, __LINE__,
1013 					subRules,
1014 					["rparen"]
1015 				);
1016 
1017 			} else if(this.lex.front.type == TokenType.rparen) {
1018 				this.lex.popFront();
1019 
1020 				return new Arguments(ArgumentsEnum.Empty
1021 				);
1022 			}
1023 			auto app = appender!string();
1024 			formattedWrite(app, 
1025 				"Found a '%s' while looking for", 
1026 				this.lex.front
1027 			);
1028 			throw new ParseException(app.data,
1029 				__FILE__, __LINE__,
1030 				subRules,
1031 				["name -> Argument","rparen"]
1032 			);
1033 
1034 		}
1035 		auto app = appender!string();
1036 		formattedWrite(app, 
1037 			"Found a '%s' while looking for", 
1038 			this.lex.front
1039 		);
1040 		throw new ParseException(app.data,
1041 			__FILE__, __LINE__,
1042 			subRules,
1043 			["lparen"]
1044 		);
1045 
1046 	}
1047 
1048 	bool firstArgumentList() const pure @nogc @safe {
1049 		return this.firstArgument();
1050 	}
1051 
1052 	ArgumentList parseArgumentList() {
1053 		try {
1054 			return this.parseArgumentListImpl();
1055 		} catch(ParseException e) {
1056 			throw new ParseException(
1057 				"While parsing a ArgumentList an Exception was thrown.",
1058 				e, __FILE__, __LINE__
1059 			);
1060 		}
1061 	}
1062 
1063 	ArgumentList parseArgumentListImpl() {
1064 		string[] subRules;
1065 		subRules = ["A", "ACS", "AS"];
1066 		if(this.firstArgument()) {
1067 			Argument arg = this.parseArgument();
1068 			subRules = ["ACS"];
1069 			if(this.lex.front.type == TokenType.comma) {
1070 				this.lex.popFront();
1071 				subRules = ["ACS"];
1072 				if(this.firstArgumentList()) {
1073 					ArgumentList follow = this.parseArgumentList();
1074 
1075 					return new ArgumentList(ArgumentListEnum.ACS
1076 						, arg
1077 						, follow
1078 					);
1079 				}
1080 				auto app = appender!string();
1081 				formattedWrite(app, 
1082 					"Found a '%s' while looking for", 
1083 					this.lex.front
1084 				);
1085 				throw new ParseException(app.data,
1086 					__FILE__, __LINE__,
1087 					subRules,
1088 					["name -> Argument"]
1089 				);
1090 
1091 			} else if(this.firstArgumentList()) {
1092 				ArgumentList follow = this.parseArgumentList();
1093 
1094 				return new ArgumentList(ArgumentListEnum.AS
1095 					, arg
1096 					, follow
1097 				);
1098 			}
1099 			return new ArgumentList(ArgumentListEnum.A
1100 				, arg
1101 			);
1102 		}
1103 		auto app = appender!string();
1104 		formattedWrite(app, 
1105 			"Found a '%s' while looking for", 
1106 			this.lex.front
1107 		);
1108 		throw new ParseException(app.data,
1109 			__FILE__, __LINE__,
1110 			subRules,
1111 			["name"]
1112 		);
1113 
1114 	}
1115 
1116 	bool firstArgument() const pure @nogc @safe {
1117 		return this.lex.front.type == TokenType.name;
1118 	}
1119 
1120 	Argument parseArgument() {
1121 		try {
1122 			return this.parseArgumentImpl();
1123 		} catch(ParseException e) {
1124 			throw new ParseException(
1125 				"While parsing a Argument an Exception was thrown.",
1126 				e, __FILE__, __LINE__
1127 			);
1128 		}
1129 	}
1130 
1131 	Argument parseArgumentImpl() {
1132 		string[] subRules;
1133 		subRules = ["Name"];
1134 		if(this.lex.front.type == TokenType.name) {
1135 			Token name = this.lex.front;
1136 			this.lex.popFront();
1137 			subRules = ["Name"];
1138 			if(this.lex.front.type == TokenType.colon) {
1139 				this.lex.popFront();
1140 				subRules = ["Name"];
1141 				if(this.firstValueOrVariable()) {
1142 					ValueOrVariable vv = this.parseValueOrVariable();
1143 
1144 					return new Argument(ArgumentEnum.Name
1145 						, name
1146 						, vv
1147 					);
1148 				}
1149 				auto app = appender!string();
1150 				formattedWrite(app, 
1151 					"Found a '%s' while looking for", 
1152 					this.lex.front
1153 				);
1154 				throw new ParseException(app.data,
1155 					__FILE__, __LINE__,
1156 					subRules,
1157 					["dollar -> Variable","false_ -> Value","floatValue -> Value","intValue -> Value","lbrack -> Value","lcurly -> Value","name -> Value","stringValue -> Value","true_ -> Value"]
1158 				);
1159 
1160 			}
1161 			auto app = appender!string();
1162 			formattedWrite(app, 
1163 				"Found a '%s' while looking for", 
1164 				this.lex.front
1165 			);
1166 			throw new ParseException(app.data,
1167 				__FILE__, __LINE__,
1168 				subRules,
1169 				["colon"]
1170 			);
1171 
1172 		}
1173 		auto app = appender!string();
1174 		formattedWrite(app, 
1175 			"Found a '%s' while looking for", 
1176 			this.lex.front
1177 		);
1178 		throw new ParseException(app.data,
1179 			__FILE__, __LINE__,
1180 			subRules,
1181 			["name"]
1182 		);
1183 
1184 	}
1185 
1186 	bool firstFragmentDefinition() const pure @nogc @safe {
1187 		return this.lex.front.type == TokenType.fragment;
1188 	}
1189 
1190 	FragmentDefinition parseFragmentDefinition() {
1191 		try {
1192 			return this.parseFragmentDefinitionImpl();
1193 		} catch(ParseException e) {
1194 			throw new ParseException(
1195 				"While parsing a FragmentDefinition an Exception was thrown.",
1196 				e, __FILE__, __LINE__
1197 			);
1198 		}
1199 	}
1200 
1201 	FragmentDefinition parseFragmentDefinitionImpl() {
1202 		string[] subRules;
1203 		subRules = ["FTDS", "FTS"];
1204 		if(this.lex.front.type == TokenType.fragment) {
1205 			this.lex.popFront();
1206 			subRules = ["FTDS", "FTS"];
1207 			if(this.lex.front.type == TokenType.name) {
1208 				Token name = this.lex.front;
1209 				this.lex.popFront();
1210 				subRules = ["FTDS", "FTS"];
1211 				if(this.lex.front.type == TokenType.on_) {
1212 					this.lex.popFront();
1213 					subRules = ["FTDS", "FTS"];
1214 					if(this.lex.front.type == TokenType.name) {
1215 						Token tc = this.lex.front;
1216 						this.lex.popFront();
1217 						subRules = ["FTDS"];
1218 						if(this.firstDirectives()) {
1219 							Directives dirs = this.parseDirectives();
1220 							subRules = ["FTDS"];
1221 							if(this.firstSelectionSet()) {
1222 								SelectionSet ss = this.parseSelectionSet();
1223 
1224 								return new FragmentDefinition(FragmentDefinitionEnum.FTDS
1225 									, name
1226 									, tc
1227 									, dirs
1228 									, ss
1229 								);
1230 							}
1231 							auto app = appender!string();
1232 							formattedWrite(app, 
1233 								"Found a '%s' while looking for", 
1234 								this.lex.front
1235 							);
1236 							throw new ParseException(app.data,
1237 								__FILE__, __LINE__,
1238 								subRules,
1239 								["lcurly"]
1240 							);
1241 
1242 						} else if(this.firstSelectionSet()) {
1243 							SelectionSet ss = this.parseSelectionSet();
1244 
1245 							return new FragmentDefinition(FragmentDefinitionEnum.FTS
1246 								, name
1247 								, tc
1248 								, ss
1249 							);
1250 						}
1251 						auto app = appender!string();
1252 						formattedWrite(app, 
1253 							"Found a '%s' while looking for", 
1254 							this.lex.front
1255 						);
1256 						throw new ParseException(app.data,
1257 							__FILE__, __LINE__,
1258 							subRules,
1259 							["at -> Directive","lcurly"]
1260 						);
1261 
1262 					}
1263 					auto app = appender!string();
1264 					formattedWrite(app, 
1265 						"Found a '%s' while looking for", 
1266 						this.lex.front
1267 					);
1268 					throw new ParseException(app.data,
1269 						__FILE__, __LINE__,
1270 						subRules,
1271 						["name"]
1272 					);
1273 
1274 				}
1275 				auto app = appender!string();
1276 				formattedWrite(app, 
1277 					"Found a '%s' while looking for", 
1278 					this.lex.front
1279 				);
1280 				throw new ParseException(app.data,
1281 					__FILE__, __LINE__,
1282 					subRules,
1283 					["on_"]
1284 				);
1285 
1286 			}
1287 			auto app = appender!string();
1288 			formattedWrite(app, 
1289 				"Found a '%s' while looking for", 
1290 				this.lex.front
1291 			);
1292 			throw new ParseException(app.data,
1293 				__FILE__, __LINE__,
1294 				subRules,
1295 				["name"]
1296 			);
1297 
1298 		}
1299 		auto app = appender!string();
1300 		formattedWrite(app, 
1301 			"Found a '%s' while looking for", 
1302 			this.lex.front
1303 		);
1304 		throw new ParseException(app.data,
1305 			__FILE__, __LINE__,
1306 			subRules,
1307 			["fragment"]
1308 		);
1309 
1310 	}
1311 
1312 	bool firstDirectives() const pure @nogc @safe {
1313 		return this.firstDirective();
1314 	}
1315 
1316 	Directives parseDirectives() {
1317 		try {
1318 			return this.parseDirectivesImpl();
1319 		} catch(ParseException e) {
1320 			throw new ParseException(
1321 				"While parsing a Directives an Exception was thrown.",
1322 				e, __FILE__, __LINE__
1323 			);
1324 		}
1325 	}
1326 
1327 	Directives parseDirectivesImpl() {
1328 		string[] subRules;
1329 		subRules = ["Dir", "Dirs"];
1330 		if(this.firstDirective()) {
1331 			Directive dir = this.parseDirective();
1332 			subRules = ["Dirs"];
1333 			if(this.firstDirectives()) {
1334 				Directives follow = this.parseDirectives();
1335 
1336 				return new Directives(DirectivesEnum.Dirs
1337 					, dir
1338 					, follow
1339 				);
1340 			}
1341 			return new Directives(DirectivesEnum.Dir
1342 				, dir
1343 			);
1344 		}
1345 		auto app = appender!string();
1346 		formattedWrite(app, 
1347 			"Found a '%s' while looking for", 
1348 			this.lex.front
1349 		);
1350 		throw new ParseException(app.data,
1351 			__FILE__, __LINE__,
1352 			subRules,
1353 			["at"]
1354 		);
1355 
1356 	}
1357 
1358 	bool firstDirective() const pure @nogc @safe {
1359 		return this.lex.front.type == TokenType.at;
1360 	}
1361 
1362 	Directive parseDirective() {
1363 		try {
1364 			return this.parseDirectiveImpl();
1365 		} catch(ParseException e) {
1366 			throw new ParseException(
1367 				"While parsing a Directive an Exception was thrown.",
1368 				e, __FILE__, __LINE__
1369 			);
1370 		}
1371 	}
1372 
1373 	Directive parseDirectiveImpl() {
1374 		string[] subRules;
1375 		subRules = ["N", "NArg"];
1376 		if(this.lex.front.type == TokenType.at) {
1377 			this.lex.popFront();
1378 			subRules = ["N", "NArg"];
1379 			if(this.lex.front.type == TokenType.name) {
1380 				Token name = this.lex.front;
1381 				this.lex.popFront();
1382 				subRules = ["NArg"];
1383 				if(this.firstArguments()) {
1384 					Arguments arg = this.parseArguments();
1385 
1386 					return new Directive(DirectiveEnum.NArg
1387 						, name
1388 						, arg
1389 					);
1390 				}
1391 				return new Directive(DirectiveEnum.N
1392 					, name
1393 				);
1394 			}
1395 			auto app = appender!string();
1396 			formattedWrite(app, 
1397 				"Found a '%s' while looking for", 
1398 				this.lex.front
1399 			);
1400 			throw new ParseException(app.data,
1401 				__FILE__, __LINE__,
1402 				subRules,
1403 				["name"]
1404 			);
1405 
1406 		}
1407 		auto app = appender!string();
1408 		formattedWrite(app, 
1409 			"Found a '%s' while looking for", 
1410 			this.lex.front
1411 		);
1412 		throw new ParseException(app.data,
1413 			__FILE__, __LINE__,
1414 			subRules,
1415 			["at"]
1416 		);
1417 
1418 	}
1419 
1420 	bool firstVariableDefinitions() const pure @nogc @safe {
1421 		return this.lex.front.type == TokenType.lparen;
1422 	}
1423 
1424 	VariableDefinitions parseVariableDefinitions() {
1425 		try {
1426 			return this.parseVariableDefinitionsImpl();
1427 		} catch(ParseException e) {
1428 			throw new ParseException(
1429 				"While parsing a VariableDefinitions an Exception was thrown.",
1430 				e, __FILE__, __LINE__
1431 			);
1432 		}
1433 	}
1434 
1435 	VariableDefinitions parseVariableDefinitionsImpl() {
1436 		string[] subRules;
1437 		subRules = ["Empty", "Vars"];
1438 		if(this.lex.front.type == TokenType.lparen) {
1439 			this.lex.popFront();
1440 			subRules = ["Empty"];
1441 			if(this.lex.front.type == TokenType.rparen) {
1442 				this.lex.popFront();
1443 
1444 				return new VariableDefinitions(VariableDefinitionsEnum.Empty
1445 				);
1446 			} else if(this.firstVariableDefinitionList()) {
1447 				VariableDefinitionList vars = this.parseVariableDefinitionList();
1448 				subRules = ["Vars"];
1449 				if(this.lex.front.type == TokenType.rparen) {
1450 					this.lex.popFront();
1451 
1452 					return new VariableDefinitions(VariableDefinitionsEnum.Vars
1453 						, vars
1454 					);
1455 				}
1456 				auto app = appender!string();
1457 				formattedWrite(app, 
1458 					"Found a '%s' while looking for", 
1459 					this.lex.front
1460 				);
1461 				throw new ParseException(app.data,
1462 					__FILE__, __LINE__,
1463 					subRules,
1464 					["rparen"]
1465 				);
1466 
1467 			}
1468 			auto app = appender!string();
1469 			formattedWrite(app, 
1470 				"Found a '%s' while looking for", 
1471 				this.lex.front
1472 			);
1473 			throw new ParseException(app.data,
1474 				__FILE__, __LINE__,
1475 				subRules,
1476 				["rparen","dollar -> VariableDefinition"]
1477 			);
1478 
1479 		}
1480 		auto app = appender!string();
1481 		formattedWrite(app, 
1482 			"Found a '%s' while looking for", 
1483 			this.lex.front
1484 		);
1485 		throw new ParseException(app.data,
1486 			__FILE__, __LINE__,
1487 			subRules,
1488 			["lparen"]
1489 		);
1490 
1491 	}
1492 
1493 	bool firstVariableDefinitionList() const pure @nogc @safe {
1494 		return this.firstVariableDefinition();
1495 	}
1496 
1497 	VariableDefinitionList parseVariableDefinitionList() {
1498 		try {
1499 			return this.parseVariableDefinitionListImpl();
1500 		} catch(ParseException e) {
1501 			throw new ParseException(
1502 				"While parsing a VariableDefinitionList an Exception was thrown.",
1503 				e, __FILE__, __LINE__
1504 			);
1505 		}
1506 	}
1507 
1508 	VariableDefinitionList parseVariableDefinitionListImpl() {
1509 		string[] subRules;
1510 		subRules = ["V", "VCF", "VF"];
1511 		if(this.firstVariableDefinition()) {
1512 			VariableDefinition var = this.parseVariableDefinition();
1513 			subRules = ["VCF"];
1514 			if(this.lex.front.type == TokenType.comma) {
1515 				this.lex.popFront();
1516 				subRules = ["VCF"];
1517 				if(this.firstVariableDefinitionList()) {
1518 					VariableDefinitionList follow = this.parseVariableDefinitionList();
1519 
1520 					return new VariableDefinitionList(VariableDefinitionListEnum.VCF
1521 						, var
1522 						, follow
1523 					);
1524 				}
1525 				auto app = appender!string();
1526 				formattedWrite(app, 
1527 					"Found a '%s' while looking for", 
1528 					this.lex.front
1529 				);
1530 				throw new ParseException(app.data,
1531 					__FILE__, __LINE__,
1532 					subRules,
1533 					["dollar -> VariableDefinition"]
1534 				);
1535 
1536 			} else if(this.firstVariableDefinitionList()) {
1537 				VariableDefinitionList follow = this.parseVariableDefinitionList();
1538 
1539 				return new VariableDefinitionList(VariableDefinitionListEnum.VF
1540 					, var
1541 					, follow
1542 				);
1543 			}
1544 			return new VariableDefinitionList(VariableDefinitionListEnum.V
1545 				, var
1546 			);
1547 		}
1548 		auto app = appender!string();
1549 		formattedWrite(app, 
1550 			"Found a '%s' while looking for", 
1551 			this.lex.front
1552 		);
1553 		throw new ParseException(app.data,
1554 			__FILE__, __LINE__,
1555 			subRules,
1556 			["dollar -> Variable"]
1557 		);
1558 
1559 	}
1560 
1561 	bool firstVariableDefinition() const pure @nogc @safe {
1562 		return this.firstVariable();
1563 	}
1564 
1565 	VariableDefinition parseVariableDefinition() {
1566 		try {
1567 			return this.parseVariableDefinitionImpl();
1568 		} catch(ParseException e) {
1569 			throw new ParseException(
1570 				"While parsing a VariableDefinition an Exception was thrown.",
1571 				e, __FILE__, __LINE__
1572 			);
1573 		}
1574 	}
1575 
1576 	VariableDefinition parseVariableDefinitionImpl() {
1577 		string[] subRules;
1578 		subRules = ["Var", "VarD"];
1579 		if(this.firstVariable()) {
1580 			this.parseVariable();
1581 			subRules = ["Var", "VarD"];
1582 			if(this.lex.front.type == TokenType.colon) {
1583 				this.lex.popFront();
1584 				subRules = ["Var", "VarD"];
1585 				if(this.firstType()) {
1586 					Type type = this.parseType();
1587 					subRules = ["VarD"];
1588 					if(this.firstDefaultValue()) {
1589 						DefaultValue dvalue = this.parseDefaultValue();
1590 
1591 						return new VariableDefinition(VariableDefinitionEnum.VarD
1592 							, type
1593 							, dvalue
1594 						);
1595 					}
1596 					return new VariableDefinition(VariableDefinitionEnum.Var
1597 						, type
1598 					);
1599 				}
1600 				auto app = appender!string();
1601 				formattedWrite(app, 
1602 					"Found a '%s' while looking for", 
1603 					this.lex.front
1604 				);
1605 				throw new ParseException(app.data,
1606 					__FILE__, __LINE__,
1607 					subRules,
1608 					["lbrack -> ListType","name"]
1609 				);
1610 
1611 			}
1612 			auto app = appender!string();
1613 			formattedWrite(app, 
1614 				"Found a '%s' while looking for", 
1615 				this.lex.front
1616 			);
1617 			throw new ParseException(app.data,
1618 				__FILE__, __LINE__,
1619 				subRules,
1620 				["colon"]
1621 			);
1622 
1623 		}
1624 		auto app = appender!string();
1625 		formattedWrite(app, 
1626 			"Found a '%s' while looking for", 
1627 			this.lex.front
1628 		);
1629 		throw new ParseException(app.data,
1630 			__FILE__, __LINE__,
1631 			subRules,
1632 			["dollar"]
1633 		);
1634 
1635 	}
1636 
1637 	bool firstVariable() const pure @nogc @safe {
1638 		return this.lex.front.type == TokenType.dollar;
1639 	}
1640 
1641 	Variable parseVariable() {
1642 		try {
1643 			return this.parseVariableImpl();
1644 		} catch(ParseException e) {
1645 			throw new ParseException(
1646 				"While parsing a Variable an Exception was thrown.",
1647 				e, __FILE__, __LINE__
1648 			);
1649 		}
1650 	}
1651 
1652 	Variable parseVariableImpl() {
1653 		string[] subRules;
1654 		subRules = ["Var"];
1655 		if(this.lex.front.type == TokenType.dollar) {
1656 			this.lex.popFront();
1657 			subRules = ["Var"];
1658 			if(this.lex.front.type == TokenType.name) {
1659 				Token name = this.lex.front;
1660 				this.lex.popFront();
1661 
1662 				return new Variable(VariableEnum.Var
1663 					, name
1664 				);
1665 			}
1666 			auto app = appender!string();
1667 			formattedWrite(app, 
1668 				"Found a '%s' while looking for", 
1669 				this.lex.front
1670 			);
1671 			throw new ParseException(app.data,
1672 				__FILE__, __LINE__,
1673 				subRules,
1674 				["name"]
1675 			);
1676 
1677 		}
1678 		auto app = appender!string();
1679 		formattedWrite(app, 
1680 			"Found a '%s' while looking for", 
1681 			this.lex.front
1682 		);
1683 		throw new ParseException(app.data,
1684 			__FILE__, __LINE__,
1685 			subRules,
1686 			["dollar"]
1687 		);
1688 
1689 	}
1690 
1691 	bool firstDefaultValue() const pure @nogc @safe {
1692 		return this.lex.front.type == TokenType.equal;
1693 	}
1694 
1695 	DefaultValue parseDefaultValue() {
1696 		try {
1697 			return this.parseDefaultValueImpl();
1698 		} catch(ParseException e) {
1699 			throw new ParseException(
1700 				"While parsing a DefaultValue an Exception was thrown.",
1701 				e, __FILE__, __LINE__
1702 			);
1703 		}
1704 	}
1705 
1706 	DefaultValue parseDefaultValueImpl() {
1707 		string[] subRules;
1708 		subRules = ["DV"];
1709 		if(this.lex.front.type == TokenType.equal) {
1710 			this.lex.popFront();
1711 			subRules = ["DV"];
1712 			if(this.firstValue()) {
1713 				Value value = this.parseValue();
1714 
1715 				return new DefaultValue(DefaultValueEnum.DV
1716 					, value
1717 				);
1718 			}
1719 			auto app = appender!string();
1720 			formattedWrite(app, 
1721 				"Found a '%s' while looking for", 
1722 				this.lex.front
1723 			);
1724 			throw new ParseException(app.data,
1725 				__FILE__, __LINE__,
1726 				subRules,
1727 				["false_","floatValue","intValue","lbrack -> Array","lcurly -> ObjectType","name","stringValue","true_"]
1728 			);
1729 
1730 		}
1731 		auto app = appender!string();
1732 		formattedWrite(app, 
1733 			"Found a '%s' while looking for", 
1734 			this.lex.front
1735 		);
1736 		throw new ParseException(app.data,
1737 			__FILE__, __LINE__,
1738 			subRules,
1739 			["equal"]
1740 		);
1741 
1742 	}
1743 
1744 	bool firstValueOrVariable() const pure @nogc @safe {
1745 		return this.firstValue()
1746 			 || this.firstVariable();
1747 	}
1748 
1749 	ValueOrVariable parseValueOrVariable() {
1750 		try {
1751 			return this.parseValueOrVariableImpl();
1752 		} catch(ParseException e) {
1753 			throw new ParseException(
1754 				"While parsing a ValueOrVariable an Exception was thrown.",
1755 				e, __FILE__, __LINE__
1756 			);
1757 		}
1758 	}
1759 
1760 	ValueOrVariable parseValueOrVariableImpl() {
1761 		string[] subRules;
1762 		subRules = ["Val"];
1763 		if(this.firstValue()) {
1764 			Value val = this.parseValue();
1765 
1766 			return new ValueOrVariable(ValueOrVariableEnum.Val
1767 				, val
1768 			);
1769 		} else if(this.firstVariable()) {
1770 			Variable var = this.parseVariable();
1771 
1772 			return new ValueOrVariable(ValueOrVariableEnum.Var
1773 				, var
1774 			);
1775 		}
1776 		auto app = appender!string();
1777 		formattedWrite(app, 
1778 			"Found a '%s' while looking for", 
1779 			this.lex.front
1780 		);
1781 		throw new ParseException(app.data,
1782 			__FILE__, __LINE__,
1783 			subRules,
1784 			["false_","floatValue","intValue","lbrack -> Array","lcurly -> ObjectType","name","stringValue","true_","dollar"]
1785 		);
1786 
1787 	}
1788 
1789 	bool firstValue() const pure @nogc @safe {
1790 		return this.lex.front.type == TokenType.stringValue
1791 			 || this.lex.front.type == TokenType.intValue
1792 			 || this.lex.front.type == TokenType.floatValue
1793 			 || this.lex.front.type == TokenType.true_
1794 			 || this.lex.front.type == TokenType.false_
1795 			 || this.firstArray()
1796 			 || this.firstObjectType()
1797 			 || this.lex.front.type == TokenType.name;
1798 	}
1799 
1800 	Value parseValue() {
1801 		try {
1802 			return this.parseValueImpl();
1803 		} catch(ParseException e) {
1804 			throw new ParseException(
1805 				"While parsing a Value an Exception was thrown.",
1806 				e, __FILE__, __LINE__
1807 			);
1808 		}
1809 	}
1810 
1811 	Value parseValueImpl() {
1812 		string[] subRules;
1813 		subRules = ["STR"];
1814 		if(this.lex.front.type == TokenType.stringValue) {
1815 			Token tok = this.lex.front;
1816 			this.lex.popFront();
1817 
1818 			return new Value(ValueEnum.STR
1819 				, tok
1820 			);
1821 		} else if(this.lex.front.type == TokenType.intValue) {
1822 			Token tok = this.lex.front;
1823 			this.lex.popFront();
1824 
1825 			return new Value(ValueEnum.INT
1826 				, tok
1827 			);
1828 		} else if(this.lex.front.type == TokenType.floatValue) {
1829 			Token tok = this.lex.front;
1830 			this.lex.popFront();
1831 
1832 			return new Value(ValueEnum.FLOAT
1833 				, tok
1834 			);
1835 		} else if(this.lex.front.type == TokenType.true_) {
1836 			Token tok = this.lex.front;
1837 			this.lex.popFront();
1838 
1839 			return new Value(ValueEnum.T
1840 				, tok
1841 			);
1842 		} else if(this.lex.front.type == TokenType.false_) {
1843 			Token tok = this.lex.front;
1844 			this.lex.popFront();
1845 
1846 			return new Value(ValueEnum.F
1847 				, tok
1848 			);
1849 		} else if(this.firstArray()) {
1850 			Array arr = this.parseArray();
1851 
1852 			return new Value(ValueEnum.ARR
1853 				, arr
1854 			);
1855 		} else if(this.firstObjectType()) {
1856 			ObjectType obj = this.parseObjectType();
1857 
1858 			return new Value(ValueEnum.O
1859 				, obj
1860 			);
1861 		} else if(this.lex.front.type == TokenType.name) {
1862 			Token tok = this.lex.front;
1863 			this.lex.popFront();
1864 
1865 			return new Value(ValueEnum.E
1866 				, tok
1867 			);
1868 		}
1869 		auto app = appender!string();
1870 		formattedWrite(app, 
1871 			"Found a '%s' while looking for", 
1872 			this.lex.front
1873 		);
1874 		throw new ParseException(app.data,
1875 			__FILE__, __LINE__,
1876 			subRules,
1877 			["stringValue","intValue","floatValue","true_","false_","lbrack","lcurly","name"]
1878 		);
1879 
1880 	}
1881 
1882 	bool firstType() const pure @nogc @safe {
1883 		return this.lex.front.type == TokenType.name
1884 			 || this.firstListType();
1885 	}
1886 
1887 	Type parseType() {
1888 		try {
1889 			return this.parseTypeImpl();
1890 		} catch(ParseException e) {
1891 			throw new ParseException(
1892 				"While parsing a Type an Exception was thrown.",
1893 				e, __FILE__, __LINE__
1894 			);
1895 		}
1896 	}
1897 
1898 	Type parseTypeImpl() {
1899 		string[] subRules;
1900 		subRules = ["T", "TN"];
1901 		if(this.lex.front.type == TokenType.name) {
1902 			Token tname = this.lex.front;
1903 			this.lex.popFront();
1904 			subRules = ["TN"];
1905 			if(this.lex.front.type == TokenType.exclamation) {
1906 				this.lex.popFront();
1907 
1908 				return new Type(TypeEnum.TN
1909 					, tname
1910 				);
1911 			}
1912 			return new Type(TypeEnum.T
1913 				, tname
1914 			);
1915 		} else if(this.firstListType()) {
1916 			ListType list = this.parseListType();
1917 			subRules = ["LN"];
1918 			if(this.lex.front.type == TokenType.exclamation) {
1919 				this.lex.popFront();
1920 
1921 				return new Type(TypeEnum.LN
1922 					, list
1923 				);
1924 			}
1925 			return new Type(TypeEnum.L
1926 				, list
1927 			);
1928 		}
1929 		auto app = appender!string();
1930 		formattedWrite(app, 
1931 			"Found a '%s' while looking for", 
1932 			this.lex.front
1933 		);
1934 		throw new ParseException(app.data,
1935 			__FILE__, __LINE__,
1936 			subRules,
1937 			["name","lbrack"]
1938 		);
1939 
1940 	}
1941 
1942 	bool firstListType() const pure @nogc @safe {
1943 		return this.lex.front.type == TokenType.lbrack;
1944 	}
1945 
1946 	ListType parseListType() {
1947 		try {
1948 			return this.parseListTypeImpl();
1949 		} catch(ParseException e) {
1950 			throw new ParseException(
1951 				"While parsing a ListType an Exception was thrown.",
1952 				e, __FILE__, __LINE__
1953 			);
1954 		}
1955 	}
1956 
1957 	ListType parseListTypeImpl() {
1958 		string[] subRules;
1959 		subRules = ["T"];
1960 		if(this.lex.front.type == TokenType.lbrack) {
1961 			this.lex.popFront();
1962 			subRules = ["T"];
1963 			if(this.firstType()) {
1964 				Type type = this.parseType();
1965 				subRules = ["T"];
1966 				if(this.lex.front.type == TokenType.rbrack) {
1967 					this.lex.popFront();
1968 
1969 					return new ListType(ListTypeEnum.T
1970 						, type
1971 					);
1972 				}
1973 				auto app = appender!string();
1974 				formattedWrite(app, 
1975 					"Found a '%s' while looking for", 
1976 					this.lex.front
1977 				);
1978 				throw new ParseException(app.data,
1979 					__FILE__, __LINE__,
1980 					subRules,
1981 					["rbrack"]
1982 				);
1983 
1984 			}
1985 			auto app = appender!string();
1986 			formattedWrite(app, 
1987 				"Found a '%s' while looking for", 
1988 				this.lex.front
1989 			);
1990 			throw new ParseException(app.data,
1991 				__FILE__, __LINE__,
1992 				subRules,
1993 				["lbrack -> ListType","name"]
1994 			);
1995 
1996 		}
1997 		auto app = appender!string();
1998 		formattedWrite(app, 
1999 			"Found a '%s' while looking for", 
2000 			this.lex.front
2001 		);
2002 		throw new ParseException(app.data,
2003 			__FILE__, __LINE__,
2004 			subRules,
2005 			["lbrack"]
2006 		);
2007 
2008 	}
2009 
2010 	bool firstValues() const pure @nogc @safe {
2011 		return this.firstValue();
2012 	}
2013 
2014 	Values parseValues() {
2015 		try {
2016 			return this.parseValuesImpl();
2017 		} catch(ParseException e) {
2018 			throw new ParseException(
2019 				"While parsing a Values an Exception was thrown.",
2020 				e, __FILE__, __LINE__
2021 			);
2022 		}
2023 	}
2024 
2025 	Values parseValuesImpl() {
2026 		string[] subRules;
2027 		subRules = ["Val", "Vals"];
2028 		if(this.firstValue()) {
2029 			Value val = this.parseValue();
2030 			subRules = ["Vals"];
2031 			if(this.lex.front.type == TokenType.comma) {
2032 				this.lex.popFront();
2033 				subRules = ["Vals"];
2034 				if(this.firstValues()) {
2035 					Values follow = this.parseValues();
2036 
2037 					return new Values(ValuesEnum.Vals
2038 						, val
2039 						, follow
2040 					);
2041 				}
2042 				auto app = appender!string();
2043 				formattedWrite(app, 
2044 					"Found a '%s' while looking for", 
2045 					this.lex.front
2046 				);
2047 				throw new ParseException(app.data,
2048 					__FILE__, __LINE__,
2049 					subRules,
2050 					["false_ -> Value","floatValue -> Value","intValue -> Value","lbrack -> Value","lcurly -> Value","name -> Value","stringValue -> Value","true_ -> Value"]
2051 				);
2052 
2053 			}
2054 			return new Values(ValuesEnum.Val
2055 				, val
2056 			);
2057 		}
2058 		auto app = appender!string();
2059 		formattedWrite(app, 
2060 			"Found a '%s' while looking for", 
2061 			this.lex.front
2062 		);
2063 		throw new ParseException(app.data,
2064 			__FILE__, __LINE__,
2065 			subRules,
2066 			["false_","floatValue","intValue","lbrack -> Array","lcurly -> ObjectType","name","stringValue","true_"]
2067 		);
2068 
2069 	}
2070 
2071 	bool firstArray() const pure @nogc @safe {
2072 		return this.lex.front.type == TokenType.lbrack;
2073 	}
2074 
2075 	Array parseArray() {
2076 		try {
2077 			return this.parseArrayImpl();
2078 		} catch(ParseException e) {
2079 			throw new ParseException(
2080 				"While parsing a Array an Exception was thrown.",
2081 				e, __FILE__, __LINE__
2082 			);
2083 		}
2084 	}
2085 
2086 	Array parseArrayImpl() {
2087 		string[] subRules;
2088 		subRules = ["Empty", "Value"];
2089 		if(this.lex.front.type == TokenType.lbrack) {
2090 			this.lex.popFront();
2091 			subRules = ["Empty"];
2092 			if(this.lex.front.type == TokenType.rbrack) {
2093 				this.lex.popFront();
2094 
2095 				return new Array(ArrayEnum.Empty
2096 				);
2097 			} else if(this.firstValues()) {
2098 				Values vals = this.parseValues();
2099 				subRules = ["Value"];
2100 				if(this.lex.front.type == TokenType.rbrack) {
2101 					this.lex.popFront();
2102 
2103 					return new Array(ArrayEnum.Value
2104 						, vals
2105 					);
2106 				}
2107 				auto app = appender!string();
2108 				formattedWrite(app, 
2109 					"Found a '%s' while looking for", 
2110 					this.lex.front
2111 				);
2112 				throw new ParseException(app.data,
2113 					__FILE__, __LINE__,
2114 					subRules,
2115 					["rbrack"]
2116 				);
2117 
2118 			}
2119 			auto app = appender!string();
2120 			formattedWrite(app, 
2121 				"Found a '%s' while looking for", 
2122 				this.lex.front
2123 			);
2124 			throw new ParseException(app.data,
2125 				__FILE__, __LINE__,
2126 				subRules,
2127 				["rbrack","false_ -> Value","floatValue -> Value","intValue -> Value","lbrack -> Value","lcurly -> Value","name -> Value","stringValue -> Value","true_ -> Value"]
2128 			);
2129 
2130 		}
2131 		auto app = appender!string();
2132 		formattedWrite(app, 
2133 			"Found a '%s' while looking for", 
2134 			this.lex.front
2135 		);
2136 		throw new ParseException(app.data,
2137 			__FILE__, __LINE__,
2138 			subRules,
2139 			["lbrack"]
2140 		);
2141 
2142 	}
2143 
2144 	bool firstObjectValues() const pure @nogc @safe {
2145 		return this.lex.front.type == TokenType.name;
2146 	}
2147 
2148 	ObjectValues parseObjectValues() {
2149 		try {
2150 			return this.parseObjectValuesImpl();
2151 		} catch(ParseException e) {
2152 			throw new ParseException(
2153 				"While parsing a ObjectValues an Exception was thrown.",
2154 				e, __FILE__, __LINE__
2155 			);
2156 		}
2157 	}
2158 
2159 	ObjectValues parseObjectValuesImpl() {
2160 		string[] subRules;
2161 		subRules = ["V", "Vs", "Vsc"];
2162 		if(this.lex.front.type == TokenType.name) {
2163 			Token name = this.lex.front;
2164 			this.lex.popFront();
2165 			subRules = ["V", "Vs", "Vsc"];
2166 			if(this.lex.front.type == TokenType.colon) {
2167 				this.lex.popFront();
2168 				subRules = ["V", "Vs", "Vsc"];
2169 				if(this.firstValue()) {
2170 					Value val = this.parseValue();
2171 					subRules = ["Vsc"];
2172 					if(this.lex.front.type == TokenType.comma) {
2173 						this.lex.popFront();
2174 						subRules = ["Vsc"];
2175 						if(this.firstObjectValues()) {
2176 							ObjectValues follow = this.parseObjectValues();
2177 
2178 							return new ObjectValues(ObjectValuesEnum.Vsc
2179 								, name
2180 								, val
2181 								, follow
2182 							);
2183 						}
2184 						auto app = appender!string();
2185 						formattedWrite(app, 
2186 							"Found a '%s' while looking for", 
2187 							this.lex.front
2188 						);
2189 						throw new ParseException(app.data,
2190 							__FILE__, __LINE__,
2191 							subRules,
2192 							["name"]
2193 						);
2194 
2195 					} else if(this.firstObjectValues()) {
2196 						ObjectValues follow = this.parseObjectValues();
2197 
2198 						return new ObjectValues(ObjectValuesEnum.Vs
2199 							, name
2200 							, val
2201 							, follow
2202 						);
2203 					}
2204 					return new ObjectValues(ObjectValuesEnum.V
2205 						, name
2206 						, val
2207 					);
2208 				}
2209 				auto app = appender!string();
2210 				formattedWrite(app, 
2211 					"Found a '%s' while looking for", 
2212 					this.lex.front
2213 				);
2214 				throw new ParseException(app.data,
2215 					__FILE__, __LINE__,
2216 					subRules,
2217 					["false_","floatValue","intValue","lbrack -> Array","lcurly -> ObjectType","name","stringValue","true_"]
2218 				);
2219 
2220 			}
2221 			auto app = appender!string();
2222 			formattedWrite(app, 
2223 				"Found a '%s' while looking for", 
2224 				this.lex.front
2225 			);
2226 			throw new ParseException(app.data,
2227 				__FILE__, __LINE__,
2228 				subRules,
2229 				["colon"]
2230 			);
2231 
2232 		}
2233 		auto app = appender!string();
2234 		formattedWrite(app, 
2235 			"Found a '%s' while looking for", 
2236 			this.lex.front
2237 		);
2238 		throw new ParseException(app.data,
2239 			__FILE__, __LINE__,
2240 			subRules,
2241 			["name"]
2242 		);
2243 
2244 	}
2245 
2246 	bool firstObjectType() const pure @nogc @safe {
2247 		return this.lex.front.type == TokenType.lcurly;
2248 	}
2249 
2250 	ObjectType parseObjectType() {
2251 		try {
2252 			return this.parseObjectTypeImpl();
2253 		} catch(ParseException e) {
2254 			throw new ParseException(
2255 				"While parsing a ObjectType an Exception was thrown.",
2256 				e, __FILE__, __LINE__
2257 			);
2258 		}
2259 	}
2260 
2261 	ObjectType parseObjectTypeImpl() {
2262 		string[] subRules;
2263 		subRules = ["Var"];
2264 		if(this.lex.front.type == TokenType.lcurly) {
2265 			this.lex.popFront();
2266 			subRules = ["Var"];
2267 			if(this.firstObjectValues()) {
2268 				ObjectValues vals = this.parseObjectValues();
2269 				subRules = ["Var"];
2270 				if(this.lex.front.type == TokenType.rcurly) {
2271 					this.lex.popFront();
2272 
2273 					return new ObjectType(ObjectTypeEnum.Var
2274 						, vals
2275 					);
2276 				}
2277 				auto app = appender!string();
2278 				formattedWrite(app, 
2279 					"Found a '%s' while looking for", 
2280 					this.lex.front
2281 				);
2282 				throw new ParseException(app.data,
2283 					__FILE__, __LINE__,
2284 					subRules,
2285 					["rcurly"]
2286 				);
2287 
2288 			}
2289 			auto app = appender!string();
2290 			formattedWrite(app, 
2291 				"Found a '%s' while looking for", 
2292 				this.lex.front
2293 			);
2294 			throw new ParseException(app.data,
2295 				__FILE__, __LINE__,
2296 				subRules,
2297 				["name"]
2298 			);
2299 
2300 		}
2301 		auto app = appender!string();
2302 		formattedWrite(app, 
2303 			"Found a '%s' while looking for", 
2304 			this.lex.front
2305 		);
2306 		throw new ParseException(app.data,
2307 			__FILE__, __LINE__,
2308 			subRules,
2309 			["lcurly"]
2310 		);
2311 
2312 	}
2313 
2314 	bool firstTypeSystemDefinition() const pure @nogc @safe {
2315 		return this.firstSchemaDefinition()
2316 			 || this.firstTypeDefinition()
2317 			 || this.firstTypeExtensionDefinition()
2318 			 || this.firstDirectiveDefinition();
2319 	}
2320 
2321 	TypeSystemDefinition parseTypeSystemDefinition() {
2322 		try {
2323 			return this.parseTypeSystemDefinitionImpl();
2324 		} catch(ParseException e) {
2325 			throw new ParseException(
2326 				"While parsing a TypeSystemDefinition an Exception was thrown.",
2327 				e, __FILE__, __LINE__
2328 			);
2329 		}
2330 	}
2331 
2332 	TypeSystemDefinition parseTypeSystemDefinitionImpl() {
2333 		string[] subRules;
2334 		subRules = ["S"];
2335 		if(this.firstSchemaDefinition()) {
2336 			SchemaDefinition sch = this.parseSchemaDefinition();
2337 
2338 			return new TypeSystemDefinition(TypeSystemDefinitionEnum.S
2339 				, sch
2340 			);
2341 		} else if(this.firstTypeDefinition()) {
2342 			TypeDefinition td = this.parseTypeDefinition();
2343 
2344 			return new TypeSystemDefinition(TypeSystemDefinitionEnum.T
2345 				, td
2346 			);
2347 		} else if(this.firstTypeExtensionDefinition()) {
2348 			TypeExtensionDefinition ted = this.parseTypeExtensionDefinition();
2349 
2350 			return new TypeSystemDefinition(TypeSystemDefinitionEnum.TE
2351 				, ted
2352 			);
2353 		} else if(this.firstDirectiveDefinition()) {
2354 			DirectiveDefinition dd = this.parseDirectiveDefinition();
2355 
2356 			return new TypeSystemDefinition(TypeSystemDefinitionEnum.D
2357 				, dd
2358 			);
2359 		}
2360 		auto app = appender!string();
2361 		formattedWrite(app, 
2362 			"Found a '%s' while looking for", 
2363 			this.lex.front
2364 		);
2365 		throw new ParseException(app.data,
2366 			__FILE__, __LINE__,
2367 			subRules,
2368 			["schema","enum_ -> EnumTypeDefinition","input -> InputObjectTypeDefinition","interface_ -> InterfaceTypeDefinition","scalar -> ScalarTypeDefinition","type -> ObjectTypeDefinition","union_ -> UnionTypeDefinition","extend","directive"]
2369 		);
2370 
2371 	}
2372 
2373 	bool firstTypeDefinition() const pure @nogc @safe {
2374 		return this.firstScalarTypeDefinition()
2375 			 || this.firstObjectTypeDefinition()
2376 			 || this.firstInterfaceTypeDefinition()
2377 			 || this.firstUnionTypeDefinition()
2378 			 || this.firstEnumTypeDefinition()
2379 			 || this.firstInputObjectTypeDefinition();
2380 	}
2381 
2382 	TypeDefinition parseTypeDefinition() {
2383 		try {
2384 			return this.parseTypeDefinitionImpl();
2385 		} catch(ParseException e) {
2386 			throw new ParseException(
2387 				"While parsing a TypeDefinition an Exception was thrown.",
2388 				e, __FILE__, __LINE__
2389 			);
2390 		}
2391 	}
2392 
2393 	TypeDefinition parseTypeDefinitionImpl() {
2394 		string[] subRules;
2395 		subRules = ["S"];
2396 		if(this.firstScalarTypeDefinition()) {
2397 			ScalarTypeDefinition std = this.parseScalarTypeDefinition();
2398 
2399 			return new TypeDefinition(TypeDefinitionEnum.S
2400 				, std
2401 			);
2402 		} else if(this.firstObjectTypeDefinition()) {
2403 			ObjectTypeDefinition otd = this.parseObjectTypeDefinition();
2404 
2405 			return new TypeDefinition(TypeDefinitionEnum.O
2406 				, otd
2407 			);
2408 		} else if(this.firstInterfaceTypeDefinition()) {
2409 			InterfaceTypeDefinition itd = this.parseInterfaceTypeDefinition();
2410 
2411 			return new TypeDefinition(TypeDefinitionEnum.I
2412 				, itd
2413 			);
2414 		} else if(this.firstUnionTypeDefinition()) {
2415 			UnionTypeDefinition utd = this.parseUnionTypeDefinition();
2416 
2417 			return new TypeDefinition(TypeDefinitionEnum.U
2418 				, utd
2419 			);
2420 		} else if(this.firstEnumTypeDefinition()) {
2421 			EnumTypeDefinition etd = this.parseEnumTypeDefinition();
2422 
2423 			return new TypeDefinition(TypeDefinitionEnum.E
2424 				, etd
2425 			);
2426 		} else if(this.firstInputObjectTypeDefinition()) {
2427 			InputObjectTypeDefinition iod = this.parseInputObjectTypeDefinition();
2428 
2429 			return new TypeDefinition(TypeDefinitionEnum.IO
2430 				, iod
2431 			);
2432 		}
2433 		auto app = appender!string();
2434 		formattedWrite(app, 
2435 			"Found a '%s' while looking for", 
2436 			this.lex.front
2437 		);
2438 		throw new ParseException(app.data,
2439 			__FILE__, __LINE__,
2440 			subRules,
2441 			["scalar","type","interface_","union_","enum_","input"]
2442 		);
2443 
2444 	}
2445 
2446 	bool firstSchemaDefinition() const pure @nogc @safe {
2447 		return this.lex.front.type == TokenType.schema;
2448 	}
2449 
2450 	SchemaDefinition parseSchemaDefinition() {
2451 		try {
2452 			return this.parseSchemaDefinitionImpl();
2453 		} catch(ParseException e) {
2454 			throw new ParseException(
2455 				"While parsing a SchemaDefinition an Exception was thrown.",
2456 				e, __FILE__, __LINE__
2457 			);
2458 		}
2459 	}
2460 
2461 	SchemaDefinition parseSchemaDefinitionImpl() {
2462 		string[] subRules;
2463 		subRules = ["DO", "O"];
2464 		if(this.lex.front.type == TokenType.schema) {
2465 			this.lex.popFront();
2466 			subRules = ["DO"];
2467 			if(this.firstDirectives()) {
2468 				Directives dir = this.parseDirectives();
2469 				subRules = ["DO"];
2470 				if(this.lex.front.type == TokenType.lcurly) {
2471 					this.lex.popFront();
2472 					subRules = ["DO"];
2473 					if(this.firstOperationTypeDefinitions()) {
2474 						OperationTypeDefinitions otds = this.parseOperationTypeDefinitions();
2475 						subRules = ["DO"];
2476 						if(this.lex.front.type == TokenType.rcurly) {
2477 							this.lex.popFront();
2478 
2479 							return new SchemaDefinition(SchemaDefinitionEnum.DO
2480 								, dir
2481 								, otds
2482 							);
2483 						}
2484 						auto app = appender!string();
2485 						formattedWrite(app, 
2486 							"Found a '%s' while looking for", 
2487 							this.lex.front
2488 						);
2489 						throw new ParseException(app.data,
2490 							__FILE__, __LINE__,
2491 							subRules,
2492 							["rcurly"]
2493 						);
2494 
2495 					}
2496 					auto app = appender!string();
2497 					formattedWrite(app, 
2498 						"Found a '%s' while looking for", 
2499 						this.lex.front
2500 					);
2501 					throw new ParseException(app.data,
2502 						__FILE__, __LINE__,
2503 						subRules,
2504 						["mutation -> OperationTypeDefinition","query -> OperationTypeDefinition","subscription -> OperationTypeDefinition"]
2505 					);
2506 
2507 				}
2508 				auto app = appender!string();
2509 				formattedWrite(app, 
2510 					"Found a '%s' while looking for", 
2511 					this.lex.front
2512 				);
2513 				throw new ParseException(app.data,
2514 					__FILE__, __LINE__,
2515 					subRules,
2516 					["lcurly"]
2517 				);
2518 
2519 			} else if(this.lex.front.type == TokenType.lcurly) {
2520 				this.lex.popFront();
2521 				subRules = ["O"];
2522 				if(this.firstOperationTypeDefinitions()) {
2523 					OperationTypeDefinitions otds = this.parseOperationTypeDefinitions();
2524 					subRules = ["O"];
2525 					if(this.lex.front.type == TokenType.rcurly) {
2526 						this.lex.popFront();
2527 
2528 						return new SchemaDefinition(SchemaDefinitionEnum.O
2529 							, otds
2530 						);
2531 					}
2532 					auto app = appender!string();
2533 					formattedWrite(app, 
2534 						"Found a '%s' while looking for", 
2535 						this.lex.front
2536 					);
2537 					throw new ParseException(app.data,
2538 						__FILE__, __LINE__,
2539 						subRules,
2540 						["rcurly"]
2541 					);
2542 
2543 				}
2544 				auto app = appender!string();
2545 				formattedWrite(app, 
2546 					"Found a '%s' while looking for", 
2547 					this.lex.front
2548 				);
2549 				throw new ParseException(app.data,
2550 					__FILE__, __LINE__,
2551 					subRules,
2552 					["mutation -> OperationTypeDefinition","query -> OperationTypeDefinition","subscription -> OperationTypeDefinition"]
2553 				);
2554 
2555 			}
2556 			auto app = appender!string();
2557 			formattedWrite(app, 
2558 				"Found a '%s' while looking for", 
2559 				this.lex.front
2560 			);
2561 			throw new ParseException(app.data,
2562 				__FILE__, __LINE__,
2563 				subRules,
2564 				["at -> Directive","lcurly"]
2565 			);
2566 
2567 		}
2568 		auto app = appender!string();
2569 		formattedWrite(app, 
2570 			"Found a '%s' while looking for", 
2571 			this.lex.front
2572 		);
2573 		throw new ParseException(app.data,
2574 			__FILE__, __LINE__,
2575 			subRules,
2576 			["schema"]
2577 		);
2578 
2579 	}
2580 
2581 	bool firstOperationTypeDefinitions() const pure @nogc @safe {
2582 		return this.firstOperationTypeDefinition();
2583 	}
2584 
2585 	OperationTypeDefinitions parseOperationTypeDefinitions() {
2586 		try {
2587 			return this.parseOperationTypeDefinitionsImpl();
2588 		} catch(ParseException e) {
2589 			throw new ParseException(
2590 				"While parsing a OperationTypeDefinitions an Exception was thrown.",
2591 				e, __FILE__, __LINE__
2592 			);
2593 		}
2594 	}
2595 
2596 	OperationTypeDefinitions parseOperationTypeDefinitionsImpl() {
2597 		string[] subRules;
2598 		subRules = ["O", "OCS", "OS"];
2599 		if(this.firstOperationTypeDefinition()) {
2600 			OperationTypeDefinition otd = this.parseOperationTypeDefinition();
2601 			subRules = ["OCS"];
2602 			if(this.lex.front.type == TokenType.comma) {
2603 				this.lex.popFront();
2604 				subRules = ["OCS"];
2605 				if(this.firstOperationTypeDefinitions()) {
2606 					OperationTypeDefinitions follow = this.parseOperationTypeDefinitions();
2607 
2608 					return new OperationTypeDefinitions(OperationTypeDefinitionsEnum.OCS
2609 						, otd
2610 						, follow
2611 					);
2612 				}
2613 				auto app = appender!string();
2614 				formattedWrite(app, 
2615 					"Found a '%s' while looking for", 
2616 					this.lex.front
2617 				);
2618 				throw new ParseException(app.data,
2619 					__FILE__, __LINE__,
2620 					subRules,
2621 					["mutation -> OperationTypeDefinition","query -> OperationTypeDefinition","subscription -> OperationTypeDefinition"]
2622 				);
2623 
2624 			} else if(this.firstOperationTypeDefinitions()) {
2625 				OperationTypeDefinitions follow = this.parseOperationTypeDefinitions();
2626 
2627 				return new OperationTypeDefinitions(OperationTypeDefinitionsEnum.OS
2628 					, otd
2629 					, follow
2630 				);
2631 			}
2632 			return new OperationTypeDefinitions(OperationTypeDefinitionsEnum.O
2633 				, otd
2634 			);
2635 		}
2636 		auto app = appender!string();
2637 		formattedWrite(app, 
2638 			"Found a '%s' while looking for", 
2639 			this.lex.front
2640 		);
2641 		throw new ParseException(app.data,
2642 			__FILE__, __LINE__,
2643 			subRules,
2644 			["mutation -> OperationType","query -> OperationType","subscription -> OperationType"]
2645 		);
2646 
2647 	}
2648 
2649 	bool firstOperationTypeDefinition() const pure @nogc @safe {
2650 		return this.firstOperationType();
2651 	}
2652 
2653 	OperationTypeDefinition parseOperationTypeDefinition() {
2654 		try {
2655 			return this.parseOperationTypeDefinitionImpl();
2656 		} catch(ParseException e) {
2657 			throw new ParseException(
2658 				"While parsing a OperationTypeDefinition an Exception was thrown.",
2659 				e, __FILE__, __LINE__
2660 			);
2661 		}
2662 	}
2663 
2664 	OperationTypeDefinition parseOperationTypeDefinitionImpl() {
2665 		string[] subRules;
2666 		subRules = ["O"];
2667 		if(this.firstOperationType()) {
2668 			OperationType ot = this.parseOperationType();
2669 			subRules = ["O"];
2670 			if(this.lex.front.type == TokenType.colon) {
2671 				this.lex.popFront();
2672 				subRules = ["O"];
2673 				if(this.lex.front.type == TokenType.name) {
2674 					Token nt = this.lex.front;
2675 					this.lex.popFront();
2676 
2677 					return new OperationTypeDefinition(OperationTypeDefinitionEnum.O
2678 						, ot
2679 						, nt
2680 					);
2681 				}
2682 				auto app = appender!string();
2683 				formattedWrite(app, 
2684 					"Found a '%s' while looking for", 
2685 					this.lex.front
2686 				);
2687 				throw new ParseException(app.data,
2688 					__FILE__, __LINE__,
2689 					subRules,
2690 					["name"]
2691 				);
2692 
2693 			}
2694 			auto app = appender!string();
2695 			formattedWrite(app, 
2696 				"Found a '%s' while looking for", 
2697 				this.lex.front
2698 			);
2699 			throw new ParseException(app.data,
2700 				__FILE__, __LINE__,
2701 				subRules,
2702 				["colon"]
2703 			);
2704 
2705 		}
2706 		auto app = appender!string();
2707 		formattedWrite(app, 
2708 			"Found a '%s' while looking for", 
2709 			this.lex.front
2710 		);
2711 		throw new ParseException(app.data,
2712 			__FILE__, __LINE__,
2713 			subRules,
2714 			["mutation","query","subscription"]
2715 		);
2716 
2717 	}
2718 
2719 	bool firstScalarTypeDefinition() const pure @nogc @safe {
2720 		return this.lex.front.type == TokenType.scalar;
2721 	}
2722 
2723 	ScalarTypeDefinition parseScalarTypeDefinition() {
2724 		try {
2725 			return this.parseScalarTypeDefinitionImpl();
2726 		} catch(ParseException e) {
2727 			throw new ParseException(
2728 				"While parsing a ScalarTypeDefinition an Exception was thrown.",
2729 				e, __FILE__, __LINE__
2730 			);
2731 		}
2732 	}
2733 
2734 	ScalarTypeDefinition parseScalarTypeDefinitionImpl() {
2735 		string[] subRules;
2736 		subRules = ["D", "S"];
2737 		if(this.lex.front.type == TokenType.scalar) {
2738 			this.lex.popFront();
2739 			subRules = ["D", "S"];
2740 			if(this.lex.front.type == TokenType.name) {
2741 				Token name = this.lex.front;
2742 				this.lex.popFront();
2743 				subRules = ["D"];
2744 				if(this.firstDirectives()) {
2745 					Directives dir = this.parseDirectives();
2746 
2747 					return new ScalarTypeDefinition(ScalarTypeDefinitionEnum.D
2748 						, name
2749 						, dir
2750 					);
2751 				}
2752 				return new ScalarTypeDefinition(ScalarTypeDefinitionEnum.S
2753 					, name
2754 				);
2755 			}
2756 			auto app = appender!string();
2757 			formattedWrite(app, 
2758 				"Found a '%s' while looking for", 
2759 				this.lex.front
2760 			);
2761 			throw new ParseException(app.data,
2762 				__FILE__, __LINE__,
2763 				subRules,
2764 				["name"]
2765 			);
2766 
2767 		}
2768 		auto app = appender!string();
2769 		formattedWrite(app, 
2770 			"Found a '%s' while looking for", 
2771 			this.lex.front
2772 		);
2773 		throw new ParseException(app.data,
2774 			__FILE__, __LINE__,
2775 			subRules,
2776 			["scalar"]
2777 		);
2778 
2779 	}
2780 
2781 	bool firstObjectTypeDefinition() const pure @nogc @safe {
2782 		return this.lex.front.type == TokenType.type;
2783 	}
2784 
2785 	ObjectTypeDefinition parseObjectTypeDefinition() {
2786 		try {
2787 			return this.parseObjectTypeDefinitionImpl();
2788 		} catch(ParseException e) {
2789 			throw new ParseException(
2790 				"While parsing a ObjectTypeDefinition an Exception was thrown.",
2791 				e, __FILE__, __LINE__
2792 			);
2793 		}
2794 	}
2795 
2796 	ObjectTypeDefinition parseObjectTypeDefinitionImpl() {
2797 		string[] subRules;
2798 		subRules = ["D", "F", "I", "ID"];
2799 		if(this.lex.front.type == TokenType.type) {
2800 			this.lex.popFront();
2801 			subRules = ["D", "F", "I", "ID"];
2802 			if(this.lex.front.type == TokenType.name) {
2803 				Token name = this.lex.front;
2804 				this.lex.popFront();
2805 				subRules = ["I", "ID"];
2806 				if(this.firstImplementsInterfaces()) {
2807 					ImplementsInterfaces ii = this.parseImplementsInterfaces();
2808 					subRules = ["ID"];
2809 					if(this.firstDirectives()) {
2810 						Directives dir = this.parseDirectives();
2811 						subRules = ["ID"];
2812 						if(this.lex.front.type == TokenType.lcurly) {
2813 							this.lex.popFront();
2814 							subRules = ["ID"];
2815 							if(this.firstFieldDefinitions()) {
2816 								FieldDefinitions fds = this.parseFieldDefinitions();
2817 								subRules = ["ID"];
2818 								if(this.lex.front.type == TokenType.rcurly) {
2819 									this.lex.popFront();
2820 
2821 									return new ObjectTypeDefinition(ObjectTypeDefinitionEnum.ID
2822 										, name
2823 										, ii
2824 										, dir
2825 										, fds
2826 									);
2827 								}
2828 								auto app = appender!string();
2829 								formattedWrite(app, 
2830 									"Found a '%s' while looking for", 
2831 									this.lex.front
2832 								);
2833 								throw new ParseException(app.data,
2834 									__FILE__, __LINE__,
2835 									subRules,
2836 									["rcurly"]
2837 								);
2838 
2839 							}
2840 							auto app = appender!string();
2841 							formattedWrite(app, 
2842 								"Found a '%s' while looking for", 
2843 								this.lex.front
2844 							);
2845 							throw new ParseException(app.data,
2846 								__FILE__, __LINE__,
2847 								subRules,
2848 								["name -> FieldDefinition"]
2849 							);
2850 
2851 						}
2852 						auto app = appender!string();
2853 						formattedWrite(app, 
2854 							"Found a '%s' while looking for", 
2855 							this.lex.front
2856 						);
2857 						throw new ParseException(app.data,
2858 							__FILE__, __LINE__,
2859 							subRules,
2860 							["lcurly"]
2861 						);
2862 
2863 					} else if(this.lex.front.type == TokenType.lcurly) {
2864 						this.lex.popFront();
2865 						subRules = ["I"];
2866 						if(this.firstFieldDefinitions()) {
2867 							FieldDefinitions fds = this.parseFieldDefinitions();
2868 							subRules = ["I"];
2869 							if(this.lex.front.type == TokenType.rcurly) {
2870 								this.lex.popFront();
2871 
2872 								return new ObjectTypeDefinition(ObjectTypeDefinitionEnum.I
2873 									, name
2874 									, ii
2875 									, fds
2876 								);
2877 							}
2878 							auto app = appender!string();
2879 							formattedWrite(app, 
2880 								"Found a '%s' while looking for", 
2881 								this.lex.front
2882 							);
2883 							throw new ParseException(app.data,
2884 								__FILE__, __LINE__,
2885 								subRules,
2886 								["rcurly"]
2887 							);
2888 
2889 						}
2890 						auto app = appender!string();
2891 						formattedWrite(app, 
2892 							"Found a '%s' while looking for", 
2893 							this.lex.front
2894 						);
2895 						throw new ParseException(app.data,
2896 							__FILE__, __LINE__,
2897 							subRules,
2898 							["name -> FieldDefinition"]
2899 						);
2900 
2901 					}
2902 					auto app = appender!string();
2903 					formattedWrite(app, 
2904 						"Found a '%s' while looking for", 
2905 						this.lex.front
2906 					);
2907 					throw new ParseException(app.data,
2908 						__FILE__, __LINE__,
2909 						subRules,
2910 						["at -> Directive","lcurly"]
2911 					);
2912 
2913 				} else if(this.firstDirectives()) {
2914 					Directives dir = this.parseDirectives();
2915 					subRules = ["D"];
2916 					if(this.lex.front.type == TokenType.lcurly) {
2917 						this.lex.popFront();
2918 						subRules = ["D"];
2919 						if(this.firstFieldDefinitions()) {
2920 							FieldDefinitions fds = this.parseFieldDefinitions();
2921 							subRules = ["D"];
2922 							if(this.lex.front.type == TokenType.rcurly) {
2923 								this.lex.popFront();
2924 
2925 								return new ObjectTypeDefinition(ObjectTypeDefinitionEnum.D
2926 									, name
2927 									, dir
2928 									, fds
2929 								);
2930 							}
2931 							auto app = appender!string();
2932 							formattedWrite(app, 
2933 								"Found a '%s' while looking for", 
2934 								this.lex.front
2935 							);
2936 							throw new ParseException(app.data,
2937 								__FILE__, __LINE__,
2938 								subRules,
2939 								["rcurly"]
2940 							);
2941 
2942 						}
2943 						auto app = appender!string();
2944 						formattedWrite(app, 
2945 							"Found a '%s' while looking for", 
2946 							this.lex.front
2947 						);
2948 						throw new ParseException(app.data,
2949 							__FILE__, __LINE__,
2950 							subRules,
2951 							["name -> FieldDefinition"]
2952 						);
2953 
2954 					}
2955 					auto app = appender!string();
2956 					formattedWrite(app, 
2957 						"Found a '%s' while looking for", 
2958 						this.lex.front
2959 					);
2960 					throw new ParseException(app.data,
2961 						__FILE__, __LINE__,
2962 						subRules,
2963 						["lcurly"]
2964 					);
2965 
2966 				} else if(this.lex.front.type == TokenType.lcurly) {
2967 					this.lex.popFront();
2968 					subRules = ["F"];
2969 					if(this.firstFieldDefinitions()) {
2970 						FieldDefinitions fds = this.parseFieldDefinitions();
2971 						subRules = ["F"];
2972 						if(this.lex.front.type == TokenType.rcurly) {
2973 							this.lex.popFront();
2974 
2975 							return new ObjectTypeDefinition(ObjectTypeDefinitionEnum.F
2976 								, name
2977 								, fds
2978 							);
2979 						}
2980 						auto app = appender!string();
2981 						formattedWrite(app, 
2982 							"Found a '%s' while looking for", 
2983 							this.lex.front
2984 						);
2985 						throw new ParseException(app.data,
2986 							__FILE__, __LINE__,
2987 							subRules,
2988 							["rcurly"]
2989 						);
2990 
2991 					}
2992 					auto app = appender!string();
2993 					formattedWrite(app, 
2994 						"Found a '%s' while looking for", 
2995 						this.lex.front
2996 					);
2997 					throw new ParseException(app.data,
2998 						__FILE__, __LINE__,
2999 						subRules,
3000 						["name -> FieldDefinition"]
3001 					);
3002 
3003 				}
3004 				auto app = appender!string();
3005 				formattedWrite(app, 
3006 					"Found a '%s' while looking for", 
3007 					this.lex.front
3008 				);
3009 				throw new ParseException(app.data,
3010 					__FILE__, __LINE__,
3011 					subRules,
3012 					["implements","at -> Directive","lcurly"]
3013 				);
3014 
3015 			}
3016 			auto app = appender!string();
3017 			formattedWrite(app, 
3018 				"Found a '%s' while looking for", 
3019 				this.lex.front
3020 			);
3021 			throw new ParseException(app.data,
3022 				__FILE__, __LINE__,
3023 				subRules,
3024 				["name"]
3025 			);
3026 
3027 		}
3028 		auto app = appender!string();
3029 		formattedWrite(app, 
3030 			"Found a '%s' while looking for", 
3031 			this.lex.front
3032 		);
3033 		throw new ParseException(app.data,
3034 			__FILE__, __LINE__,
3035 			subRules,
3036 			["type"]
3037 		);
3038 
3039 	}
3040 
3041 	bool firstFieldDefinitions() const pure @nogc @safe {
3042 		return this.firstFieldDefinition();
3043 	}
3044 
3045 	FieldDefinitions parseFieldDefinitions() {
3046 		try {
3047 			return this.parseFieldDefinitionsImpl();
3048 		} catch(ParseException e) {
3049 			throw new ParseException(
3050 				"While parsing a FieldDefinitions an Exception was thrown.",
3051 				e, __FILE__, __LINE__
3052 			);
3053 		}
3054 	}
3055 
3056 	FieldDefinitions parseFieldDefinitionsImpl() {
3057 		string[] subRules;
3058 		subRules = ["F", "FC", "FNC"];
3059 		if(this.firstFieldDefinition()) {
3060 			FieldDefinition fd = this.parseFieldDefinition();
3061 			subRules = ["FC"];
3062 			if(this.lex.front.type == TokenType.comma) {
3063 				this.lex.popFront();
3064 				subRules = ["FC"];
3065 				if(this.firstFieldDefinitions()) {
3066 					FieldDefinitions follow = this.parseFieldDefinitions();
3067 
3068 					return new FieldDefinitions(FieldDefinitionsEnum.FC
3069 						, fd
3070 						, follow
3071 					);
3072 				}
3073 				auto app = appender!string();
3074 				formattedWrite(app, 
3075 					"Found a '%s' while looking for", 
3076 					this.lex.front
3077 				);
3078 				throw new ParseException(app.data,
3079 					__FILE__, __LINE__,
3080 					subRules,
3081 					["name -> FieldDefinition"]
3082 				);
3083 
3084 			} else if(this.firstFieldDefinitions()) {
3085 				FieldDefinitions follow = this.parseFieldDefinitions();
3086 
3087 				return new FieldDefinitions(FieldDefinitionsEnum.FNC
3088 					, fd
3089 					, follow
3090 				);
3091 			}
3092 			return new FieldDefinitions(FieldDefinitionsEnum.F
3093 				, fd
3094 			);
3095 		}
3096 		auto app = appender!string();
3097 		formattedWrite(app, 
3098 			"Found a '%s' while looking for", 
3099 			this.lex.front
3100 		);
3101 		throw new ParseException(app.data,
3102 			__FILE__, __LINE__,
3103 			subRules,
3104 			["name"]
3105 		);
3106 
3107 	}
3108 
3109 	bool firstFieldDefinition() const pure @nogc @safe {
3110 		return this.lex.front.type == TokenType.name;
3111 	}
3112 
3113 	FieldDefinition parseFieldDefinition() {
3114 		try {
3115 			return this.parseFieldDefinitionImpl();
3116 		} catch(ParseException e) {
3117 			throw new ParseException(
3118 				"While parsing a FieldDefinition an Exception was thrown.",
3119 				e, __FILE__, __LINE__
3120 			);
3121 		}
3122 	}
3123 
3124 	FieldDefinition parseFieldDefinitionImpl() {
3125 		string[] subRules;
3126 		subRules = ["A", "AD", "D", "T"];
3127 		if(this.lex.front.type == TokenType.name) {
3128 			Token name = this.lex.front;
3129 			this.lex.popFront();
3130 			subRules = ["A", "AD"];
3131 			if(this.firstArgumentsDefinition()) {
3132 				ArgumentsDefinition arg = this.parseArgumentsDefinition();
3133 				subRules = ["A", "AD"];
3134 				if(this.lex.front.type == TokenType.colon) {
3135 					this.lex.popFront();
3136 					subRules = ["A", "AD"];
3137 					if(this.firstType()) {
3138 						Type typ = this.parseType();
3139 						subRules = ["AD"];
3140 						if(this.firstDirectives()) {
3141 							Directives dir = this.parseDirectives();
3142 
3143 							return new FieldDefinition(FieldDefinitionEnum.AD
3144 								, name
3145 								, arg
3146 								, typ
3147 								, dir
3148 							);
3149 						}
3150 						return new FieldDefinition(FieldDefinitionEnum.A
3151 							, name
3152 							, arg
3153 							, typ
3154 						);
3155 					}
3156 					auto app = appender!string();
3157 					formattedWrite(app, 
3158 						"Found a '%s' while looking for", 
3159 						this.lex.front
3160 					);
3161 					throw new ParseException(app.data,
3162 						__FILE__, __LINE__,
3163 						subRules,
3164 						["lbrack -> ListType","name"]
3165 					);
3166 
3167 				}
3168 				auto app = appender!string();
3169 				formattedWrite(app, 
3170 					"Found a '%s' while looking for", 
3171 					this.lex.front
3172 				);
3173 				throw new ParseException(app.data,
3174 					__FILE__, __LINE__,
3175 					subRules,
3176 					["colon"]
3177 				);
3178 
3179 			} else if(this.lex.front.type == TokenType.colon) {
3180 				this.lex.popFront();
3181 				subRules = ["D", "T"];
3182 				if(this.firstType()) {
3183 					Type typ = this.parseType();
3184 					subRules = ["D"];
3185 					if(this.firstDirectives()) {
3186 						Directives dir = this.parseDirectives();
3187 
3188 						return new FieldDefinition(FieldDefinitionEnum.D
3189 							, name
3190 							, typ
3191 							, dir
3192 						);
3193 					}
3194 					return new FieldDefinition(FieldDefinitionEnum.T
3195 						, name
3196 						, typ
3197 					);
3198 				}
3199 				auto app = appender!string();
3200 				formattedWrite(app, 
3201 					"Found a '%s' while looking for", 
3202 					this.lex.front
3203 				);
3204 				throw new ParseException(app.data,
3205 					__FILE__, __LINE__,
3206 					subRules,
3207 					["lbrack -> ListType","name"]
3208 				);
3209 
3210 			}
3211 			auto app = appender!string();
3212 			formattedWrite(app, 
3213 				"Found a '%s' while looking for", 
3214 				this.lex.front
3215 			);
3216 			throw new ParseException(app.data,
3217 				__FILE__, __LINE__,
3218 				subRules,
3219 				["lparen","colon"]
3220 			);
3221 
3222 		}
3223 		auto app = appender!string();
3224 		formattedWrite(app, 
3225 			"Found a '%s' while looking for", 
3226 			this.lex.front
3227 		);
3228 		throw new ParseException(app.data,
3229 			__FILE__, __LINE__,
3230 			subRules,
3231 			["name"]
3232 		);
3233 
3234 	}
3235 
3236 	bool firstImplementsInterfaces() const pure @nogc @safe {
3237 		return this.lex.front.type == TokenType.implements;
3238 	}
3239 
3240 	ImplementsInterfaces parseImplementsInterfaces() {
3241 		try {
3242 			return this.parseImplementsInterfacesImpl();
3243 		} catch(ParseException e) {
3244 			throw new ParseException(
3245 				"While parsing a ImplementsInterfaces an Exception was thrown.",
3246 				e, __FILE__, __LINE__
3247 			);
3248 		}
3249 	}
3250 
3251 	ImplementsInterfaces parseImplementsInterfacesImpl() {
3252 		string[] subRules;
3253 		subRules = ["N"];
3254 		if(this.lex.front.type == TokenType.implements) {
3255 			this.lex.popFront();
3256 			subRules = ["N"];
3257 			if(this.firstNamedTypes()) {
3258 				NamedTypes nts = this.parseNamedTypes();
3259 
3260 				return new ImplementsInterfaces(ImplementsInterfacesEnum.N
3261 					, nts
3262 				);
3263 			}
3264 			auto app = appender!string();
3265 			formattedWrite(app, 
3266 				"Found a '%s' while looking for", 
3267 				this.lex.front
3268 			);
3269 			throw new ParseException(app.data,
3270 				__FILE__, __LINE__,
3271 				subRules,
3272 				["name"]
3273 			);
3274 
3275 		}
3276 		auto app = appender!string();
3277 		formattedWrite(app, 
3278 			"Found a '%s' while looking for", 
3279 			this.lex.front
3280 		);
3281 		throw new ParseException(app.data,
3282 			__FILE__, __LINE__,
3283 			subRules,
3284 			["implements"]
3285 		);
3286 
3287 	}
3288 
3289 	bool firstNamedTypes() const pure @nogc @safe {
3290 		return this.lex.front.type == TokenType.name;
3291 	}
3292 
3293 	NamedTypes parseNamedTypes() {
3294 		try {
3295 			return this.parseNamedTypesImpl();
3296 		} catch(ParseException e) {
3297 			throw new ParseException(
3298 				"While parsing a NamedTypes an Exception was thrown.",
3299 				e, __FILE__, __LINE__
3300 			);
3301 		}
3302 	}
3303 
3304 	NamedTypes parseNamedTypesImpl() {
3305 		string[] subRules;
3306 		subRules = ["N", "NCS", "NS"];
3307 		if(this.lex.front.type == TokenType.name) {
3308 			Token name = this.lex.front;
3309 			this.lex.popFront();
3310 			subRules = ["NCS"];
3311 			if(this.lex.front.type == TokenType.comma) {
3312 				this.lex.popFront();
3313 				subRules = ["NCS"];
3314 				if(this.firstNamedTypes()) {
3315 					NamedTypes follow = this.parseNamedTypes();
3316 
3317 					return new NamedTypes(NamedTypesEnum.NCS
3318 						, name
3319 						, follow
3320 					);
3321 				}
3322 				auto app = appender!string();
3323 				formattedWrite(app, 
3324 					"Found a '%s' while looking for", 
3325 					this.lex.front
3326 				);
3327 				throw new ParseException(app.data,
3328 					__FILE__, __LINE__,
3329 					subRules,
3330 					["name"]
3331 				);
3332 
3333 			} else if(this.firstNamedTypes()) {
3334 				NamedTypes follow = this.parseNamedTypes();
3335 
3336 				return new NamedTypes(NamedTypesEnum.NS
3337 					, name
3338 					, follow
3339 				);
3340 			}
3341 			return new NamedTypes(NamedTypesEnum.N
3342 				, name
3343 			);
3344 		}
3345 		auto app = appender!string();
3346 		formattedWrite(app, 
3347 			"Found a '%s' while looking for", 
3348 			this.lex.front
3349 		);
3350 		throw new ParseException(app.data,
3351 			__FILE__, __LINE__,
3352 			subRules,
3353 			["name"]
3354 		);
3355 
3356 	}
3357 
3358 	bool firstArgumentsDefinition() const pure @nogc @safe {
3359 		return this.lex.front.type == TokenType.lparen;
3360 	}
3361 
3362 	ArgumentsDefinition parseArgumentsDefinition() {
3363 		try {
3364 			return this.parseArgumentsDefinitionImpl();
3365 		} catch(ParseException e) {
3366 			throw new ParseException(
3367 				"While parsing a ArgumentsDefinition an Exception was thrown.",
3368 				e, __FILE__, __LINE__
3369 			);
3370 		}
3371 	}
3372 
3373 	ArgumentsDefinition parseArgumentsDefinitionImpl() {
3374 		string[] subRules;
3375 		subRules = ["A"];
3376 		if(this.lex.front.type == TokenType.lparen) {
3377 			this.lex.popFront();
3378 			subRules = ["A"];
3379 			if(this.firstInputValueDefinitions()) {
3380 				this.parseInputValueDefinitions();
3381 				subRules = ["A"];
3382 				if(this.lex.front.type == TokenType.rparen) {
3383 					this.lex.popFront();
3384 
3385 					return new ArgumentsDefinition(ArgumentsDefinitionEnum.A
3386 					);
3387 				}
3388 				auto app = appender!string();
3389 				formattedWrite(app, 
3390 					"Found a '%s' while looking for", 
3391 					this.lex.front
3392 				);
3393 				throw new ParseException(app.data,
3394 					__FILE__, __LINE__,
3395 					subRules,
3396 					["rparen"]
3397 				);
3398 
3399 			}
3400 			auto app = appender!string();
3401 			formattedWrite(app, 
3402 				"Found a '%s' while looking for", 
3403 				this.lex.front
3404 			);
3405 			throw new ParseException(app.data,
3406 				__FILE__, __LINE__,
3407 				subRules,
3408 				["name -> InputValueDefinition"]
3409 			);
3410 
3411 		}
3412 		auto app = appender!string();
3413 		formattedWrite(app, 
3414 			"Found a '%s' while looking for", 
3415 			this.lex.front
3416 		);
3417 		throw new ParseException(app.data,
3418 			__FILE__, __LINE__,
3419 			subRules,
3420 			["lparen"]
3421 		);
3422 
3423 	}
3424 
3425 	bool firstInputValueDefinitions() const pure @nogc @safe {
3426 		return this.firstInputValueDefinition();
3427 	}
3428 
3429 	InputValueDefinitions parseInputValueDefinitions() {
3430 		try {
3431 			return this.parseInputValueDefinitionsImpl();
3432 		} catch(ParseException e) {
3433 			throw new ParseException(
3434 				"While parsing a InputValueDefinitions an Exception was thrown.",
3435 				e, __FILE__, __LINE__
3436 			);
3437 		}
3438 	}
3439 
3440 	InputValueDefinitions parseInputValueDefinitionsImpl() {
3441 		string[] subRules;
3442 		subRules = ["I", "ICF", "IF"];
3443 		if(this.firstInputValueDefinition()) {
3444 			InputValueDefinition iv = this.parseInputValueDefinition();
3445 			subRules = ["ICF"];
3446 			if(this.lex.front.type == TokenType.comma) {
3447 				this.lex.popFront();
3448 				subRules = ["ICF"];
3449 				if(this.firstInputValueDefinitions()) {
3450 					InputValueDefinitions follow = this.parseInputValueDefinitions();
3451 
3452 					return new InputValueDefinitions(InputValueDefinitionsEnum.ICF
3453 						, iv
3454 						, follow
3455 					);
3456 				}
3457 				auto app = appender!string();
3458 				formattedWrite(app, 
3459 					"Found a '%s' while looking for", 
3460 					this.lex.front
3461 				);
3462 				throw new ParseException(app.data,
3463 					__FILE__, __LINE__,
3464 					subRules,
3465 					["name -> InputValueDefinition"]
3466 				);
3467 
3468 			} else if(this.firstInputValueDefinitions()) {
3469 				InputValueDefinitions follow = this.parseInputValueDefinitions();
3470 
3471 				return new InputValueDefinitions(InputValueDefinitionsEnum.IF
3472 					, iv
3473 					, follow
3474 				);
3475 			}
3476 			return new InputValueDefinitions(InputValueDefinitionsEnum.I
3477 				, iv
3478 			);
3479 		}
3480 		auto app = appender!string();
3481 		formattedWrite(app, 
3482 			"Found a '%s' while looking for", 
3483 			this.lex.front
3484 		);
3485 		throw new ParseException(app.data,
3486 			__FILE__, __LINE__,
3487 			subRules,
3488 			["name"]
3489 		);
3490 
3491 	}
3492 
3493 	bool firstInputValueDefinition() const pure @nogc @safe {
3494 		return this.lex.front.type == TokenType.name;
3495 	}
3496 
3497 	InputValueDefinition parseInputValueDefinition() {
3498 		try {
3499 			return this.parseInputValueDefinitionImpl();
3500 		} catch(ParseException e) {
3501 			throw new ParseException(
3502 				"While parsing a InputValueDefinition an Exception was thrown.",
3503 				e, __FILE__, __LINE__
3504 			);
3505 		}
3506 	}
3507 
3508 	InputValueDefinition parseInputValueDefinitionImpl() {
3509 		string[] subRules;
3510 		subRules = ["T", "TD", "TV", "TVD"];
3511 		if(this.lex.front.type == TokenType.name) {
3512 			Token name = this.lex.front;
3513 			this.lex.popFront();
3514 			subRules = ["T", "TD", "TV", "TVD"];
3515 			if(this.lex.front.type == TokenType.colon) {
3516 				this.lex.popFront();
3517 				subRules = ["T", "TD", "TV", "TVD"];
3518 				if(this.firstType()) {
3519 					Type type = this.parseType();
3520 					subRules = ["TV", "TVD"];
3521 					if(this.firstDefaultValue()) {
3522 						DefaultValue df = this.parseDefaultValue();
3523 						subRules = ["TVD"];
3524 						if(this.firstDirectives()) {
3525 							Directives dirs = this.parseDirectives();
3526 
3527 							return new InputValueDefinition(InputValueDefinitionEnum.TVD
3528 								, name
3529 								, type
3530 								, df
3531 								, dirs
3532 							);
3533 						}
3534 						return new InputValueDefinition(InputValueDefinitionEnum.TV
3535 							, name
3536 							, type
3537 							, df
3538 						);
3539 					} else if(this.firstDirectives()) {
3540 						Directives dirs = this.parseDirectives();
3541 
3542 						return new InputValueDefinition(InputValueDefinitionEnum.TD
3543 							, name
3544 							, type
3545 							, dirs
3546 						);
3547 					}
3548 					return new InputValueDefinition(InputValueDefinitionEnum.T
3549 						, name
3550 						, type
3551 					);
3552 				}
3553 				auto app = appender!string();
3554 				formattedWrite(app, 
3555 					"Found a '%s' while looking for", 
3556 					this.lex.front
3557 				);
3558 				throw new ParseException(app.data,
3559 					__FILE__, __LINE__,
3560 					subRules,
3561 					["lbrack -> ListType","name"]
3562 				);
3563 
3564 			}
3565 			auto app = appender!string();
3566 			formattedWrite(app, 
3567 				"Found a '%s' while looking for", 
3568 				this.lex.front
3569 			);
3570 			throw new ParseException(app.data,
3571 				__FILE__, __LINE__,
3572 				subRules,
3573 				["colon"]
3574 			);
3575 
3576 		}
3577 		auto app = appender!string();
3578 		formattedWrite(app, 
3579 			"Found a '%s' while looking for", 
3580 			this.lex.front
3581 		);
3582 		throw new ParseException(app.data,
3583 			__FILE__, __LINE__,
3584 			subRules,
3585 			["name"]
3586 		);
3587 
3588 	}
3589 
3590 	bool firstInterfaceTypeDefinition() const pure @nogc @safe {
3591 		return this.lex.front.type == TokenType.interface_;
3592 	}
3593 
3594 	InterfaceTypeDefinition parseInterfaceTypeDefinition() {
3595 		try {
3596 			return this.parseInterfaceTypeDefinitionImpl();
3597 		} catch(ParseException e) {
3598 			throw new ParseException(
3599 				"While parsing a InterfaceTypeDefinition an Exception was thrown.",
3600 				e, __FILE__, __LINE__
3601 			);
3602 		}
3603 	}
3604 
3605 	InterfaceTypeDefinition parseInterfaceTypeDefinitionImpl() {
3606 		string[] subRules;
3607 		subRules = ["NDF", "NF"];
3608 		if(this.lex.front.type == TokenType.interface_) {
3609 			this.lex.popFront();
3610 			subRules = ["NDF", "NF"];
3611 			if(this.lex.front.type == TokenType.name) {
3612 				Token name = this.lex.front;
3613 				this.lex.popFront();
3614 				subRules = ["NDF"];
3615 				if(this.firstDirectives()) {
3616 					Directives dirs = this.parseDirectives();
3617 					subRules = ["NDF"];
3618 					if(this.lex.front.type == TokenType.lcurly) {
3619 						this.lex.popFront();
3620 						subRules = ["NDF"];
3621 						if(this.firstFieldDefinitions()) {
3622 							FieldDefinitions fds = this.parseFieldDefinitions();
3623 							subRules = ["NDF"];
3624 							if(this.lex.front.type == TokenType.rcurly) {
3625 								this.lex.popFront();
3626 
3627 								return new InterfaceTypeDefinition(InterfaceTypeDefinitionEnum.NDF
3628 									, name
3629 									, dirs
3630 									, fds
3631 								);
3632 							}
3633 							auto app = appender!string();
3634 							formattedWrite(app, 
3635 								"Found a '%s' while looking for", 
3636 								this.lex.front
3637 							);
3638 							throw new ParseException(app.data,
3639 								__FILE__, __LINE__,
3640 								subRules,
3641 								["rcurly"]
3642 							);
3643 
3644 						}
3645 						auto app = appender!string();
3646 						formattedWrite(app, 
3647 							"Found a '%s' while looking for", 
3648 							this.lex.front
3649 						);
3650 						throw new ParseException(app.data,
3651 							__FILE__, __LINE__,
3652 							subRules,
3653 							["name -> FieldDefinition"]
3654 						);
3655 
3656 					}
3657 					auto app = appender!string();
3658 					formattedWrite(app, 
3659 						"Found a '%s' while looking for", 
3660 						this.lex.front
3661 					);
3662 					throw new ParseException(app.data,
3663 						__FILE__, __LINE__,
3664 						subRules,
3665 						["lcurly"]
3666 					);
3667 
3668 				} else if(this.lex.front.type == TokenType.lcurly) {
3669 					this.lex.popFront();
3670 					subRules = ["NF"];
3671 					if(this.firstFieldDefinitions()) {
3672 						FieldDefinitions fds = this.parseFieldDefinitions();
3673 						subRules = ["NF"];
3674 						if(this.lex.front.type == TokenType.rcurly) {
3675 							this.lex.popFront();
3676 
3677 							return new InterfaceTypeDefinition(InterfaceTypeDefinitionEnum.NF
3678 								, name
3679 								, fds
3680 							);
3681 						}
3682 						auto app = appender!string();
3683 						formattedWrite(app, 
3684 							"Found a '%s' while looking for", 
3685 							this.lex.front
3686 						);
3687 						throw new ParseException(app.data,
3688 							__FILE__, __LINE__,
3689 							subRules,
3690 							["rcurly"]
3691 						);
3692 
3693 					}
3694 					auto app = appender!string();
3695 					formattedWrite(app, 
3696 						"Found a '%s' while looking for", 
3697 						this.lex.front
3698 					);
3699 					throw new ParseException(app.data,
3700 						__FILE__, __LINE__,
3701 						subRules,
3702 						["name -> FieldDefinition"]
3703 					);
3704 
3705 				}
3706 				auto app = appender!string();
3707 				formattedWrite(app, 
3708 					"Found a '%s' while looking for", 
3709 					this.lex.front
3710 				);
3711 				throw new ParseException(app.data,
3712 					__FILE__, __LINE__,
3713 					subRules,
3714 					["at -> Directive","lcurly"]
3715 				);
3716 
3717 			}
3718 			auto app = appender!string();
3719 			formattedWrite(app, 
3720 				"Found a '%s' while looking for", 
3721 				this.lex.front
3722 			);
3723 			throw new ParseException(app.data,
3724 				__FILE__, __LINE__,
3725 				subRules,
3726 				["name"]
3727 			);
3728 
3729 		}
3730 		auto app = appender!string();
3731 		formattedWrite(app, 
3732 			"Found a '%s' while looking for", 
3733 			this.lex.front
3734 		);
3735 		throw new ParseException(app.data,
3736 			__FILE__, __LINE__,
3737 			subRules,
3738 			["interface_"]
3739 		);
3740 
3741 	}
3742 
3743 	bool firstUnionTypeDefinition() const pure @nogc @safe {
3744 		return this.lex.front.type == TokenType.union_;
3745 	}
3746 
3747 	UnionTypeDefinition parseUnionTypeDefinition() {
3748 		try {
3749 			return this.parseUnionTypeDefinitionImpl();
3750 		} catch(ParseException e) {
3751 			throw new ParseException(
3752 				"While parsing a UnionTypeDefinition an Exception was thrown.",
3753 				e, __FILE__, __LINE__
3754 			);
3755 		}
3756 	}
3757 
3758 	UnionTypeDefinition parseUnionTypeDefinitionImpl() {
3759 		string[] subRules;
3760 		subRules = ["NDU", "NU"];
3761 		if(this.lex.front.type == TokenType.union_) {
3762 			this.lex.popFront();
3763 			subRules = ["NDU", "NU"];
3764 			if(this.lex.front.type == TokenType.name) {
3765 				Token name = this.lex.front;
3766 				this.lex.popFront();
3767 				subRules = ["NDU"];
3768 				if(this.firstDirectives()) {
3769 					Directives dirs = this.parseDirectives();
3770 					subRules = ["NDU"];
3771 					if(this.lex.front.type == TokenType.equal) {
3772 						this.lex.popFront();
3773 						subRules = ["NDU"];
3774 						if(this.firstUnionMembers()) {
3775 							UnionMembers um = this.parseUnionMembers();
3776 
3777 							return new UnionTypeDefinition(UnionTypeDefinitionEnum.NDU
3778 								, name
3779 								, dirs
3780 								, um
3781 							);
3782 						}
3783 						auto app = appender!string();
3784 						formattedWrite(app, 
3785 							"Found a '%s' while looking for", 
3786 							this.lex.front
3787 						);
3788 						throw new ParseException(app.data,
3789 							__FILE__, __LINE__,
3790 							subRules,
3791 							["name"]
3792 						);
3793 
3794 					}
3795 					auto app = appender!string();
3796 					formattedWrite(app, 
3797 						"Found a '%s' while looking for", 
3798 						this.lex.front
3799 					);
3800 					throw new ParseException(app.data,
3801 						__FILE__, __LINE__,
3802 						subRules,
3803 						["equal"]
3804 					);
3805 
3806 				} else if(this.lex.front.type == TokenType.equal) {
3807 					this.lex.popFront();
3808 					subRules = ["NU"];
3809 					if(this.firstUnionMembers()) {
3810 						UnionMembers um = this.parseUnionMembers();
3811 
3812 						return new UnionTypeDefinition(UnionTypeDefinitionEnum.NU
3813 							, name
3814 							, um
3815 						);
3816 					}
3817 					auto app = appender!string();
3818 					formattedWrite(app, 
3819 						"Found a '%s' while looking for", 
3820 						this.lex.front
3821 					);
3822 					throw new ParseException(app.data,
3823 						__FILE__, __LINE__,
3824 						subRules,
3825 						["name"]
3826 					);
3827 
3828 				}
3829 				auto app = appender!string();
3830 				formattedWrite(app, 
3831 					"Found a '%s' while looking for", 
3832 					this.lex.front
3833 				);
3834 				throw new ParseException(app.data,
3835 					__FILE__, __LINE__,
3836 					subRules,
3837 					["at -> Directive","equal"]
3838 				);
3839 
3840 			}
3841 			auto app = appender!string();
3842 			formattedWrite(app, 
3843 				"Found a '%s' while looking for", 
3844 				this.lex.front
3845 			);
3846 			throw new ParseException(app.data,
3847 				__FILE__, __LINE__,
3848 				subRules,
3849 				["name"]
3850 			);
3851 
3852 		}
3853 		auto app = appender!string();
3854 		formattedWrite(app, 
3855 			"Found a '%s' while looking for", 
3856 			this.lex.front
3857 		);
3858 		throw new ParseException(app.data,
3859 			__FILE__, __LINE__,
3860 			subRules,
3861 			["union_"]
3862 		);
3863 
3864 	}
3865 
3866 	bool firstUnionMembers() const pure @nogc @safe {
3867 		return this.lex.front.type == TokenType.name;
3868 	}
3869 
3870 	UnionMembers parseUnionMembers() {
3871 		try {
3872 			return this.parseUnionMembersImpl();
3873 		} catch(ParseException e) {
3874 			throw new ParseException(
3875 				"While parsing a UnionMembers an Exception was thrown.",
3876 				e, __FILE__, __LINE__
3877 			);
3878 		}
3879 	}
3880 
3881 	UnionMembers parseUnionMembersImpl() {
3882 		string[] subRules;
3883 		subRules = ["S", "SF", "SPF"];
3884 		if(this.lex.front.type == TokenType.name) {
3885 			Token name = this.lex.front;
3886 			this.lex.popFront();
3887 			subRules = ["SPF"];
3888 			if(this.lex.front.type == TokenType.pipe) {
3889 				this.lex.popFront();
3890 				subRules = ["SPF"];
3891 				if(this.firstUnionMembers()) {
3892 					UnionMembers follow = this.parseUnionMembers();
3893 
3894 					return new UnionMembers(UnionMembersEnum.SPF
3895 						, name
3896 						, follow
3897 					);
3898 				}
3899 				auto app = appender!string();
3900 				formattedWrite(app, 
3901 					"Found a '%s' while looking for", 
3902 					this.lex.front
3903 				);
3904 				throw new ParseException(app.data,
3905 					__FILE__, __LINE__,
3906 					subRules,
3907 					["name"]
3908 				);
3909 
3910 			} else if(this.firstUnionMembers()) {
3911 				UnionMembers follow = this.parseUnionMembers();
3912 
3913 				return new UnionMembers(UnionMembersEnum.SF
3914 					, name
3915 					, follow
3916 				);
3917 			}
3918 			return new UnionMembers(UnionMembersEnum.S
3919 				, name
3920 			);
3921 		}
3922 		auto app = appender!string();
3923 		formattedWrite(app, 
3924 			"Found a '%s' while looking for", 
3925 			this.lex.front
3926 		);
3927 		throw new ParseException(app.data,
3928 			__FILE__, __LINE__,
3929 			subRules,
3930 			["name"]
3931 		);
3932 
3933 	}
3934 
3935 	bool firstEnumTypeDefinition() const pure @nogc @safe {
3936 		return this.lex.front.type == TokenType.enum_;
3937 	}
3938 
3939 	EnumTypeDefinition parseEnumTypeDefinition() {
3940 		try {
3941 			return this.parseEnumTypeDefinitionImpl();
3942 		} catch(ParseException e) {
3943 			throw new ParseException(
3944 				"While parsing a EnumTypeDefinition an Exception was thrown.",
3945 				e, __FILE__, __LINE__
3946 			);
3947 		}
3948 	}
3949 
3950 	EnumTypeDefinition parseEnumTypeDefinitionImpl() {
3951 		string[] subRules;
3952 		subRules = ["NDE", "NE"];
3953 		if(this.lex.front.type == TokenType.enum_) {
3954 			this.lex.popFront();
3955 			subRules = ["NDE", "NE"];
3956 			if(this.lex.front.type == TokenType.name) {
3957 				Token name = this.lex.front;
3958 				this.lex.popFront();
3959 				subRules = ["NDE"];
3960 				if(this.firstDirectives()) {
3961 					Directives dir = this.parseDirectives();
3962 					subRules = ["NDE"];
3963 					if(this.lex.front.type == TokenType.lcurly) {
3964 						this.lex.popFront();
3965 						subRules = ["NDE"];
3966 						if(this.firstEnumValueDefinitions()) {
3967 							EnumValueDefinitions evds = this.parseEnumValueDefinitions();
3968 							subRules = ["NDE"];
3969 							if(this.lex.front.type == TokenType.rcurly) {
3970 								this.lex.popFront();
3971 
3972 								return new EnumTypeDefinition(EnumTypeDefinitionEnum.NDE
3973 									, name
3974 									, dir
3975 									, evds
3976 								);
3977 							}
3978 							auto app = appender!string();
3979 							formattedWrite(app, 
3980 								"Found a '%s' while looking for", 
3981 								this.lex.front
3982 							);
3983 							throw new ParseException(app.data,
3984 								__FILE__, __LINE__,
3985 								subRules,
3986 								["rcurly"]
3987 							);
3988 
3989 						}
3990 						auto app = appender!string();
3991 						formattedWrite(app, 
3992 							"Found a '%s' while looking for", 
3993 							this.lex.front
3994 						);
3995 						throw new ParseException(app.data,
3996 							__FILE__, __LINE__,
3997 							subRules,
3998 							["name -> EnumValueDefinition"]
3999 						);
4000 
4001 					}
4002 					auto app = appender!string();
4003 					formattedWrite(app, 
4004 						"Found a '%s' while looking for", 
4005 						this.lex.front
4006 					);
4007 					throw new ParseException(app.data,
4008 						__FILE__, __LINE__,
4009 						subRules,
4010 						["lcurly"]
4011 					);
4012 
4013 				} else if(this.lex.front.type == TokenType.lcurly) {
4014 					this.lex.popFront();
4015 					subRules = ["NE"];
4016 					if(this.firstEnumValueDefinitions()) {
4017 						EnumValueDefinitions evds = this.parseEnumValueDefinitions();
4018 						subRules = ["NE"];
4019 						if(this.lex.front.type == TokenType.rcurly) {
4020 							this.lex.popFront();
4021 
4022 							return new EnumTypeDefinition(EnumTypeDefinitionEnum.NE
4023 								, name
4024 								, evds
4025 							);
4026 						}
4027 						auto app = appender!string();
4028 						formattedWrite(app, 
4029 							"Found a '%s' while looking for", 
4030 							this.lex.front
4031 						);
4032 						throw new ParseException(app.data,
4033 							__FILE__, __LINE__,
4034 							subRules,
4035 							["rcurly"]
4036 						);
4037 
4038 					}
4039 					auto app = appender!string();
4040 					formattedWrite(app, 
4041 						"Found a '%s' while looking for", 
4042 						this.lex.front
4043 					);
4044 					throw new ParseException(app.data,
4045 						__FILE__, __LINE__,
4046 						subRules,
4047 						["name -> EnumValueDefinition"]
4048 					);
4049 
4050 				}
4051 				auto app = appender!string();
4052 				formattedWrite(app, 
4053 					"Found a '%s' while looking for", 
4054 					this.lex.front
4055 				);
4056 				throw new ParseException(app.data,
4057 					__FILE__, __LINE__,
4058 					subRules,
4059 					["at -> Directive","lcurly"]
4060 				);
4061 
4062 			}
4063 			auto app = appender!string();
4064 			formattedWrite(app, 
4065 				"Found a '%s' while looking for", 
4066 				this.lex.front
4067 			);
4068 			throw new ParseException(app.data,
4069 				__FILE__, __LINE__,
4070 				subRules,
4071 				["name"]
4072 			);
4073 
4074 		}
4075 		auto app = appender!string();
4076 		formattedWrite(app, 
4077 			"Found a '%s' while looking for", 
4078 			this.lex.front
4079 		);
4080 		throw new ParseException(app.data,
4081 			__FILE__, __LINE__,
4082 			subRules,
4083 			["enum_"]
4084 		);
4085 
4086 	}
4087 
4088 	bool firstEnumValueDefinitions() const pure @nogc @safe {
4089 		return this.firstEnumValueDefinition();
4090 	}
4091 
4092 	EnumValueDefinitions parseEnumValueDefinitions() {
4093 		try {
4094 			return this.parseEnumValueDefinitionsImpl();
4095 		} catch(ParseException e) {
4096 			throw new ParseException(
4097 				"While parsing a EnumValueDefinitions an Exception was thrown.",
4098 				e, __FILE__, __LINE__
4099 			);
4100 		}
4101 	}
4102 
4103 	EnumValueDefinitions parseEnumValueDefinitionsImpl() {
4104 		string[] subRules;
4105 		subRules = ["D", "DCE", "DE"];
4106 		if(this.firstEnumValueDefinition()) {
4107 			EnumValueDefinition evd = this.parseEnumValueDefinition();
4108 			subRules = ["DCE"];
4109 			if(this.lex.front.type == TokenType.comma) {
4110 				this.lex.popFront();
4111 				subRules = ["DCE"];
4112 				if(this.firstEnumValueDefinitions()) {
4113 					EnumValueDefinitions follow = this.parseEnumValueDefinitions();
4114 
4115 					return new EnumValueDefinitions(EnumValueDefinitionsEnum.DCE
4116 						, evd
4117 						, follow
4118 					);
4119 				}
4120 				auto app = appender!string();
4121 				formattedWrite(app, 
4122 					"Found a '%s' while looking for", 
4123 					this.lex.front
4124 				);
4125 				throw new ParseException(app.data,
4126 					__FILE__, __LINE__,
4127 					subRules,
4128 					["name -> EnumValueDefinition"]
4129 				);
4130 
4131 			} else if(this.firstEnumValueDefinitions()) {
4132 				EnumValueDefinitions follow = this.parseEnumValueDefinitions();
4133 
4134 				return new EnumValueDefinitions(EnumValueDefinitionsEnum.DE
4135 					, evd
4136 					, follow
4137 				);
4138 			}
4139 			return new EnumValueDefinitions(EnumValueDefinitionsEnum.D
4140 				, evd
4141 			);
4142 		}
4143 		auto app = appender!string();
4144 		formattedWrite(app, 
4145 			"Found a '%s' while looking for", 
4146 			this.lex.front
4147 		);
4148 		throw new ParseException(app.data,
4149 			__FILE__, __LINE__,
4150 			subRules,
4151 			["name"]
4152 		);
4153 
4154 	}
4155 
4156 	bool firstEnumValueDefinition() const pure @nogc @safe {
4157 		return this.lex.front.type == TokenType.name;
4158 	}
4159 
4160 	EnumValueDefinition parseEnumValueDefinition() {
4161 		try {
4162 			return this.parseEnumValueDefinitionImpl();
4163 		} catch(ParseException e) {
4164 			throw new ParseException(
4165 				"While parsing a EnumValueDefinition an Exception was thrown.",
4166 				e, __FILE__, __LINE__
4167 			);
4168 		}
4169 	}
4170 
4171 	EnumValueDefinition parseEnumValueDefinitionImpl() {
4172 		string[] subRules;
4173 		subRules = ["E", "ED"];
4174 		if(this.lex.front.type == TokenType.name) {
4175 			Token name = this.lex.front;
4176 			this.lex.popFront();
4177 			subRules = ["ED"];
4178 			if(this.firstDirectives()) {
4179 				Directives dirs = this.parseDirectives();
4180 
4181 				return new EnumValueDefinition(EnumValueDefinitionEnum.ED
4182 					, name
4183 					, dirs
4184 				);
4185 			}
4186 			return new EnumValueDefinition(EnumValueDefinitionEnum.E
4187 				, name
4188 			);
4189 		}
4190 		auto app = appender!string();
4191 		formattedWrite(app, 
4192 			"Found a '%s' while looking for", 
4193 			this.lex.front
4194 		);
4195 		throw new ParseException(app.data,
4196 			__FILE__, __LINE__,
4197 			subRules,
4198 			["name"]
4199 		);
4200 
4201 	}
4202 
4203 	bool firstInputTypeDefinition() const pure @nogc @safe {
4204 		return this.lex.front.type == TokenType.input;
4205 	}
4206 
4207 	InputTypeDefinition parseInputTypeDefinition() {
4208 		try {
4209 			return this.parseInputTypeDefinitionImpl();
4210 		} catch(ParseException e) {
4211 			throw new ParseException(
4212 				"While parsing a InputTypeDefinition an Exception was thrown.",
4213 				e, __FILE__, __LINE__
4214 			);
4215 		}
4216 	}
4217 
4218 	InputTypeDefinition parseInputTypeDefinitionImpl() {
4219 		string[] subRules;
4220 		subRules = ["NDE", "NE"];
4221 		if(this.lex.front.type == TokenType.input) {
4222 			this.lex.popFront();
4223 			subRules = ["NDE", "NE"];
4224 			if(this.lex.front.type == TokenType.name) {
4225 				Token name = this.lex.front;
4226 				this.lex.popFront();
4227 				subRules = ["NDE"];
4228 				if(this.firstDirectives()) {
4229 					Directives dir = this.parseDirectives();
4230 					subRules = ["NDE"];
4231 					if(this.lex.front.type == TokenType.lcurly) {
4232 						this.lex.popFront();
4233 						subRules = ["NDE"];
4234 						if(this.firstInputValueDefinitions()) {
4235 							InputValueDefinitions ivds = this.parseInputValueDefinitions();
4236 							subRules = ["NDE"];
4237 							if(this.lex.front.type == TokenType.rcurly) {
4238 								this.lex.popFront();
4239 
4240 								return new InputTypeDefinition(InputTypeDefinitionEnum.NDE
4241 									, name
4242 									, dir
4243 									, ivds
4244 								);
4245 							}
4246 							auto app = appender!string();
4247 							formattedWrite(app, 
4248 								"Found a '%s' while looking for", 
4249 								this.lex.front
4250 							);
4251 							throw new ParseException(app.data,
4252 								__FILE__, __LINE__,
4253 								subRules,
4254 								["rcurly"]
4255 							);
4256 
4257 						}
4258 						auto app = appender!string();
4259 						formattedWrite(app, 
4260 							"Found a '%s' while looking for", 
4261 							this.lex.front
4262 						);
4263 						throw new ParseException(app.data,
4264 							__FILE__, __LINE__,
4265 							subRules,
4266 							["name -> InputValueDefinition"]
4267 						);
4268 
4269 					}
4270 					auto app = appender!string();
4271 					formattedWrite(app, 
4272 						"Found a '%s' while looking for", 
4273 						this.lex.front
4274 					);
4275 					throw new ParseException(app.data,
4276 						__FILE__, __LINE__,
4277 						subRules,
4278 						["lcurly"]
4279 					);
4280 
4281 				} else if(this.lex.front.type == TokenType.lcurly) {
4282 					this.lex.popFront();
4283 					subRules = ["NE"];
4284 					if(this.firstInputValueDefinitions()) {
4285 						InputValueDefinitions ivds = this.parseInputValueDefinitions();
4286 						subRules = ["NE"];
4287 						if(this.lex.front.type == TokenType.rcurly) {
4288 							this.lex.popFront();
4289 
4290 							return new InputTypeDefinition(InputTypeDefinitionEnum.NE
4291 								, name
4292 								, ivds
4293 							);
4294 						}
4295 						auto app = appender!string();
4296 						formattedWrite(app, 
4297 							"Found a '%s' while looking for", 
4298 							this.lex.front
4299 						);
4300 						throw new ParseException(app.data,
4301 							__FILE__, __LINE__,
4302 							subRules,
4303 							["rcurly"]
4304 						);
4305 
4306 					}
4307 					auto app = appender!string();
4308 					formattedWrite(app, 
4309 						"Found a '%s' while looking for", 
4310 						this.lex.front
4311 					);
4312 					throw new ParseException(app.data,
4313 						__FILE__, __LINE__,
4314 						subRules,
4315 						["name -> InputValueDefinition"]
4316 					);
4317 
4318 				}
4319 				auto app = appender!string();
4320 				formattedWrite(app, 
4321 					"Found a '%s' while looking for", 
4322 					this.lex.front
4323 				);
4324 				throw new ParseException(app.data,
4325 					__FILE__, __LINE__,
4326 					subRules,
4327 					["at -> Directive","lcurly"]
4328 				);
4329 
4330 			}
4331 			auto app = appender!string();
4332 			formattedWrite(app, 
4333 				"Found a '%s' while looking for", 
4334 				this.lex.front
4335 			);
4336 			throw new ParseException(app.data,
4337 				__FILE__, __LINE__,
4338 				subRules,
4339 				["name"]
4340 			);
4341 
4342 		}
4343 		auto app = appender!string();
4344 		formattedWrite(app, 
4345 			"Found a '%s' while looking for", 
4346 			this.lex.front
4347 		);
4348 		throw new ParseException(app.data,
4349 			__FILE__, __LINE__,
4350 			subRules,
4351 			["input"]
4352 		);
4353 
4354 	}
4355 
4356 	bool firstTypeExtensionDefinition() const pure @nogc @safe {
4357 		return this.lex.front.type == TokenType.extend;
4358 	}
4359 
4360 	TypeExtensionDefinition parseTypeExtensionDefinition() {
4361 		try {
4362 			return this.parseTypeExtensionDefinitionImpl();
4363 		} catch(ParseException e) {
4364 			throw new ParseException(
4365 				"While parsing a TypeExtensionDefinition an Exception was thrown.",
4366 				e, __FILE__, __LINE__
4367 			);
4368 		}
4369 	}
4370 
4371 	TypeExtensionDefinition parseTypeExtensionDefinitionImpl() {
4372 		string[] subRules;
4373 		subRules = ["O"];
4374 		if(this.lex.front.type == TokenType.extend) {
4375 			this.lex.popFront();
4376 			subRules = ["O"];
4377 			if(this.firstObjectTypeDefinition()) {
4378 				ObjectTypeDefinition otd = this.parseObjectTypeDefinition();
4379 
4380 				return new TypeExtensionDefinition(TypeExtensionDefinitionEnum.O
4381 					, otd
4382 				);
4383 			}
4384 			auto app = appender!string();
4385 			formattedWrite(app, 
4386 				"Found a '%s' while looking for", 
4387 				this.lex.front
4388 			);
4389 			throw new ParseException(app.data,
4390 				__FILE__, __LINE__,
4391 				subRules,
4392 				["type"]
4393 			);
4394 
4395 		}
4396 		auto app = appender!string();
4397 		formattedWrite(app, 
4398 			"Found a '%s' while looking for", 
4399 			this.lex.front
4400 		);
4401 		throw new ParseException(app.data,
4402 			__FILE__, __LINE__,
4403 			subRules,
4404 			["extend"]
4405 		);
4406 
4407 	}
4408 
4409 	bool firstDirectiveDefinition() const pure @nogc @safe {
4410 		return this.lex.front.type == TokenType.directive;
4411 	}
4412 
4413 	DirectiveDefinition parseDirectiveDefinition() {
4414 		try {
4415 			return this.parseDirectiveDefinitionImpl();
4416 		} catch(ParseException e) {
4417 			throw new ParseException(
4418 				"While parsing a DirectiveDefinition an Exception was thrown.",
4419 				e, __FILE__, __LINE__
4420 			);
4421 		}
4422 	}
4423 
4424 	DirectiveDefinition parseDirectiveDefinitionImpl() {
4425 		string[] subRules;
4426 		subRules = ["AD", "D"];
4427 		if(this.lex.front.type == TokenType.directive) {
4428 			this.lex.popFront();
4429 			subRules = ["AD", "D"];
4430 			if(this.lex.front.type == TokenType.at) {
4431 				this.lex.popFront();
4432 				subRules = ["AD", "D"];
4433 				if(this.lex.front.type == TokenType.name) {
4434 					Token name = this.lex.front;
4435 					this.lex.popFront();
4436 					subRules = ["AD"];
4437 					if(this.firstArgumentsDefinition()) {
4438 						ArgumentsDefinition ad = this.parseArgumentsDefinition();
4439 						subRules = ["AD"];
4440 						if(this.lex.front.type == TokenType.on_) {
4441 							this.lex.popFront();
4442 							subRules = ["AD"];
4443 							if(this.firstDirectiveLocations()) {
4444 								DirectiveLocations dl = this.parseDirectiveLocations();
4445 
4446 								return new DirectiveDefinition(DirectiveDefinitionEnum.AD
4447 									, name
4448 									, ad
4449 									, dl
4450 								);
4451 							}
4452 							auto app = appender!string();
4453 							formattedWrite(app, 
4454 								"Found a '%s' while looking for", 
4455 								this.lex.front
4456 							);
4457 							throw new ParseException(app.data,
4458 								__FILE__, __LINE__,
4459 								subRules,
4460 								["name"]
4461 							);
4462 
4463 						}
4464 						auto app = appender!string();
4465 						formattedWrite(app, 
4466 							"Found a '%s' while looking for", 
4467 							this.lex.front
4468 						);
4469 						throw new ParseException(app.data,
4470 							__FILE__, __LINE__,
4471 							subRules,
4472 							["on_"]
4473 						);
4474 
4475 					} else if(this.lex.front.type == TokenType.on_) {
4476 						this.lex.popFront();
4477 						subRules = ["D"];
4478 						if(this.firstDirectiveLocations()) {
4479 							DirectiveLocations dl = this.parseDirectiveLocations();
4480 
4481 							return new DirectiveDefinition(DirectiveDefinitionEnum.D
4482 								, name
4483 								, dl
4484 							);
4485 						}
4486 						auto app = appender!string();
4487 						formattedWrite(app, 
4488 							"Found a '%s' while looking for", 
4489 							this.lex.front
4490 						);
4491 						throw new ParseException(app.data,
4492 							__FILE__, __LINE__,
4493 							subRules,
4494 							["name"]
4495 						);
4496 
4497 					}
4498 					auto app = appender!string();
4499 					formattedWrite(app, 
4500 						"Found a '%s' while looking for", 
4501 						this.lex.front
4502 					);
4503 					throw new ParseException(app.data,
4504 						__FILE__, __LINE__,
4505 						subRules,
4506 						["lparen","on_"]
4507 					);
4508 
4509 				}
4510 				auto app = appender!string();
4511 				formattedWrite(app, 
4512 					"Found a '%s' while looking for", 
4513 					this.lex.front
4514 				);
4515 				throw new ParseException(app.data,
4516 					__FILE__, __LINE__,
4517 					subRules,
4518 					["name"]
4519 				);
4520 
4521 			}
4522 			auto app = appender!string();
4523 			formattedWrite(app, 
4524 				"Found a '%s' while looking for", 
4525 				this.lex.front
4526 			);
4527 			throw new ParseException(app.data,
4528 				__FILE__, __LINE__,
4529 				subRules,
4530 				["at"]
4531 			);
4532 
4533 		}
4534 		auto app = appender!string();
4535 		formattedWrite(app, 
4536 			"Found a '%s' while looking for", 
4537 			this.lex.front
4538 		);
4539 		throw new ParseException(app.data,
4540 			__FILE__, __LINE__,
4541 			subRules,
4542 			["directive"]
4543 		);
4544 
4545 	}
4546 
4547 	bool firstDirectiveLocations() const pure @nogc @safe {
4548 		return this.lex.front.type == TokenType.name;
4549 	}
4550 
4551 	DirectiveLocations parseDirectiveLocations() {
4552 		try {
4553 			return this.parseDirectiveLocationsImpl();
4554 		} catch(ParseException e) {
4555 			throw new ParseException(
4556 				"While parsing a DirectiveLocations an Exception was thrown.",
4557 				e, __FILE__, __LINE__
4558 			);
4559 		}
4560 	}
4561 
4562 	DirectiveLocations parseDirectiveLocationsImpl() {
4563 		string[] subRules;
4564 		subRules = ["N", "NF", "NPF"];
4565 		if(this.lex.front.type == TokenType.name) {
4566 			Token name = this.lex.front;
4567 			this.lex.popFront();
4568 			subRules = ["NPF"];
4569 			if(this.lex.front.type == TokenType.pipe) {
4570 				this.lex.popFront();
4571 				subRules = ["NPF"];
4572 				if(this.firstDirectiveLocations()) {
4573 					DirectiveLocations follow = this.parseDirectiveLocations();
4574 
4575 					return new DirectiveLocations(DirectiveLocationsEnum.NPF
4576 						, name
4577 						, follow
4578 					);
4579 				}
4580 				auto app = appender!string();
4581 				formattedWrite(app, 
4582 					"Found a '%s' while looking for", 
4583 					this.lex.front
4584 				);
4585 				throw new ParseException(app.data,
4586 					__FILE__, __LINE__,
4587 					subRules,
4588 					["name"]
4589 				);
4590 
4591 			} else if(this.firstDirectiveLocations()) {
4592 				DirectiveLocations follow = this.parseDirectiveLocations();
4593 
4594 				return new DirectiveLocations(DirectiveLocationsEnum.NF
4595 					, name
4596 					, follow
4597 				);
4598 			}
4599 			return new DirectiveLocations(DirectiveLocationsEnum.N
4600 				, name
4601 			);
4602 		}
4603 		auto app = appender!string();
4604 		formattedWrite(app, 
4605 			"Found a '%s' while looking for", 
4606 			this.lex.front
4607 		);
4608 		throw new ParseException(app.data,
4609 			__FILE__, __LINE__,
4610 			subRules,
4611 			["name"]
4612 		);
4613 
4614 	}
4615 
4616 	bool firstInputObjectTypeDefinition() const pure @nogc @safe {
4617 		return this.lex.front.type == TokenType.input;
4618 	}
4619 
4620 	InputObjectTypeDefinition parseInputObjectTypeDefinition() {
4621 		try {
4622 			return this.parseInputObjectTypeDefinitionImpl();
4623 		} catch(ParseException e) {
4624 			throw new ParseException(
4625 				"While parsing a InputObjectTypeDefinition an Exception was thrown.",
4626 				e, __FILE__, __LINE__
4627 			);
4628 		}
4629 	}
4630 
4631 	InputObjectTypeDefinition parseInputObjectTypeDefinitionImpl() {
4632 		string[] subRules;
4633 		subRules = ["NDI", "NI"];
4634 		if(this.lex.front.type == TokenType.input) {
4635 			this.lex.popFront();
4636 			subRules = ["NDI", "NI"];
4637 			if(this.lex.front.type == TokenType.name) {
4638 				Token name = this.lex.front;
4639 				this.lex.popFront();
4640 				subRules = ["NDI"];
4641 				if(this.firstDirectives()) {
4642 					Directives dirs = this.parseDirectives();
4643 					subRules = ["NDI"];
4644 					if(this.lex.front.type == TokenType.lcurly) {
4645 						this.lex.popFront();
4646 						subRules = ["NDI"];
4647 						if(this.firstInputValueDefinitions()) {
4648 							this.parseInputValueDefinitions();
4649 							subRules = ["NDI"];
4650 							if(this.lex.front.type == TokenType.rcurly) {
4651 								this.lex.popFront();
4652 
4653 								return new InputObjectTypeDefinition(InputObjectTypeDefinitionEnum.NDI
4654 									, name
4655 									, dirs
4656 								);
4657 							}
4658 							auto app = appender!string();
4659 							formattedWrite(app, 
4660 								"Found a '%s' while looking for", 
4661 								this.lex.front
4662 							);
4663 							throw new ParseException(app.data,
4664 								__FILE__, __LINE__,
4665 								subRules,
4666 								["rcurly"]
4667 							);
4668 
4669 						}
4670 						auto app = appender!string();
4671 						formattedWrite(app, 
4672 							"Found a '%s' while looking for", 
4673 							this.lex.front
4674 						);
4675 						throw new ParseException(app.data,
4676 							__FILE__, __LINE__,
4677 							subRules,
4678 							["name -> InputValueDefinition"]
4679 						);
4680 
4681 					}
4682 					auto app = appender!string();
4683 					formattedWrite(app, 
4684 						"Found a '%s' while looking for", 
4685 						this.lex.front
4686 					);
4687 					throw new ParseException(app.data,
4688 						__FILE__, __LINE__,
4689 						subRules,
4690 						["lcurly"]
4691 					);
4692 
4693 				} else if(this.lex.front.type == TokenType.lcurly) {
4694 					this.lex.popFront();
4695 					subRules = ["NI"];
4696 					if(this.firstInputValueDefinitions()) {
4697 						this.parseInputValueDefinitions();
4698 						subRules = ["NI"];
4699 						if(this.lex.front.type == TokenType.rcurly) {
4700 							this.lex.popFront();
4701 
4702 							return new InputObjectTypeDefinition(InputObjectTypeDefinitionEnum.NI
4703 								, name
4704 							);
4705 						}
4706 						auto app = appender!string();
4707 						formattedWrite(app, 
4708 							"Found a '%s' while looking for", 
4709 							this.lex.front
4710 						);
4711 						throw new ParseException(app.data,
4712 							__FILE__, __LINE__,
4713 							subRules,
4714 							["rcurly"]
4715 						);
4716 
4717 					}
4718 					auto app = appender!string();
4719 					formattedWrite(app, 
4720 						"Found a '%s' while looking for", 
4721 						this.lex.front
4722 					);
4723 					throw new ParseException(app.data,
4724 						__FILE__, __LINE__,
4725 						subRules,
4726 						["name -> InputValueDefinition"]
4727 					);
4728 
4729 				}
4730 				auto app = appender!string();
4731 				formattedWrite(app, 
4732 					"Found a '%s' while looking for", 
4733 					this.lex.front
4734 				);
4735 				throw new ParseException(app.data,
4736 					__FILE__, __LINE__,
4737 					subRules,
4738 					["at -> Directive","lcurly"]
4739 				);
4740 
4741 			}
4742 			auto app = appender!string();
4743 			formattedWrite(app, 
4744 				"Found a '%s' while looking for", 
4745 				this.lex.front
4746 			);
4747 			throw new ParseException(app.data,
4748 				__FILE__, __LINE__,
4749 				subRules,
4750 				["name"]
4751 			);
4752 
4753 		}
4754 		auto app = appender!string();
4755 		formattedWrite(app, 
4756 			"Found a '%s' while looking for", 
4757 			this.lex.front
4758 		);
4759 		throw new ParseException(app.data,
4760 			__FILE__, __LINE__,
4761 			subRules,
4762 			["input"]
4763 		);
4764 
4765 	}
4766 
4767 }