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 			Variable var = 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 							, var
1593 							, type
1594 							, dvalue
1595 						);
1596 					}
1597 					return new VariableDefinition(VariableDefinitionEnum.Var
1598 						, var
1599 						, type
1600 					);
1601 				}
1602 				auto app = appender!string();
1603 				formattedWrite(app, 
1604 					"Found a '%s' while looking for", 
1605 					this.lex.front
1606 				);
1607 				throw new ParseException(app.data,
1608 					__FILE__, __LINE__,
1609 					subRules,
1610 					["lbrack -> ListType","name"]
1611 				);
1612 
1613 			}
1614 			auto app = appender!string();
1615 			formattedWrite(app, 
1616 				"Found a '%s' while looking for", 
1617 				this.lex.front
1618 			);
1619 			throw new ParseException(app.data,
1620 				__FILE__, __LINE__,
1621 				subRules,
1622 				["colon"]
1623 			);
1624 
1625 		}
1626 		auto app = appender!string();
1627 		formattedWrite(app, 
1628 			"Found a '%s' while looking for", 
1629 			this.lex.front
1630 		);
1631 		throw new ParseException(app.data,
1632 			__FILE__, __LINE__,
1633 			subRules,
1634 			["dollar"]
1635 		);
1636 
1637 	}
1638 
1639 	bool firstVariable() const pure @nogc @safe {
1640 		return this.lex.front.type == TokenType.dollar;
1641 	}
1642 
1643 	Variable parseVariable() {
1644 		try {
1645 			return this.parseVariableImpl();
1646 		} catch(ParseException e) {
1647 			throw new ParseException(
1648 				"While parsing a Variable an Exception was thrown.",
1649 				e, __FILE__, __LINE__
1650 			);
1651 		}
1652 	}
1653 
1654 	Variable parseVariableImpl() {
1655 		string[] subRules;
1656 		subRules = ["Var"];
1657 		if(this.lex.front.type == TokenType.dollar) {
1658 			this.lex.popFront();
1659 			subRules = ["Var"];
1660 			if(this.lex.front.type == TokenType.name) {
1661 				Token name = this.lex.front;
1662 				this.lex.popFront();
1663 
1664 				return new Variable(VariableEnum.Var
1665 					, name
1666 				);
1667 			}
1668 			auto app = appender!string();
1669 			formattedWrite(app, 
1670 				"Found a '%s' while looking for", 
1671 				this.lex.front
1672 			);
1673 			throw new ParseException(app.data,
1674 				__FILE__, __LINE__,
1675 				subRules,
1676 				["name"]
1677 			);
1678 
1679 		}
1680 		auto app = appender!string();
1681 		formattedWrite(app, 
1682 			"Found a '%s' while looking for", 
1683 			this.lex.front
1684 		);
1685 		throw new ParseException(app.data,
1686 			__FILE__, __LINE__,
1687 			subRules,
1688 			["dollar"]
1689 		);
1690 
1691 	}
1692 
1693 	bool firstDefaultValue() const pure @nogc @safe {
1694 		return this.lex.front.type == TokenType.equal;
1695 	}
1696 
1697 	DefaultValue parseDefaultValue() {
1698 		try {
1699 			return this.parseDefaultValueImpl();
1700 		} catch(ParseException e) {
1701 			throw new ParseException(
1702 				"While parsing a DefaultValue an Exception was thrown.",
1703 				e, __FILE__, __LINE__
1704 			);
1705 		}
1706 	}
1707 
1708 	DefaultValue parseDefaultValueImpl() {
1709 		string[] subRules;
1710 		subRules = ["DV"];
1711 		if(this.lex.front.type == TokenType.equal) {
1712 			this.lex.popFront();
1713 			subRules = ["DV"];
1714 			if(this.firstValue()) {
1715 				Value value = this.parseValue();
1716 
1717 				return new DefaultValue(DefaultValueEnum.DV
1718 					, value
1719 				);
1720 			}
1721 			auto app = appender!string();
1722 			formattedWrite(app, 
1723 				"Found a '%s' while looking for", 
1724 				this.lex.front
1725 			);
1726 			throw new ParseException(app.data,
1727 				__FILE__, __LINE__,
1728 				subRules,
1729 				["false_","floatValue","intValue","lbrack -> Array","lcurly -> ObjectType","name","stringValue","true_"]
1730 			);
1731 
1732 		}
1733 		auto app = appender!string();
1734 		formattedWrite(app, 
1735 			"Found a '%s' while looking for", 
1736 			this.lex.front
1737 		);
1738 		throw new ParseException(app.data,
1739 			__FILE__, __LINE__,
1740 			subRules,
1741 			["equal"]
1742 		);
1743 
1744 	}
1745 
1746 	bool firstValueOrVariable() const pure @nogc @safe {
1747 		return this.firstValue()
1748 			 || this.firstVariable();
1749 	}
1750 
1751 	ValueOrVariable parseValueOrVariable() {
1752 		try {
1753 			return this.parseValueOrVariableImpl();
1754 		} catch(ParseException e) {
1755 			throw new ParseException(
1756 				"While parsing a ValueOrVariable an Exception was thrown.",
1757 				e, __FILE__, __LINE__
1758 			);
1759 		}
1760 	}
1761 
1762 	ValueOrVariable parseValueOrVariableImpl() {
1763 		string[] subRules;
1764 		subRules = ["Val"];
1765 		if(this.firstValue()) {
1766 			Value val = this.parseValue();
1767 
1768 			return new ValueOrVariable(ValueOrVariableEnum.Val
1769 				, val
1770 			);
1771 		} else if(this.firstVariable()) {
1772 			Variable var = this.parseVariable();
1773 
1774 			return new ValueOrVariable(ValueOrVariableEnum.Var
1775 				, var
1776 			);
1777 		}
1778 		auto app = appender!string();
1779 		formattedWrite(app, 
1780 			"Found a '%s' while looking for", 
1781 			this.lex.front
1782 		);
1783 		throw new ParseException(app.data,
1784 			__FILE__, __LINE__,
1785 			subRules,
1786 			["false_","floatValue","intValue","lbrack -> Array","lcurly -> ObjectType","name","stringValue","true_","dollar"]
1787 		);
1788 
1789 	}
1790 
1791 	bool firstValue() const pure @nogc @safe {
1792 		return this.lex.front.type == TokenType.stringValue
1793 			 || this.lex.front.type == TokenType.intValue
1794 			 || this.lex.front.type == TokenType.floatValue
1795 			 || this.lex.front.type == TokenType.true_
1796 			 || this.lex.front.type == TokenType.false_
1797 			 || this.firstArray()
1798 			 || this.firstObjectType()
1799 			 || this.lex.front.type == TokenType.name;
1800 	}
1801 
1802 	Value parseValue() {
1803 		try {
1804 			return this.parseValueImpl();
1805 		} catch(ParseException e) {
1806 			throw new ParseException(
1807 				"While parsing a Value an Exception was thrown.",
1808 				e, __FILE__, __LINE__
1809 			);
1810 		}
1811 	}
1812 
1813 	Value parseValueImpl() {
1814 		string[] subRules;
1815 		subRules = ["STR"];
1816 		if(this.lex.front.type == TokenType.stringValue) {
1817 			Token tok = this.lex.front;
1818 			this.lex.popFront();
1819 
1820 			return new Value(ValueEnum.STR
1821 				, tok
1822 			);
1823 		} else if(this.lex.front.type == TokenType.intValue) {
1824 			Token tok = this.lex.front;
1825 			this.lex.popFront();
1826 
1827 			return new Value(ValueEnum.INT
1828 				, tok
1829 			);
1830 		} else if(this.lex.front.type == TokenType.floatValue) {
1831 			Token tok = this.lex.front;
1832 			this.lex.popFront();
1833 
1834 			return new Value(ValueEnum.FLOAT
1835 				, tok
1836 			);
1837 		} else if(this.lex.front.type == TokenType.true_) {
1838 			Token tok = this.lex.front;
1839 			this.lex.popFront();
1840 
1841 			return new Value(ValueEnum.T
1842 				, tok
1843 			);
1844 		} else if(this.lex.front.type == TokenType.false_) {
1845 			Token tok = this.lex.front;
1846 			this.lex.popFront();
1847 
1848 			return new Value(ValueEnum.F
1849 				, tok
1850 			);
1851 		} else if(this.firstArray()) {
1852 			Array arr = this.parseArray();
1853 
1854 			return new Value(ValueEnum.ARR
1855 				, arr
1856 			);
1857 		} else if(this.firstObjectType()) {
1858 			ObjectType obj = this.parseObjectType();
1859 
1860 			return new Value(ValueEnum.O
1861 				, obj
1862 			);
1863 		} else if(this.lex.front.type == TokenType.name) {
1864 			Token tok = this.lex.front;
1865 			this.lex.popFront();
1866 
1867 			return new Value(ValueEnum.E
1868 				, tok
1869 			);
1870 		}
1871 		auto app = appender!string();
1872 		formattedWrite(app, 
1873 			"Found a '%s' while looking for", 
1874 			this.lex.front
1875 		);
1876 		throw new ParseException(app.data,
1877 			__FILE__, __LINE__,
1878 			subRules,
1879 			["stringValue","intValue","floatValue","true_","false_","lbrack","lcurly","name"]
1880 		);
1881 
1882 	}
1883 
1884 	bool firstType() const pure @nogc @safe {
1885 		return this.lex.front.type == TokenType.name
1886 			 || this.firstListType();
1887 	}
1888 
1889 	Type parseType() {
1890 		try {
1891 			return this.parseTypeImpl();
1892 		} catch(ParseException e) {
1893 			throw new ParseException(
1894 				"While parsing a Type an Exception was thrown.",
1895 				e, __FILE__, __LINE__
1896 			);
1897 		}
1898 	}
1899 
1900 	Type parseTypeImpl() {
1901 		string[] subRules;
1902 		subRules = ["T", "TN"];
1903 		if(this.lex.front.type == TokenType.name) {
1904 			Token tname = this.lex.front;
1905 			this.lex.popFront();
1906 			subRules = ["TN"];
1907 			if(this.lex.front.type == TokenType.exclamation) {
1908 				this.lex.popFront();
1909 
1910 				return new Type(TypeEnum.TN
1911 					, tname
1912 				);
1913 			}
1914 			return new Type(TypeEnum.T
1915 				, tname
1916 			);
1917 		} else if(this.firstListType()) {
1918 			ListType list = this.parseListType();
1919 			subRules = ["LN"];
1920 			if(this.lex.front.type == TokenType.exclamation) {
1921 				this.lex.popFront();
1922 
1923 				return new Type(TypeEnum.LN
1924 					, list
1925 				);
1926 			}
1927 			return new Type(TypeEnum.L
1928 				, list
1929 			);
1930 		}
1931 		auto app = appender!string();
1932 		formattedWrite(app, 
1933 			"Found a '%s' while looking for", 
1934 			this.lex.front
1935 		);
1936 		throw new ParseException(app.data,
1937 			__FILE__, __LINE__,
1938 			subRules,
1939 			["name","lbrack"]
1940 		);
1941 
1942 	}
1943 
1944 	bool firstListType() const pure @nogc @safe {
1945 		return this.lex.front.type == TokenType.lbrack;
1946 	}
1947 
1948 	ListType parseListType() {
1949 		try {
1950 			return this.parseListTypeImpl();
1951 		} catch(ParseException e) {
1952 			throw new ParseException(
1953 				"While parsing a ListType an Exception was thrown.",
1954 				e, __FILE__, __LINE__
1955 			);
1956 		}
1957 	}
1958 
1959 	ListType parseListTypeImpl() {
1960 		string[] subRules;
1961 		subRules = ["T"];
1962 		if(this.lex.front.type == TokenType.lbrack) {
1963 			this.lex.popFront();
1964 			subRules = ["T"];
1965 			if(this.firstType()) {
1966 				Type type = this.parseType();
1967 				subRules = ["T"];
1968 				if(this.lex.front.type == TokenType.rbrack) {
1969 					this.lex.popFront();
1970 
1971 					return new ListType(ListTypeEnum.T
1972 						, type
1973 					);
1974 				}
1975 				auto app = appender!string();
1976 				formattedWrite(app, 
1977 					"Found a '%s' while looking for", 
1978 					this.lex.front
1979 				);
1980 				throw new ParseException(app.data,
1981 					__FILE__, __LINE__,
1982 					subRules,
1983 					["rbrack"]
1984 				);
1985 
1986 			}
1987 			auto app = appender!string();
1988 			formattedWrite(app, 
1989 				"Found a '%s' while looking for", 
1990 				this.lex.front
1991 			);
1992 			throw new ParseException(app.data,
1993 				__FILE__, __LINE__,
1994 				subRules,
1995 				["lbrack -> ListType","name"]
1996 			);
1997 
1998 		}
1999 		auto app = appender!string();
2000 		formattedWrite(app, 
2001 			"Found a '%s' while looking for", 
2002 			this.lex.front
2003 		);
2004 		throw new ParseException(app.data,
2005 			__FILE__, __LINE__,
2006 			subRules,
2007 			["lbrack"]
2008 		);
2009 
2010 	}
2011 
2012 	bool firstValues() const pure @nogc @safe {
2013 		return this.firstValue();
2014 	}
2015 
2016 	Values parseValues() {
2017 		try {
2018 			return this.parseValuesImpl();
2019 		} catch(ParseException e) {
2020 			throw new ParseException(
2021 				"While parsing a Values an Exception was thrown.",
2022 				e, __FILE__, __LINE__
2023 			);
2024 		}
2025 	}
2026 
2027 	Values parseValuesImpl() {
2028 		string[] subRules;
2029 		subRules = ["Val", "Vals"];
2030 		if(this.firstValue()) {
2031 			Value val = this.parseValue();
2032 			subRules = ["Vals"];
2033 			if(this.lex.front.type == TokenType.comma) {
2034 				this.lex.popFront();
2035 				subRules = ["Vals"];
2036 				if(this.firstValues()) {
2037 					Values follow = this.parseValues();
2038 
2039 					return new Values(ValuesEnum.Vals
2040 						, val
2041 						, follow
2042 					);
2043 				}
2044 				auto app = appender!string();
2045 				formattedWrite(app, 
2046 					"Found a '%s' while looking for", 
2047 					this.lex.front
2048 				);
2049 				throw new ParseException(app.data,
2050 					__FILE__, __LINE__,
2051 					subRules,
2052 					["false_ -> Value","floatValue -> Value","intValue -> Value","lbrack -> Value","lcurly -> Value","name -> Value","stringValue -> Value","true_ -> Value"]
2053 				);
2054 
2055 			}
2056 			return new Values(ValuesEnum.Val
2057 				, val
2058 			);
2059 		}
2060 		auto app = appender!string();
2061 		formattedWrite(app, 
2062 			"Found a '%s' while looking for", 
2063 			this.lex.front
2064 		);
2065 		throw new ParseException(app.data,
2066 			__FILE__, __LINE__,
2067 			subRules,
2068 			["false_","floatValue","intValue","lbrack -> Array","lcurly -> ObjectType","name","stringValue","true_"]
2069 		);
2070 
2071 	}
2072 
2073 	bool firstArray() const pure @nogc @safe {
2074 		return this.lex.front.type == TokenType.lbrack;
2075 	}
2076 
2077 	Array parseArray() {
2078 		try {
2079 			return this.parseArrayImpl();
2080 		} catch(ParseException e) {
2081 			throw new ParseException(
2082 				"While parsing a Array an Exception was thrown.",
2083 				e, __FILE__, __LINE__
2084 			);
2085 		}
2086 	}
2087 
2088 	Array parseArrayImpl() {
2089 		string[] subRules;
2090 		subRules = ["Empty", "Value"];
2091 		if(this.lex.front.type == TokenType.lbrack) {
2092 			this.lex.popFront();
2093 			subRules = ["Empty"];
2094 			if(this.lex.front.type == TokenType.rbrack) {
2095 				this.lex.popFront();
2096 
2097 				return new Array(ArrayEnum.Empty
2098 				);
2099 			} else if(this.firstValues()) {
2100 				Values vals = this.parseValues();
2101 				subRules = ["Value"];
2102 				if(this.lex.front.type == TokenType.rbrack) {
2103 					this.lex.popFront();
2104 
2105 					return new Array(ArrayEnum.Value
2106 						, vals
2107 					);
2108 				}
2109 				auto app = appender!string();
2110 				formattedWrite(app, 
2111 					"Found a '%s' while looking for", 
2112 					this.lex.front
2113 				);
2114 				throw new ParseException(app.data,
2115 					__FILE__, __LINE__,
2116 					subRules,
2117 					["rbrack"]
2118 				);
2119 
2120 			}
2121 			auto app = appender!string();
2122 			formattedWrite(app, 
2123 				"Found a '%s' while looking for", 
2124 				this.lex.front
2125 			);
2126 			throw new ParseException(app.data,
2127 				__FILE__, __LINE__,
2128 				subRules,
2129 				["rbrack","false_ -> Value","floatValue -> Value","intValue -> Value","lbrack -> Value","lcurly -> Value","name -> Value","stringValue -> Value","true_ -> Value"]
2130 			);
2131 
2132 		}
2133 		auto app = appender!string();
2134 		formattedWrite(app, 
2135 			"Found a '%s' while looking for", 
2136 			this.lex.front
2137 		);
2138 		throw new ParseException(app.data,
2139 			__FILE__, __LINE__,
2140 			subRules,
2141 			["lbrack"]
2142 		);
2143 
2144 	}
2145 
2146 	bool firstObjectValues() const pure @nogc @safe {
2147 		return this.lex.front.type == TokenType.name;
2148 	}
2149 
2150 	ObjectValues parseObjectValues() {
2151 		try {
2152 			return this.parseObjectValuesImpl();
2153 		} catch(ParseException e) {
2154 			throw new ParseException(
2155 				"While parsing a ObjectValues an Exception was thrown.",
2156 				e, __FILE__, __LINE__
2157 			);
2158 		}
2159 	}
2160 
2161 	ObjectValues parseObjectValuesImpl() {
2162 		string[] subRules;
2163 		subRules = ["V", "Vs", "Vsc"];
2164 		if(this.lex.front.type == TokenType.name) {
2165 			Token name = this.lex.front;
2166 			this.lex.popFront();
2167 			subRules = ["V", "Vs", "Vsc"];
2168 			if(this.lex.front.type == TokenType.colon) {
2169 				this.lex.popFront();
2170 				subRules = ["V", "Vs", "Vsc"];
2171 				if(this.firstValue()) {
2172 					Value val = this.parseValue();
2173 					subRules = ["Vsc"];
2174 					if(this.lex.front.type == TokenType.comma) {
2175 						this.lex.popFront();
2176 						subRules = ["Vsc"];
2177 						if(this.firstObjectValues()) {
2178 							ObjectValues follow = this.parseObjectValues();
2179 
2180 							return new ObjectValues(ObjectValuesEnum.Vsc
2181 								, name
2182 								, val
2183 								, follow
2184 							);
2185 						}
2186 						auto app = appender!string();
2187 						formattedWrite(app, 
2188 							"Found a '%s' while looking for", 
2189 							this.lex.front
2190 						);
2191 						throw new ParseException(app.data,
2192 							__FILE__, __LINE__,
2193 							subRules,
2194 							["name"]
2195 						);
2196 
2197 					} else if(this.firstObjectValues()) {
2198 						ObjectValues follow = this.parseObjectValues();
2199 
2200 						return new ObjectValues(ObjectValuesEnum.Vs
2201 							, name
2202 							, val
2203 							, follow
2204 						);
2205 					}
2206 					return new ObjectValues(ObjectValuesEnum.V
2207 						, name
2208 						, val
2209 					);
2210 				}
2211 				auto app = appender!string();
2212 				formattedWrite(app, 
2213 					"Found a '%s' while looking for", 
2214 					this.lex.front
2215 				);
2216 				throw new ParseException(app.data,
2217 					__FILE__, __LINE__,
2218 					subRules,
2219 					["false_","floatValue","intValue","lbrack -> Array","lcurly -> ObjectType","name","stringValue","true_"]
2220 				);
2221 
2222 			}
2223 			auto app = appender!string();
2224 			formattedWrite(app, 
2225 				"Found a '%s' while looking for", 
2226 				this.lex.front
2227 			);
2228 			throw new ParseException(app.data,
2229 				__FILE__, __LINE__,
2230 				subRules,
2231 				["colon"]
2232 			);
2233 
2234 		}
2235 		auto app = appender!string();
2236 		formattedWrite(app, 
2237 			"Found a '%s' while looking for", 
2238 			this.lex.front
2239 		);
2240 		throw new ParseException(app.data,
2241 			__FILE__, __LINE__,
2242 			subRules,
2243 			["name"]
2244 		);
2245 
2246 	}
2247 
2248 	bool firstObjectType() const pure @nogc @safe {
2249 		return this.lex.front.type == TokenType.lcurly;
2250 	}
2251 
2252 	ObjectType parseObjectType() {
2253 		try {
2254 			return this.parseObjectTypeImpl();
2255 		} catch(ParseException e) {
2256 			throw new ParseException(
2257 				"While parsing a ObjectType an Exception was thrown.",
2258 				e, __FILE__, __LINE__
2259 			);
2260 		}
2261 	}
2262 
2263 	ObjectType parseObjectTypeImpl() {
2264 		string[] subRules;
2265 		subRules = ["Var"];
2266 		if(this.lex.front.type == TokenType.lcurly) {
2267 			this.lex.popFront();
2268 			subRules = ["Var"];
2269 			if(this.firstObjectValues()) {
2270 				ObjectValues vals = this.parseObjectValues();
2271 				subRules = ["Var"];
2272 				if(this.lex.front.type == TokenType.rcurly) {
2273 					this.lex.popFront();
2274 
2275 					return new ObjectType(ObjectTypeEnum.Var
2276 						, vals
2277 					);
2278 				}
2279 				auto app = appender!string();
2280 				formattedWrite(app, 
2281 					"Found a '%s' while looking for", 
2282 					this.lex.front
2283 				);
2284 				throw new ParseException(app.data,
2285 					__FILE__, __LINE__,
2286 					subRules,
2287 					["rcurly"]
2288 				);
2289 
2290 			}
2291 			auto app = appender!string();
2292 			formattedWrite(app, 
2293 				"Found a '%s' while looking for", 
2294 				this.lex.front
2295 			);
2296 			throw new ParseException(app.data,
2297 				__FILE__, __LINE__,
2298 				subRules,
2299 				["name"]
2300 			);
2301 
2302 		}
2303 		auto app = appender!string();
2304 		formattedWrite(app, 
2305 			"Found a '%s' while looking for", 
2306 			this.lex.front
2307 		);
2308 		throw new ParseException(app.data,
2309 			__FILE__, __LINE__,
2310 			subRules,
2311 			["lcurly"]
2312 		);
2313 
2314 	}
2315 
2316 	bool firstTypeSystemDefinition() const pure @nogc @safe {
2317 		return this.firstSchemaDefinition()
2318 			 || this.firstTypeDefinition()
2319 			 || this.firstTypeExtensionDefinition()
2320 			 || this.firstDirectiveDefinition();
2321 	}
2322 
2323 	TypeSystemDefinition parseTypeSystemDefinition() {
2324 		try {
2325 			return this.parseTypeSystemDefinitionImpl();
2326 		} catch(ParseException e) {
2327 			throw new ParseException(
2328 				"While parsing a TypeSystemDefinition an Exception was thrown.",
2329 				e, __FILE__, __LINE__
2330 			);
2331 		}
2332 	}
2333 
2334 	TypeSystemDefinition parseTypeSystemDefinitionImpl() {
2335 		string[] subRules;
2336 		subRules = ["S"];
2337 		if(this.firstSchemaDefinition()) {
2338 			SchemaDefinition sch = this.parseSchemaDefinition();
2339 
2340 			return new TypeSystemDefinition(TypeSystemDefinitionEnum.S
2341 				, sch
2342 			);
2343 		} else if(this.firstTypeDefinition()) {
2344 			TypeDefinition td = this.parseTypeDefinition();
2345 
2346 			return new TypeSystemDefinition(TypeSystemDefinitionEnum.T
2347 				, td
2348 			);
2349 		} else if(this.firstTypeExtensionDefinition()) {
2350 			TypeExtensionDefinition ted = this.parseTypeExtensionDefinition();
2351 
2352 			return new TypeSystemDefinition(TypeSystemDefinitionEnum.TE
2353 				, ted
2354 			);
2355 		} else if(this.firstDirectiveDefinition()) {
2356 			DirectiveDefinition dd = this.parseDirectiveDefinition();
2357 
2358 			return new TypeSystemDefinition(TypeSystemDefinitionEnum.D
2359 				, dd
2360 			);
2361 		}
2362 		auto app = appender!string();
2363 		formattedWrite(app, 
2364 			"Found a '%s' while looking for", 
2365 			this.lex.front
2366 		);
2367 		throw new ParseException(app.data,
2368 			__FILE__, __LINE__,
2369 			subRules,
2370 			["schema","enum_ -> EnumTypeDefinition","input -> InputObjectTypeDefinition","interface_ -> InterfaceTypeDefinition","scalar -> ScalarTypeDefinition","type -> ObjectTypeDefinition","union_ -> UnionTypeDefinition","extend","directive"]
2371 		);
2372 
2373 	}
2374 
2375 	bool firstTypeDefinition() const pure @nogc @safe {
2376 		return this.firstScalarTypeDefinition()
2377 			 || this.firstObjectTypeDefinition()
2378 			 || this.firstInterfaceTypeDefinition()
2379 			 || this.firstUnionTypeDefinition()
2380 			 || this.firstEnumTypeDefinition()
2381 			 || this.firstInputObjectTypeDefinition();
2382 	}
2383 
2384 	TypeDefinition parseTypeDefinition() {
2385 		try {
2386 			return this.parseTypeDefinitionImpl();
2387 		} catch(ParseException e) {
2388 			throw new ParseException(
2389 				"While parsing a TypeDefinition an Exception was thrown.",
2390 				e, __FILE__, __LINE__
2391 			);
2392 		}
2393 	}
2394 
2395 	TypeDefinition parseTypeDefinitionImpl() {
2396 		string[] subRules;
2397 		subRules = ["S"];
2398 		if(this.firstScalarTypeDefinition()) {
2399 			ScalarTypeDefinition std = this.parseScalarTypeDefinition();
2400 
2401 			return new TypeDefinition(TypeDefinitionEnum.S
2402 				, std
2403 			);
2404 		} else if(this.firstObjectTypeDefinition()) {
2405 			ObjectTypeDefinition otd = this.parseObjectTypeDefinition();
2406 
2407 			return new TypeDefinition(TypeDefinitionEnum.O
2408 				, otd
2409 			);
2410 		} else if(this.firstInterfaceTypeDefinition()) {
2411 			InterfaceTypeDefinition itd = this.parseInterfaceTypeDefinition();
2412 
2413 			return new TypeDefinition(TypeDefinitionEnum.I
2414 				, itd
2415 			);
2416 		} else if(this.firstUnionTypeDefinition()) {
2417 			UnionTypeDefinition utd = this.parseUnionTypeDefinition();
2418 
2419 			return new TypeDefinition(TypeDefinitionEnum.U
2420 				, utd
2421 			);
2422 		} else if(this.firstEnumTypeDefinition()) {
2423 			EnumTypeDefinition etd = this.parseEnumTypeDefinition();
2424 
2425 			return new TypeDefinition(TypeDefinitionEnum.E
2426 				, etd
2427 			);
2428 		} else if(this.firstInputObjectTypeDefinition()) {
2429 			InputObjectTypeDefinition iod = this.parseInputObjectTypeDefinition();
2430 
2431 			return new TypeDefinition(TypeDefinitionEnum.IO
2432 				, iod
2433 			);
2434 		}
2435 		auto app = appender!string();
2436 		formattedWrite(app, 
2437 			"Found a '%s' while looking for", 
2438 			this.lex.front
2439 		);
2440 		throw new ParseException(app.data,
2441 			__FILE__, __LINE__,
2442 			subRules,
2443 			["scalar","type","interface_","union_","enum_","input"]
2444 		);
2445 
2446 	}
2447 
2448 	bool firstSchemaDefinition() const pure @nogc @safe {
2449 		return this.lex.front.type == TokenType.schema;
2450 	}
2451 
2452 	SchemaDefinition parseSchemaDefinition() {
2453 		try {
2454 			return this.parseSchemaDefinitionImpl();
2455 		} catch(ParseException e) {
2456 			throw new ParseException(
2457 				"While parsing a SchemaDefinition an Exception was thrown.",
2458 				e, __FILE__, __LINE__
2459 			);
2460 		}
2461 	}
2462 
2463 	SchemaDefinition parseSchemaDefinitionImpl() {
2464 		string[] subRules;
2465 		subRules = ["DO", "O"];
2466 		if(this.lex.front.type == TokenType.schema) {
2467 			this.lex.popFront();
2468 			subRules = ["DO"];
2469 			if(this.firstDirectives()) {
2470 				Directives dir = this.parseDirectives();
2471 				subRules = ["DO"];
2472 				if(this.lex.front.type == TokenType.lcurly) {
2473 					this.lex.popFront();
2474 					subRules = ["DO"];
2475 					if(this.firstOperationTypeDefinitions()) {
2476 						OperationTypeDefinitions otds = this.parseOperationTypeDefinitions();
2477 						subRules = ["DO"];
2478 						if(this.lex.front.type == TokenType.rcurly) {
2479 							this.lex.popFront();
2480 
2481 							return new SchemaDefinition(SchemaDefinitionEnum.DO
2482 								, dir
2483 								, otds
2484 							);
2485 						}
2486 						auto app = appender!string();
2487 						formattedWrite(app, 
2488 							"Found a '%s' while looking for", 
2489 							this.lex.front
2490 						);
2491 						throw new ParseException(app.data,
2492 							__FILE__, __LINE__,
2493 							subRules,
2494 							["rcurly"]
2495 						);
2496 
2497 					}
2498 					auto app = appender!string();
2499 					formattedWrite(app, 
2500 						"Found a '%s' while looking for", 
2501 						this.lex.front
2502 					);
2503 					throw new ParseException(app.data,
2504 						__FILE__, __LINE__,
2505 						subRules,
2506 						["mutation -> OperationTypeDefinition","query -> OperationTypeDefinition","subscription -> OperationTypeDefinition"]
2507 					);
2508 
2509 				}
2510 				auto app = appender!string();
2511 				formattedWrite(app, 
2512 					"Found a '%s' while looking for", 
2513 					this.lex.front
2514 				);
2515 				throw new ParseException(app.data,
2516 					__FILE__, __LINE__,
2517 					subRules,
2518 					["lcurly"]
2519 				);
2520 
2521 			} else if(this.lex.front.type == TokenType.lcurly) {
2522 				this.lex.popFront();
2523 				subRules = ["O"];
2524 				if(this.firstOperationTypeDefinitions()) {
2525 					OperationTypeDefinitions otds = this.parseOperationTypeDefinitions();
2526 					subRules = ["O"];
2527 					if(this.lex.front.type == TokenType.rcurly) {
2528 						this.lex.popFront();
2529 
2530 						return new SchemaDefinition(SchemaDefinitionEnum.O
2531 							, otds
2532 						);
2533 					}
2534 					auto app = appender!string();
2535 					formattedWrite(app, 
2536 						"Found a '%s' while looking for", 
2537 						this.lex.front
2538 					);
2539 					throw new ParseException(app.data,
2540 						__FILE__, __LINE__,
2541 						subRules,
2542 						["rcurly"]
2543 					);
2544 
2545 				}
2546 				auto app = appender!string();
2547 				formattedWrite(app, 
2548 					"Found a '%s' while looking for", 
2549 					this.lex.front
2550 				);
2551 				throw new ParseException(app.data,
2552 					__FILE__, __LINE__,
2553 					subRules,
2554 					["mutation -> OperationTypeDefinition","query -> OperationTypeDefinition","subscription -> OperationTypeDefinition"]
2555 				);
2556 
2557 			}
2558 			auto app = appender!string();
2559 			formattedWrite(app, 
2560 				"Found a '%s' while looking for", 
2561 				this.lex.front
2562 			);
2563 			throw new ParseException(app.data,
2564 				__FILE__, __LINE__,
2565 				subRules,
2566 				["at -> Directive","lcurly"]
2567 			);
2568 
2569 		}
2570 		auto app = appender!string();
2571 		formattedWrite(app, 
2572 			"Found a '%s' while looking for", 
2573 			this.lex.front
2574 		);
2575 		throw new ParseException(app.data,
2576 			__FILE__, __LINE__,
2577 			subRules,
2578 			["schema"]
2579 		);
2580 
2581 	}
2582 
2583 	bool firstOperationTypeDefinitions() const pure @nogc @safe {
2584 		return this.firstOperationTypeDefinition();
2585 	}
2586 
2587 	OperationTypeDefinitions parseOperationTypeDefinitions() {
2588 		try {
2589 			return this.parseOperationTypeDefinitionsImpl();
2590 		} catch(ParseException e) {
2591 			throw new ParseException(
2592 				"While parsing a OperationTypeDefinitions an Exception was thrown.",
2593 				e, __FILE__, __LINE__
2594 			);
2595 		}
2596 	}
2597 
2598 	OperationTypeDefinitions parseOperationTypeDefinitionsImpl() {
2599 		string[] subRules;
2600 		subRules = ["O", "OCS", "OS"];
2601 		if(this.firstOperationTypeDefinition()) {
2602 			OperationTypeDefinition otd = this.parseOperationTypeDefinition();
2603 			subRules = ["OCS"];
2604 			if(this.lex.front.type == TokenType.comma) {
2605 				this.lex.popFront();
2606 				subRules = ["OCS"];
2607 				if(this.firstOperationTypeDefinitions()) {
2608 					OperationTypeDefinitions follow = this.parseOperationTypeDefinitions();
2609 
2610 					return new OperationTypeDefinitions(OperationTypeDefinitionsEnum.OCS
2611 						, otd
2612 						, follow
2613 					);
2614 				}
2615 				auto app = appender!string();
2616 				formattedWrite(app, 
2617 					"Found a '%s' while looking for", 
2618 					this.lex.front
2619 				);
2620 				throw new ParseException(app.data,
2621 					__FILE__, __LINE__,
2622 					subRules,
2623 					["mutation -> OperationTypeDefinition","query -> OperationTypeDefinition","subscription -> OperationTypeDefinition"]
2624 				);
2625 
2626 			} else if(this.firstOperationTypeDefinitions()) {
2627 				OperationTypeDefinitions follow = this.parseOperationTypeDefinitions();
2628 
2629 				return new OperationTypeDefinitions(OperationTypeDefinitionsEnum.OS
2630 					, otd
2631 					, follow
2632 				);
2633 			}
2634 			return new OperationTypeDefinitions(OperationTypeDefinitionsEnum.O
2635 				, otd
2636 			);
2637 		}
2638 		auto app = appender!string();
2639 		formattedWrite(app, 
2640 			"Found a '%s' while looking for", 
2641 			this.lex.front
2642 		);
2643 		throw new ParseException(app.data,
2644 			__FILE__, __LINE__,
2645 			subRules,
2646 			["mutation -> OperationType","query -> OperationType","subscription -> OperationType"]
2647 		);
2648 
2649 	}
2650 
2651 	bool firstOperationTypeDefinition() const pure @nogc @safe {
2652 		return this.firstOperationType();
2653 	}
2654 
2655 	OperationTypeDefinition parseOperationTypeDefinition() {
2656 		try {
2657 			return this.parseOperationTypeDefinitionImpl();
2658 		} catch(ParseException e) {
2659 			throw new ParseException(
2660 				"While parsing a OperationTypeDefinition an Exception was thrown.",
2661 				e, __FILE__, __LINE__
2662 			);
2663 		}
2664 	}
2665 
2666 	OperationTypeDefinition parseOperationTypeDefinitionImpl() {
2667 		string[] subRules;
2668 		subRules = ["O"];
2669 		if(this.firstOperationType()) {
2670 			OperationType ot = this.parseOperationType();
2671 			subRules = ["O"];
2672 			if(this.lex.front.type == TokenType.colon) {
2673 				this.lex.popFront();
2674 				subRules = ["O"];
2675 				if(this.lex.front.type == TokenType.name) {
2676 					Token nt = this.lex.front;
2677 					this.lex.popFront();
2678 
2679 					return new OperationTypeDefinition(OperationTypeDefinitionEnum.O
2680 						, ot
2681 						, nt
2682 					);
2683 				}
2684 				auto app = appender!string();
2685 				formattedWrite(app, 
2686 					"Found a '%s' while looking for", 
2687 					this.lex.front
2688 				);
2689 				throw new ParseException(app.data,
2690 					__FILE__, __LINE__,
2691 					subRules,
2692 					["name"]
2693 				);
2694 
2695 			}
2696 			auto app = appender!string();
2697 			formattedWrite(app, 
2698 				"Found a '%s' while looking for", 
2699 				this.lex.front
2700 			);
2701 			throw new ParseException(app.data,
2702 				__FILE__, __LINE__,
2703 				subRules,
2704 				["colon"]
2705 			);
2706 
2707 		}
2708 		auto app = appender!string();
2709 		formattedWrite(app, 
2710 			"Found a '%s' while looking for", 
2711 			this.lex.front
2712 		);
2713 		throw new ParseException(app.data,
2714 			__FILE__, __LINE__,
2715 			subRules,
2716 			["mutation","query","subscription"]
2717 		);
2718 
2719 	}
2720 
2721 	bool firstScalarTypeDefinition() const pure @nogc @safe {
2722 		return this.lex.front.type == TokenType.scalar;
2723 	}
2724 
2725 	ScalarTypeDefinition parseScalarTypeDefinition() {
2726 		try {
2727 			return this.parseScalarTypeDefinitionImpl();
2728 		} catch(ParseException e) {
2729 			throw new ParseException(
2730 				"While parsing a ScalarTypeDefinition an Exception was thrown.",
2731 				e, __FILE__, __LINE__
2732 			);
2733 		}
2734 	}
2735 
2736 	ScalarTypeDefinition parseScalarTypeDefinitionImpl() {
2737 		string[] subRules;
2738 		subRules = ["D", "S"];
2739 		if(this.lex.front.type == TokenType.scalar) {
2740 			this.lex.popFront();
2741 			subRules = ["D", "S"];
2742 			if(this.lex.front.type == TokenType.name) {
2743 				Token name = this.lex.front;
2744 				this.lex.popFront();
2745 				subRules = ["D"];
2746 				if(this.firstDirectives()) {
2747 					Directives dir = this.parseDirectives();
2748 
2749 					return new ScalarTypeDefinition(ScalarTypeDefinitionEnum.D
2750 						, name
2751 						, dir
2752 					);
2753 				}
2754 				return new ScalarTypeDefinition(ScalarTypeDefinitionEnum.S
2755 					, name
2756 				);
2757 			}
2758 			auto app = appender!string();
2759 			formattedWrite(app, 
2760 				"Found a '%s' while looking for", 
2761 				this.lex.front
2762 			);
2763 			throw new ParseException(app.data,
2764 				__FILE__, __LINE__,
2765 				subRules,
2766 				["name"]
2767 			);
2768 
2769 		}
2770 		auto app = appender!string();
2771 		formattedWrite(app, 
2772 			"Found a '%s' while looking for", 
2773 			this.lex.front
2774 		);
2775 		throw new ParseException(app.data,
2776 			__FILE__, __LINE__,
2777 			subRules,
2778 			["scalar"]
2779 		);
2780 
2781 	}
2782 
2783 	bool firstObjectTypeDefinition() const pure @nogc @safe {
2784 		return this.lex.front.type == TokenType.type;
2785 	}
2786 
2787 	ObjectTypeDefinition parseObjectTypeDefinition() {
2788 		try {
2789 			return this.parseObjectTypeDefinitionImpl();
2790 		} catch(ParseException e) {
2791 			throw new ParseException(
2792 				"While parsing a ObjectTypeDefinition an Exception was thrown.",
2793 				e, __FILE__, __LINE__
2794 			);
2795 		}
2796 	}
2797 
2798 	ObjectTypeDefinition parseObjectTypeDefinitionImpl() {
2799 		string[] subRules;
2800 		subRules = ["D", "F", "I", "ID"];
2801 		if(this.lex.front.type == TokenType.type) {
2802 			this.lex.popFront();
2803 			subRules = ["D", "F", "I", "ID"];
2804 			if(this.lex.front.type == TokenType.name) {
2805 				Token name = this.lex.front;
2806 				this.lex.popFront();
2807 				subRules = ["I", "ID"];
2808 				if(this.firstImplementsInterfaces()) {
2809 					ImplementsInterfaces ii = this.parseImplementsInterfaces();
2810 					subRules = ["ID"];
2811 					if(this.firstDirectives()) {
2812 						Directives dir = this.parseDirectives();
2813 						subRules = ["ID"];
2814 						if(this.lex.front.type == TokenType.lcurly) {
2815 							this.lex.popFront();
2816 							subRules = ["ID"];
2817 							if(this.firstFieldDefinitions()) {
2818 								FieldDefinitions fds = this.parseFieldDefinitions();
2819 								subRules = ["ID"];
2820 								if(this.lex.front.type == TokenType.rcurly) {
2821 									this.lex.popFront();
2822 
2823 									return new ObjectTypeDefinition(ObjectTypeDefinitionEnum.ID
2824 										, name
2825 										, ii
2826 										, dir
2827 										, fds
2828 									);
2829 								}
2830 								auto app = appender!string();
2831 								formattedWrite(app, 
2832 									"Found a '%s' while looking for", 
2833 									this.lex.front
2834 								);
2835 								throw new ParseException(app.data,
2836 									__FILE__, __LINE__,
2837 									subRules,
2838 									["rcurly"]
2839 								);
2840 
2841 							}
2842 							auto app = appender!string();
2843 							formattedWrite(app, 
2844 								"Found a '%s' while looking for", 
2845 								this.lex.front
2846 							);
2847 							throw new ParseException(app.data,
2848 								__FILE__, __LINE__,
2849 								subRules,
2850 								["name -> FieldDefinition"]
2851 							);
2852 
2853 						}
2854 						auto app = appender!string();
2855 						formattedWrite(app, 
2856 							"Found a '%s' while looking for", 
2857 							this.lex.front
2858 						);
2859 						throw new ParseException(app.data,
2860 							__FILE__, __LINE__,
2861 							subRules,
2862 							["lcurly"]
2863 						);
2864 
2865 					} else if(this.lex.front.type == TokenType.lcurly) {
2866 						this.lex.popFront();
2867 						subRules = ["I"];
2868 						if(this.firstFieldDefinitions()) {
2869 							FieldDefinitions fds = this.parseFieldDefinitions();
2870 							subRules = ["I"];
2871 							if(this.lex.front.type == TokenType.rcurly) {
2872 								this.lex.popFront();
2873 
2874 								return new ObjectTypeDefinition(ObjectTypeDefinitionEnum.I
2875 									, name
2876 									, ii
2877 									, fds
2878 								);
2879 							}
2880 							auto app = appender!string();
2881 							formattedWrite(app, 
2882 								"Found a '%s' while looking for", 
2883 								this.lex.front
2884 							);
2885 							throw new ParseException(app.data,
2886 								__FILE__, __LINE__,
2887 								subRules,
2888 								["rcurly"]
2889 							);
2890 
2891 						}
2892 						auto app = appender!string();
2893 						formattedWrite(app, 
2894 							"Found a '%s' while looking for", 
2895 							this.lex.front
2896 						);
2897 						throw new ParseException(app.data,
2898 							__FILE__, __LINE__,
2899 							subRules,
2900 							["name -> FieldDefinition"]
2901 						);
2902 
2903 					}
2904 					auto app = appender!string();
2905 					formattedWrite(app, 
2906 						"Found a '%s' while looking for", 
2907 						this.lex.front
2908 					);
2909 					throw new ParseException(app.data,
2910 						__FILE__, __LINE__,
2911 						subRules,
2912 						["at -> Directive","lcurly"]
2913 					);
2914 
2915 				} else if(this.firstDirectives()) {
2916 					Directives dir = this.parseDirectives();
2917 					subRules = ["D"];
2918 					if(this.lex.front.type == TokenType.lcurly) {
2919 						this.lex.popFront();
2920 						subRules = ["D"];
2921 						if(this.firstFieldDefinitions()) {
2922 							FieldDefinitions fds = this.parseFieldDefinitions();
2923 							subRules = ["D"];
2924 							if(this.lex.front.type == TokenType.rcurly) {
2925 								this.lex.popFront();
2926 
2927 								return new ObjectTypeDefinition(ObjectTypeDefinitionEnum.D
2928 									, name
2929 									, dir
2930 									, fds
2931 								);
2932 							}
2933 							auto app = appender!string();
2934 							formattedWrite(app, 
2935 								"Found a '%s' while looking for", 
2936 								this.lex.front
2937 							);
2938 							throw new ParseException(app.data,
2939 								__FILE__, __LINE__,
2940 								subRules,
2941 								["rcurly"]
2942 							);
2943 
2944 						}
2945 						auto app = appender!string();
2946 						formattedWrite(app, 
2947 							"Found a '%s' while looking for", 
2948 							this.lex.front
2949 						);
2950 						throw new ParseException(app.data,
2951 							__FILE__, __LINE__,
2952 							subRules,
2953 							["name -> FieldDefinition"]
2954 						);
2955 
2956 					}
2957 					auto app = appender!string();
2958 					formattedWrite(app, 
2959 						"Found a '%s' while looking for", 
2960 						this.lex.front
2961 					);
2962 					throw new ParseException(app.data,
2963 						__FILE__, __LINE__,
2964 						subRules,
2965 						["lcurly"]
2966 					);
2967 
2968 				} else if(this.lex.front.type == TokenType.lcurly) {
2969 					this.lex.popFront();
2970 					subRules = ["F"];
2971 					if(this.firstFieldDefinitions()) {
2972 						FieldDefinitions fds = this.parseFieldDefinitions();
2973 						subRules = ["F"];
2974 						if(this.lex.front.type == TokenType.rcurly) {
2975 							this.lex.popFront();
2976 
2977 							return new ObjectTypeDefinition(ObjectTypeDefinitionEnum.F
2978 								, name
2979 								, fds
2980 							);
2981 						}
2982 						auto app = appender!string();
2983 						formattedWrite(app, 
2984 							"Found a '%s' while looking for", 
2985 							this.lex.front
2986 						);
2987 						throw new ParseException(app.data,
2988 							__FILE__, __LINE__,
2989 							subRules,
2990 							["rcurly"]
2991 						);
2992 
2993 					}
2994 					auto app = appender!string();
2995 					formattedWrite(app, 
2996 						"Found a '%s' while looking for", 
2997 						this.lex.front
2998 					);
2999 					throw new ParseException(app.data,
3000 						__FILE__, __LINE__,
3001 						subRules,
3002 						["name -> FieldDefinition"]
3003 					);
3004 
3005 				}
3006 				auto app = appender!string();
3007 				formattedWrite(app, 
3008 					"Found a '%s' while looking for", 
3009 					this.lex.front
3010 				);
3011 				throw new ParseException(app.data,
3012 					__FILE__, __LINE__,
3013 					subRules,
3014 					["implements","at -> Directive","lcurly"]
3015 				);
3016 
3017 			}
3018 			auto app = appender!string();
3019 			formattedWrite(app, 
3020 				"Found a '%s' while looking for", 
3021 				this.lex.front
3022 			);
3023 			throw new ParseException(app.data,
3024 				__FILE__, __LINE__,
3025 				subRules,
3026 				["name"]
3027 			);
3028 
3029 		}
3030 		auto app = appender!string();
3031 		formattedWrite(app, 
3032 			"Found a '%s' while looking for", 
3033 			this.lex.front
3034 		);
3035 		throw new ParseException(app.data,
3036 			__FILE__, __LINE__,
3037 			subRules,
3038 			["type"]
3039 		);
3040 
3041 	}
3042 
3043 	bool firstFieldDefinitions() const pure @nogc @safe {
3044 		return this.firstFieldDefinition();
3045 	}
3046 
3047 	FieldDefinitions parseFieldDefinitions() {
3048 		try {
3049 			return this.parseFieldDefinitionsImpl();
3050 		} catch(ParseException e) {
3051 			throw new ParseException(
3052 				"While parsing a FieldDefinitions an Exception was thrown.",
3053 				e, __FILE__, __LINE__
3054 			);
3055 		}
3056 	}
3057 
3058 	FieldDefinitions parseFieldDefinitionsImpl() {
3059 		string[] subRules;
3060 		subRules = ["F", "FC", "FNC"];
3061 		if(this.firstFieldDefinition()) {
3062 			FieldDefinition fd = this.parseFieldDefinition();
3063 			subRules = ["FC"];
3064 			if(this.lex.front.type == TokenType.comma) {
3065 				this.lex.popFront();
3066 				subRules = ["FC"];
3067 				if(this.firstFieldDefinitions()) {
3068 					FieldDefinitions follow = this.parseFieldDefinitions();
3069 
3070 					return new FieldDefinitions(FieldDefinitionsEnum.FC
3071 						, fd
3072 						, follow
3073 					);
3074 				}
3075 				auto app = appender!string();
3076 				formattedWrite(app, 
3077 					"Found a '%s' while looking for", 
3078 					this.lex.front
3079 				);
3080 				throw new ParseException(app.data,
3081 					__FILE__, __LINE__,
3082 					subRules,
3083 					["name -> FieldDefinition"]
3084 				);
3085 
3086 			} else if(this.firstFieldDefinitions()) {
3087 				FieldDefinitions follow = this.parseFieldDefinitions();
3088 
3089 				return new FieldDefinitions(FieldDefinitionsEnum.FNC
3090 					, fd
3091 					, follow
3092 				);
3093 			}
3094 			return new FieldDefinitions(FieldDefinitionsEnum.F
3095 				, fd
3096 			);
3097 		}
3098 		auto app = appender!string();
3099 		formattedWrite(app, 
3100 			"Found a '%s' while looking for", 
3101 			this.lex.front
3102 		);
3103 		throw new ParseException(app.data,
3104 			__FILE__, __LINE__,
3105 			subRules,
3106 			["name"]
3107 		);
3108 
3109 	}
3110 
3111 	bool firstFieldDefinition() const pure @nogc @safe {
3112 		return this.lex.front.type == TokenType.name;
3113 	}
3114 
3115 	FieldDefinition parseFieldDefinition() {
3116 		try {
3117 			return this.parseFieldDefinitionImpl();
3118 		} catch(ParseException e) {
3119 			throw new ParseException(
3120 				"While parsing a FieldDefinition an Exception was thrown.",
3121 				e, __FILE__, __LINE__
3122 			);
3123 		}
3124 	}
3125 
3126 	FieldDefinition parseFieldDefinitionImpl() {
3127 		string[] subRules;
3128 		subRules = ["A", "AD", "D", "T"];
3129 		if(this.lex.front.type == TokenType.name) {
3130 			Token name = this.lex.front;
3131 			this.lex.popFront();
3132 			subRules = ["A", "AD"];
3133 			if(this.firstArgumentsDefinition()) {
3134 				ArgumentsDefinition arg = this.parseArgumentsDefinition();
3135 				subRules = ["A", "AD"];
3136 				if(this.lex.front.type == TokenType.colon) {
3137 					this.lex.popFront();
3138 					subRules = ["A", "AD"];
3139 					if(this.firstType()) {
3140 						Type typ = this.parseType();
3141 						subRules = ["AD"];
3142 						if(this.firstDirectives()) {
3143 							Directives dir = this.parseDirectives();
3144 
3145 							return new FieldDefinition(FieldDefinitionEnum.AD
3146 								, name
3147 								, arg
3148 								, typ
3149 								, dir
3150 							);
3151 						}
3152 						return new FieldDefinition(FieldDefinitionEnum.A
3153 							, name
3154 							, arg
3155 							, typ
3156 						);
3157 					}
3158 					auto app = appender!string();
3159 					formattedWrite(app, 
3160 						"Found a '%s' while looking for", 
3161 						this.lex.front
3162 					);
3163 					throw new ParseException(app.data,
3164 						__FILE__, __LINE__,
3165 						subRules,
3166 						["lbrack -> ListType","name"]
3167 					);
3168 
3169 				}
3170 				auto app = appender!string();
3171 				formattedWrite(app, 
3172 					"Found a '%s' while looking for", 
3173 					this.lex.front
3174 				);
3175 				throw new ParseException(app.data,
3176 					__FILE__, __LINE__,
3177 					subRules,
3178 					["colon"]
3179 				);
3180 
3181 			} else if(this.lex.front.type == TokenType.colon) {
3182 				this.lex.popFront();
3183 				subRules = ["D", "T"];
3184 				if(this.firstType()) {
3185 					Type typ = this.parseType();
3186 					subRules = ["D"];
3187 					if(this.firstDirectives()) {
3188 						Directives dir = this.parseDirectives();
3189 
3190 						return new FieldDefinition(FieldDefinitionEnum.D
3191 							, name
3192 							, typ
3193 							, dir
3194 						);
3195 					}
3196 					return new FieldDefinition(FieldDefinitionEnum.T
3197 						, name
3198 						, typ
3199 					);
3200 				}
3201 				auto app = appender!string();
3202 				formattedWrite(app, 
3203 					"Found a '%s' while looking for", 
3204 					this.lex.front
3205 				);
3206 				throw new ParseException(app.data,
3207 					__FILE__, __LINE__,
3208 					subRules,
3209 					["lbrack -> ListType","name"]
3210 				);
3211 
3212 			}
3213 			auto app = appender!string();
3214 			formattedWrite(app, 
3215 				"Found a '%s' while looking for", 
3216 				this.lex.front
3217 			);
3218 			throw new ParseException(app.data,
3219 				__FILE__, __LINE__,
3220 				subRules,
3221 				["lparen","colon"]
3222 			);
3223 
3224 		}
3225 		auto app = appender!string();
3226 		formattedWrite(app, 
3227 			"Found a '%s' while looking for", 
3228 			this.lex.front
3229 		);
3230 		throw new ParseException(app.data,
3231 			__FILE__, __LINE__,
3232 			subRules,
3233 			["name"]
3234 		);
3235 
3236 	}
3237 
3238 	bool firstImplementsInterfaces() const pure @nogc @safe {
3239 		return this.lex.front.type == TokenType.implements;
3240 	}
3241 
3242 	ImplementsInterfaces parseImplementsInterfaces() {
3243 		try {
3244 			return this.parseImplementsInterfacesImpl();
3245 		} catch(ParseException e) {
3246 			throw new ParseException(
3247 				"While parsing a ImplementsInterfaces an Exception was thrown.",
3248 				e, __FILE__, __LINE__
3249 			);
3250 		}
3251 	}
3252 
3253 	ImplementsInterfaces parseImplementsInterfacesImpl() {
3254 		string[] subRules;
3255 		subRules = ["N"];
3256 		if(this.lex.front.type == TokenType.implements) {
3257 			this.lex.popFront();
3258 			subRules = ["N"];
3259 			if(this.firstNamedTypes()) {
3260 				NamedTypes nts = this.parseNamedTypes();
3261 
3262 				return new ImplementsInterfaces(ImplementsInterfacesEnum.N
3263 					, nts
3264 				);
3265 			}
3266 			auto app = appender!string();
3267 			formattedWrite(app, 
3268 				"Found a '%s' while looking for", 
3269 				this.lex.front
3270 			);
3271 			throw new ParseException(app.data,
3272 				__FILE__, __LINE__,
3273 				subRules,
3274 				["name"]
3275 			);
3276 
3277 		}
3278 		auto app = appender!string();
3279 		formattedWrite(app, 
3280 			"Found a '%s' while looking for", 
3281 			this.lex.front
3282 		);
3283 		throw new ParseException(app.data,
3284 			__FILE__, __LINE__,
3285 			subRules,
3286 			["implements"]
3287 		);
3288 
3289 	}
3290 
3291 	bool firstNamedTypes() const pure @nogc @safe {
3292 		return this.lex.front.type == TokenType.name;
3293 	}
3294 
3295 	NamedTypes parseNamedTypes() {
3296 		try {
3297 			return this.parseNamedTypesImpl();
3298 		} catch(ParseException e) {
3299 			throw new ParseException(
3300 				"While parsing a NamedTypes an Exception was thrown.",
3301 				e, __FILE__, __LINE__
3302 			);
3303 		}
3304 	}
3305 
3306 	NamedTypes parseNamedTypesImpl() {
3307 		string[] subRules;
3308 		subRules = ["N", "NCS", "NS"];
3309 		if(this.lex.front.type == TokenType.name) {
3310 			Token name = this.lex.front;
3311 			this.lex.popFront();
3312 			subRules = ["NCS"];
3313 			if(this.lex.front.type == TokenType.comma) {
3314 				this.lex.popFront();
3315 				subRules = ["NCS"];
3316 				if(this.firstNamedTypes()) {
3317 					NamedTypes follow = this.parseNamedTypes();
3318 
3319 					return new NamedTypes(NamedTypesEnum.NCS
3320 						, name
3321 						, follow
3322 					);
3323 				}
3324 				auto app = appender!string();
3325 				formattedWrite(app, 
3326 					"Found a '%s' while looking for", 
3327 					this.lex.front
3328 				);
3329 				throw new ParseException(app.data,
3330 					__FILE__, __LINE__,
3331 					subRules,
3332 					["name"]
3333 				);
3334 
3335 			} else if(this.firstNamedTypes()) {
3336 				NamedTypes follow = this.parseNamedTypes();
3337 
3338 				return new NamedTypes(NamedTypesEnum.NS
3339 					, name
3340 					, follow
3341 				);
3342 			}
3343 			return new NamedTypes(NamedTypesEnum.N
3344 				, name
3345 			);
3346 		}
3347 		auto app = appender!string();
3348 		formattedWrite(app, 
3349 			"Found a '%s' while looking for", 
3350 			this.lex.front
3351 		);
3352 		throw new ParseException(app.data,
3353 			__FILE__, __LINE__,
3354 			subRules,
3355 			["name"]
3356 		);
3357 
3358 	}
3359 
3360 	bool firstArgumentsDefinition() const pure @nogc @safe {
3361 		return this.lex.front.type == TokenType.lparen;
3362 	}
3363 
3364 	ArgumentsDefinition parseArgumentsDefinition() {
3365 		try {
3366 			return this.parseArgumentsDefinitionImpl();
3367 		} catch(ParseException e) {
3368 			throw new ParseException(
3369 				"While parsing a ArgumentsDefinition an Exception was thrown.",
3370 				e, __FILE__, __LINE__
3371 			);
3372 		}
3373 	}
3374 
3375 	ArgumentsDefinition parseArgumentsDefinitionImpl() {
3376 		string[] subRules;
3377 		subRules = ["A"];
3378 		if(this.lex.front.type == TokenType.lparen) {
3379 			this.lex.popFront();
3380 			subRules = ["A"];
3381 			if(this.firstInputValueDefinitions()) {
3382 				this.parseInputValueDefinitions();
3383 				subRules = ["A"];
3384 				if(this.lex.front.type == TokenType.rparen) {
3385 					this.lex.popFront();
3386 
3387 					return new ArgumentsDefinition(ArgumentsDefinitionEnum.A
3388 					);
3389 				}
3390 				auto app = appender!string();
3391 				formattedWrite(app, 
3392 					"Found a '%s' while looking for", 
3393 					this.lex.front
3394 				);
3395 				throw new ParseException(app.data,
3396 					__FILE__, __LINE__,
3397 					subRules,
3398 					["rparen"]
3399 				);
3400 
3401 			}
3402 			auto app = appender!string();
3403 			formattedWrite(app, 
3404 				"Found a '%s' while looking for", 
3405 				this.lex.front
3406 			);
3407 			throw new ParseException(app.data,
3408 				__FILE__, __LINE__,
3409 				subRules,
3410 				["name -> InputValueDefinition"]
3411 			);
3412 
3413 		}
3414 		auto app = appender!string();
3415 		formattedWrite(app, 
3416 			"Found a '%s' while looking for", 
3417 			this.lex.front
3418 		);
3419 		throw new ParseException(app.data,
3420 			__FILE__, __LINE__,
3421 			subRules,
3422 			["lparen"]
3423 		);
3424 
3425 	}
3426 
3427 	bool firstInputValueDefinitions() const pure @nogc @safe {
3428 		return this.firstInputValueDefinition();
3429 	}
3430 
3431 	InputValueDefinitions parseInputValueDefinitions() {
3432 		try {
3433 			return this.parseInputValueDefinitionsImpl();
3434 		} catch(ParseException e) {
3435 			throw new ParseException(
3436 				"While parsing a InputValueDefinitions an Exception was thrown.",
3437 				e, __FILE__, __LINE__
3438 			);
3439 		}
3440 	}
3441 
3442 	InputValueDefinitions parseInputValueDefinitionsImpl() {
3443 		string[] subRules;
3444 		subRules = ["I", "ICF", "IF"];
3445 		if(this.firstInputValueDefinition()) {
3446 			InputValueDefinition iv = this.parseInputValueDefinition();
3447 			subRules = ["ICF"];
3448 			if(this.lex.front.type == TokenType.comma) {
3449 				this.lex.popFront();
3450 				subRules = ["ICF"];
3451 				if(this.firstInputValueDefinitions()) {
3452 					InputValueDefinitions follow = this.parseInputValueDefinitions();
3453 
3454 					return new InputValueDefinitions(InputValueDefinitionsEnum.ICF
3455 						, iv
3456 						, follow
3457 					);
3458 				}
3459 				auto app = appender!string();
3460 				formattedWrite(app, 
3461 					"Found a '%s' while looking for", 
3462 					this.lex.front
3463 				);
3464 				throw new ParseException(app.data,
3465 					__FILE__, __LINE__,
3466 					subRules,
3467 					["name -> InputValueDefinition"]
3468 				);
3469 
3470 			} else if(this.firstInputValueDefinitions()) {
3471 				InputValueDefinitions follow = this.parseInputValueDefinitions();
3472 
3473 				return new InputValueDefinitions(InputValueDefinitionsEnum.IF
3474 					, iv
3475 					, follow
3476 				);
3477 			}
3478 			return new InputValueDefinitions(InputValueDefinitionsEnum.I
3479 				, iv
3480 			);
3481 		}
3482 		auto app = appender!string();
3483 		formattedWrite(app, 
3484 			"Found a '%s' while looking for", 
3485 			this.lex.front
3486 		);
3487 		throw new ParseException(app.data,
3488 			__FILE__, __LINE__,
3489 			subRules,
3490 			["name"]
3491 		);
3492 
3493 	}
3494 
3495 	bool firstInputValueDefinition() const pure @nogc @safe {
3496 		return this.lex.front.type == TokenType.name;
3497 	}
3498 
3499 	InputValueDefinition parseInputValueDefinition() {
3500 		try {
3501 			return this.parseInputValueDefinitionImpl();
3502 		} catch(ParseException e) {
3503 			throw new ParseException(
3504 				"While parsing a InputValueDefinition an Exception was thrown.",
3505 				e, __FILE__, __LINE__
3506 			);
3507 		}
3508 	}
3509 
3510 	InputValueDefinition parseInputValueDefinitionImpl() {
3511 		string[] subRules;
3512 		subRules = ["T", "TD", "TV", "TVD"];
3513 		if(this.lex.front.type == TokenType.name) {
3514 			Token name = this.lex.front;
3515 			this.lex.popFront();
3516 			subRules = ["T", "TD", "TV", "TVD"];
3517 			if(this.lex.front.type == TokenType.colon) {
3518 				this.lex.popFront();
3519 				subRules = ["T", "TD", "TV", "TVD"];
3520 				if(this.firstType()) {
3521 					Type type = this.parseType();
3522 					subRules = ["TV", "TVD"];
3523 					if(this.firstDefaultValue()) {
3524 						DefaultValue df = this.parseDefaultValue();
3525 						subRules = ["TVD"];
3526 						if(this.firstDirectives()) {
3527 							Directives dirs = this.parseDirectives();
3528 
3529 							return new InputValueDefinition(InputValueDefinitionEnum.TVD
3530 								, name
3531 								, type
3532 								, df
3533 								, dirs
3534 							);
3535 						}
3536 						return new InputValueDefinition(InputValueDefinitionEnum.TV
3537 							, name
3538 							, type
3539 							, df
3540 						);
3541 					} else if(this.firstDirectives()) {
3542 						Directives dirs = this.parseDirectives();
3543 
3544 						return new InputValueDefinition(InputValueDefinitionEnum.TD
3545 							, name
3546 							, type
3547 							, dirs
3548 						);
3549 					}
3550 					return new InputValueDefinition(InputValueDefinitionEnum.T
3551 						, name
3552 						, type
3553 					);
3554 				}
3555 				auto app = appender!string();
3556 				formattedWrite(app, 
3557 					"Found a '%s' while looking for", 
3558 					this.lex.front
3559 				);
3560 				throw new ParseException(app.data,
3561 					__FILE__, __LINE__,
3562 					subRules,
3563 					["lbrack -> ListType","name"]
3564 				);
3565 
3566 			}
3567 			auto app = appender!string();
3568 			formattedWrite(app, 
3569 				"Found a '%s' while looking for", 
3570 				this.lex.front
3571 			);
3572 			throw new ParseException(app.data,
3573 				__FILE__, __LINE__,
3574 				subRules,
3575 				["colon"]
3576 			);
3577 
3578 		}
3579 		auto app = appender!string();
3580 		formattedWrite(app, 
3581 			"Found a '%s' while looking for", 
3582 			this.lex.front
3583 		);
3584 		throw new ParseException(app.data,
3585 			__FILE__, __LINE__,
3586 			subRules,
3587 			["name"]
3588 		);
3589 
3590 	}
3591 
3592 	bool firstInterfaceTypeDefinition() const pure @nogc @safe {
3593 		return this.lex.front.type == TokenType.interface_;
3594 	}
3595 
3596 	InterfaceTypeDefinition parseInterfaceTypeDefinition() {
3597 		try {
3598 			return this.parseInterfaceTypeDefinitionImpl();
3599 		} catch(ParseException e) {
3600 			throw new ParseException(
3601 				"While parsing a InterfaceTypeDefinition an Exception was thrown.",
3602 				e, __FILE__, __LINE__
3603 			);
3604 		}
3605 	}
3606 
3607 	InterfaceTypeDefinition parseInterfaceTypeDefinitionImpl() {
3608 		string[] subRules;
3609 		subRules = ["NDF", "NF"];
3610 		if(this.lex.front.type == TokenType.interface_) {
3611 			this.lex.popFront();
3612 			subRules = ["NDF", "NF"];
3613 			if(this.lex.front.type == TokenType.name) {
3614 				Token name = this.lex.front;
3615 				this.lex.popFront();
3616 				subRules = ["NDF"];
3617 				if(this.firstDirectives()) {
3618 					Directives dirs = this.parseDirectives();
3619 					subRules = ["NDF"];
3620 					if(this.lex.front.type == TokenType.lcurly) {
3621 						this.lex.popFront();
3622 						subRules = ["NDF"];
3623 						if(this.firstFieldDefinitions()) {
3624 							FieldDefinitions fds = this.parseFieldDefinitions();
3625 							subRules = ["NDF"];
3626 							if(this.lex.front.type == TokenType.rcurly) {
3627 								this.lex.popFront();
3628 
3629 								return new InterfaceTypeDefinition(InterfaceTypeDefinitionEnum.NDF
3630 									, name
3631 									, dirs
3632 									, fds
3633 								);
3634 							}
3635 							auto app = appender!string();
3636 							formattedWrite(app, 
3637 								"Found a '%s' while looking for", 
3638 								this.lex.front
3639 							);
3640 							throw new ParseException(app.data,
3641 								__FILE__, __LINE__,
3642 								subRules,
3643 								["rcurly"]
3644 							);
3645 
3646 						}
3647 						auto app = appender!string();
3648 						formattedWrite(app, 
3649 							"Found a '%s' while looking for", 
3650 							this.lex.front
3651 						);
3652 						throw new ParseException(app.data,
3653 							__FILE__, __LINE__,
3654 							subRules,
3655 							["name -> FieldDefinition"]
3656 						);
3657 
3658 					}
3659 					auto app = appender!string();
3660 					formattedWrite(app, 
3661 						"Found a '%s' while looking for", 
3662 						this.lex.front
3663 					);
3664 					throw new ParseException(app.data,
3665 						__FILE__, __LINE__,
3666 						subRules,
3667 						["lcurly"]
3668 					);
3669 
3670 				} else if(this.lex.front.type == TokenType.lcurly) {
3671 					this.lex.popFront();
3672 					subRules = ["NF"];
3673 					if(this.firstFieldDefinitions()) {
3674 						FieldDefinitions fds = this.parseFieldDefinitions();
3675 						subRules = ["NF"];
3676 						if(this.lex.front.type == TokenType.rcurly) {
3677 							this.lex.popFront();
3678 
3679 							return new InterfaceTypeDefinition(InterfaceTypeDefinitionEnum.NF
3680 								, name
3681 								, fds
3682 							);
3683 						}
3684 						auto app = appender!string();
3685 						formattedWrite(app, 
3686 							"Found a '%s' while looking for", 
3687 							this.lex.front
3688 						);
3689 						throw new ParseException(app.data,
3690 							__FILE__, __LINE__,
3691 							subRules,
3692 							["rcurly"]
3693 						);
3694 
3695 					}
3696 					auto app = appender!string();
3697 					formattedWrite(app, 
3698 						"Found a '%s' while looking for", 
3699 						this.lex.front
3700 					);
3701 					throw new ParseException(app.data,
3702 						__FILE__, __LINE__,
3703 						subRules,
3704 						["name -> FieldDefinition"]
3705 					);
3706 
3707 				}
3708 				auto app = appender!string();
3709 				formattedWrite(app, 
3710 					"Found a '%s' while looking for", 
3711 					this.lex.front
3712 				);
3713 				throw new ParseException(app.data,
3714 					__FILE__, __LINE__,
3715 					subRules,
3716 					["at -> Directive","lcurly"]
3717 				);
3718 
3719 			}
3720 			auto app = appender!string();
3721 			formattedWrite(app, 
3722 				"Found a '%s' while looking for", 
3723 				this.lex.front
3724 			);
3725 			throw new ParseException(app.data,
3726 				__FILE__, __LINE__,
3727 				subRules,
3728 				["name"]
3729 			);
3730 
3731 		}
3732 		auto app = appender!string();
3733 		formattedWrite(app, 
3734 			"Found a '%s' while looking for", 
3735 			this.lex.front
3736 		);
3737 		throw new ParseException(app.data,
3738 			__FILE__, __LINE__,
3739 			subRules,
3740 			["interface_"]
3741 		);
3742 
3743 	}
3744 
3745 	bool firstUnionTypeDefinition() const pure @nogc @safe {
3746 		return this.lex.front.type == TokenType.union_;
3747 	}
3748 
3749 	UnionTypeDefinition parseUnionTypeDefinition() {
3750 		try {
3751 			return this.parseUnionTypeDefinitionImpl();
3752 		} catch(ParseException e) {
3753 			throw new ParseException(
3754 				"While parsing a UnionTypeDefinition an Exception was thrown.",
3755 				e, __FILE__, __LINE__
3756 			);
3757 		}
3758 	}
3759 
3760 	UnionTypeDefinition parseUnionTypeDefinitionImpl() {
3761 		string[] subRules;
3762 		subRules = ["NDU", "NU"];
3763 		if(this.lex.front.type == TokenType.union_) {
3764 			this.lex.popFront();
3765 			subRules = ["NDU", "NU"];
3766 			if(this.lex.front.type == TokenType.name) {
3767 				Token name = this.lex.front;
3768 				this.lex.popFront();
3769 				subRules = ["NDU"];
3770 				if(this.firstDirectives()) {
3771 					Directives dirs = this.parseDirectives();
3772 					subRules = ["NDU"];
3773 					if(this.lex.front.type == TokenType.equal) {
3774 						this.lex.popFront();
3775 						subRules = ["NDU"];
3776 						if(this.firstUnionMembers()) {
3777 							UnionMembers um = this.parseUnionMembers();
3778 
3779 							return new UnionTypeDefinition(UnionTypeDefinitionEnum.NDU
3780 								, name
3781 								, dirs
3782 								, um
3783 							);
3784 						}
3785 						auto app = appender!string();
3786 						formattedWrite(app, 
3787 							"Found a '%s' while looking for", 
3788 							this.lex.front
3789 						);
3790 						throw new ParseException(app.data,
3791 							__FILE__, __LINE__,
3792 							subRules,
3793 							["name"]
3794 						);
3795 
3796 					}
3797 					auto app = appender!string();
3798 					formattedWrite(app, 
3799 						"Found a '%s' while looking for", 
3800 						this.lex.front
3801 					);
3802 					throw new ParseException(app.data,
3803 						__FILE__, __LINE__,
3804 						subRules,
3805 						["equal"]
3806 					);
3807 
3808 				} else if(this.lex.front.type == TokenType.equal) {
3809 					this.lex.popFront();
3810 					subRules = ["NU"];
3811 					if(this.firstUnionMembers()) {
3812 						UnionMembers um = this.parseUnionMembers();
3813 
3814 						return new UnionTypeDefinition(UnionTypeDefinitionEnum.NU
3815 							, name
3816 							, um
3817 						);
3818 					}
3819 					auto app = appender!string();
3820 					formattedWrite(app, 
3821 						"Found a '%s' while looking for", 
3822 						this.lex.front
3823 					);
3824 					throw new ParseException(app.data,
3825 						__FILE__, __LINE__,
3826 						subRules,
3827 						["name"]
3828 					);
3829 
3830 				}
3831 				auto app = appender!string();
3832 				formattedWrite(app, 
3833 					"Found a '%s' while looking for", 
3834 					this.lex.front
3835 				);
3836 				throw new ParseException(app.data,
3837 					__FILE__, __LINE__,
3838 					subRules,
3839 					["at -> Directive","equal"]
3840 				);
3841 
3842 			}
3843 			auto app = appender!string();
3844 			formattedWrite(app, 
3845 				"Found a '%s' while looking for", 
3846 				this.lex.front
3847 			);
3848 			throw new ParseException(app.data,
3849 				__FILE__, __LINE__,
3850 				subRules,
3851 				["name"]
3852 			);
3853 
3854 		}
3855 		auto app = appender!string();
3856 		formattedWrite(app, 
3857 			"Found a '%s' while looking for", 
3858 			this.lex.front
3859 		);
3860 		throw new ParseException(app.data,
3861 			__FILE__, __LINE__,
3862 			subRules,
3863 			["union_"]
3864 		);
3865 
3866 	}
3867 
3868 	bool firstUnionMembers() const pure @nogc @safe {
3869 		return this.lex.front.type == TokenType.name;
3870 	}
3871 
3872 	UnionMembers parseUnionMembers() {
3873 		try {
3874 			return this.parseUnionMembersImpl();
3875 		} catch(ParseException e) {
3876 			throw new ParseException(
3877 				"While parsing a UnionMembers an Exception was thrown.",
3878 				e, __FILE__, __LINE__
3879 			);
3880 		}
3881 	}
3882 
3883 	UnionMembers parseUnionMembersImpl() {
3884 		string[] subRules;
3885 		subRules = ["S", "SF", "SPF"];
3886 		if(this.lex.front.type == TokenType.name) {
3887 			Token name = this.lex.front;
3888 			this.lex.popFront();
3889 			subRules = ["SPF"];
3890 			if(this.lex.front.type == TokenType.pipe) {
3891 				this.lex.popFront();
3892 				subRules = ["SPF"];
3893 				if(this.firstUnionMembers()) {
3894 					UnionMembers follow = this.parseUnionMembers();
3895 
3896 					return new UnionMembers(UnionMembersEnum.SPF
3897 						, name
3898 						, follow
3899 					);
3900 				}
3901 				auto app = appender!string();
3902 				formattedWrite(app, 
3903 					"Found a '%s' while looking for", 
3904 					this.lex.front
3905 				);
3906 				throw new ParseException(app.data,
3907 					__FILE__, __LINE__,
3908 					subRules,
3909 					["name"]
3910 				);
3911 
3912 			} else if(this.firstUnionMembers()) {
3913 				UnionMembers follow = this.parseUnionMembers();
3914 
3915 				return new UnionMembers(UnionMembersEnum.SF
3916 					, name
3917 					, follow
3918 				);
3919 			}
3920 			return new UnionMembers(UnionMembersEnum.S
3921 				, name
3922 			);
3923 		}
3924 		auto app = appender!string();
3925 		formattedWrite(app, 
3926 			"Found a '%s' while looking for", 
3927 			this.lex.front
3928 		);
3929 		throw new ParseException(app.data,
3930 			__FILE__, __LINE__,
3931 			subRules,
3932 			["name"]
3933 		);
3934 
3935 	}
3936 
3937 	bool firstEnumTypeDefinition() const pure @nogc @safe {
3938 		return this.lex.front.type == TokenType.enum_;
3939 	}
3940 
3941 	EnumTypeDefinition parseEnumTypeDefinition() {
3942 		try {
3943 			return this.parseEnumTypeDefinitionImpl();
3944 		} catch(ParseException e) {
3945 			throw new ParseException(
3946 				"While parsing a EnumTypeDefinition an Exception was thrown.",
3947 				e, __FILE__, __LINE__
3948 			);
3949 		}
3950 	}
3951 
3952 	EnumTypeDefinition parseEnumTypeDefinitionImpl() {
3953 		string[] subRules;
3954 		subRules = ["NDE", "NE"];
3955 		if(this.lex.front.type == TokenType.enum_) {
3956 			this.lex.popFront();
3957 			subRules = ["NDE", "NE"];
3958 			if(this.lex.front.type == TokenType.name) {
3959 				Token name = this.lex.front;
3960 				this.lex.popFront();
3961 				subRules = ["NDE"];
3962 				if(this.firstDirectives()) {
3963 					Directives dir = this.parseDirectives();
3964 					subRules = ["NDE"];
3965 					if(this.lex.front.type == TokenType.lcurly) {
3966 						this.lex.popFront();
3967 						subRules = ["NDE"];
3968 						if(this.firstEnumValueDefinitions()) {
3969 							EnumValueDefinitions evds = this.parseEnumValueDefinitions();
3970 							subRules = ["NDE"];
3971 							if(this.lex.front.type == TokenType.rcurly) {
3972 								this.lex.popFront();
3973 
3974 								return new EnumTypeDefinition(EnumTypeDefinitionEnum.NDE
3975 									, name
3976 									, dir
3977 									, evds
3978 								);
3979 							}
3980 							auto app = appender!string();
3981 							formattedWrite(app, 
3982 								"Found a '%s' while looking for", 
3983 								this.lex.front
3984 							);
3985 							throw new ParseException(app.data,
3986 								__FILE__, __LINE__,
3987 								subRules,
3988 								["rcurly"]
3989 							);
3990 
3991 						}
3992 						auto app = appender!string();
3993 						formattedWrite(app, 
3994 							"Found a '%s' while looking for", 
3995 							this.lex.front
3996 						);
3997 						throw new ParseException(app.data,
3998 							__FILE__, __LINE__,
3999 							subRules,
4000 							["name -> EnumValueDefinition"]
4001 						);
4002 
4003 					}
4004 					auto app = appender!string();
4005 					formattedWrite(app, 
4006 						"Found a '%s' while looking for", 
4007 						this.lex.front
4008 					);
4009 					throw new ParseException(app.data,
4010 						__FILE__, __LINE__,
4011 						subRules,
4012 						["lcurly"]
4013 					);
4014 
4015 				} else if(this.lex.front.type == TokenType.lcurly) {
4016 					this.lex.popFront();
4017 					subRules = ["NE"];
4018 					if(this.firstEnumValueDefinitions()) {
4019 						EnumValueDefinitions evds = this.parseEnumValueDefinitions();
4020 						subRules = ["NE"];
4021 						if(this.lex.front.type == TokenType.rcurly) {
4022 							this.lex.popFront();
4023 
4024 							return new EnumTypeDefinition(EnumTypeDefinitionEnum.NE
4025 								, name
4026 								, evds
4027 							);
4028 						}
4029 						auto app = appender!string();
4030 						formattedWrite(app, 
4031 							"Found a '%s' while looking for", 
4032 							this.lex.front
4033 						);
4034 						throw new ParseException(app.data,
4035 							__FILE__, __LINE__,
4036 							subRules,
4037 							["rcurly"]
4038 						);
4039 
4040 					}
4041 					auto app = appender!string();
4042 					formattedWrite(app, 
4043 						"Found a '%s' while looking for", 
4044 						this.lex.front
4045 					);
4046 					throw new ParseException(app.data,
4047 						__FILE__, __LINE__,
4048 						subRules,
4049 						["name -> EnumValueDefinition"]
4050 					);
4051 
4052 				}
4053 				auto app = appender!string();
4054 				formattedWrite(app, 
4055 					"Found a '%s' while looking for", 
4056 					this.lex.front
4057 				);
4058 				throw new ParseException(app.data,
4059 					__FILE__, __LINE__,
4060 					subRules,
4061 					["at -> Directive","lcurly"]
4062 				);
4063 
4064 			}
4065 			auto app = appender!string();
4066 			formattedWrite(app, 
4067 				"Found a '%s' while looking for", 
4068 				this.lex.front
4069 			);
4070 			throw new ParseException(app.data,
4071 				__FILE__, __LINE__,
4072 				subRules,
4073 				["name"]
4074 			);
4075 
4076 		}
4077 		auto app = appender!string();
4078 		formattedWrite(app, 
4079 			"Found a '%s' while looking for", 
4080 			this.lex.front
4081 		);
4082 		throw new ParseException(app.data,
4083 			__FILE__, __LINE__,
4084 			subRules,
4085 			["enum_"]
4086 		);
4087 
4088 	}
4089 
4090 	bool firstEnumValueDefinitions() const pure @nogc @safe {
4091 		return this.firstEnumValueDefinition();
4092 	}
4093 
4094 	EnumValueDefinitions parseEnumValueDefinitions() {
4095 		try {
4096 			return this.parseEnumValueDefinitionsImpl();
4097 		} catch(ParseException e) {
4098 			throw new ParseException(
4099 				"While parsing a EnumValueDefinitions an Exception was thrown.",
4100 				e, __FILE__, __LINE__
4101 			);
4102 		}
4103 	}
4104 
4105 	EnumValueDefinitions parseEnumValueDefinitionsImpl() {
4106 		string[] subRules;
4107 		subRules = ["D", "DCE", "DE"];
4108 		if(this.firstEnumValueDefinition()) {
4109 			EnumValueDefinition evd = this.parseEnumValueDefinition();
4110 			subRules = ["DCE"];
4111 			if(this.lex.front.type == TokenType.comma) {
4112 				this.lex.popFront();
4113 				subRules = ["DCE"];
4114 				if(this.firstEnumValueDefinitions()) {
4115 					EnumValueDefinitions follow = this.parseEnumValueDefinitions();
4116 
4117 					return new EnumValueDefinitions(EnumValueDefinitionsEnum.DCE
4118 						, evd
4119 						, follow
4120 					);
4121 				}
4122 				auto app = appender!string();
4123 				formattedWrite(app, 
4124 					"Found a '%s' while looking for", 
4125 					this.lex.front
4126 				);
4127 				throw new ParseException(app.data,
4128 					__FILE__, __LINE__,
4129 					subRules,
4130 					["name -> EnumValueDefinition"]
4131 				);
4132 
4133 			} else if(this.firstEnumValueDefinitions()) {
4134 				EnumValueDefinitions follow = this.parseEnumValueDefinitions();
4135 
4136 				return new EnumValueDefinitions(EnumValueDefinitionsEnum.DE
4137 					, evd
4138 					, follow
4139 				);
4140 			}
4141 			return new EnumValueDefinitions(EnumValueDefinitionsEnum.D
4142 				, evd
4143 			);
4144 		}
4145 		auto app = appender!string();
4146 		formattedWrite(app, 
4147 			"Found a '%s' while looking for", 
4148 			this.lex.front
4149 		);
4150 		throw new ParseException(app.data,
4151 			__FILE__, __LINE__,
4152 			subRules,
4153 			["name"]
4154 		);
4155 
4156 	}
4157 
4158 	bool firstEnumValueDefinition() const pure @nogc @safe {
4159 		return this.lex.front.type == TokenType.name;
4160 	}
4161 
4162 	EnumValueDefinition parseEnumValueDefinition() {
4163 		try {
4164 			return this.parseEnumValueDefinitionImpl();
4165 		} catch(ParseException e) {
4166 			throw new ParseException(
4167 				"While parsing a EnumValueDefinition an Exception was thrown.",
4168 				e, __FILE__, __LINE__
4169 			);
4170 		}
4171 	}
4172 
4173 	EnumValueDefinition parseEnumValueDefinitionImpl() {
4174 		string[] subRules;
4175 		subRules = ["E", "ED"];
4176 		if(this.lex.front.type == TokenType.name) {
4177 			Token name = this.lex.front;
4178 			this.lex.popFront();
4179 			subRules = ["ED"];
4180 			if(this.firstDirectives()) {
4181 				Directives dirs = this.parseDirectives();
4182 
4183 				return new EnumValueDefinition(EnumValueDefinitionEnum.ED
4184 					, name
4185 					, dirs
4186 				);
4187 			}
4188 			return new EnumValueDefinition(EnumValueDefinitionEnum.E
4189 				, name
4190 			);
4191 		}
4192 		auto app = appender!string();
4193 		formattedWrite(app, 
4194 			"Found a '%s' while looking for", 
4195 			this.lex.front
4196 		);
4197 		throw new ParseException(app.data,
4198 			__FILE__, __LINE__,
4199 			subRules,
4200 			["name"]
4201 		);
4202 
4203 	}
4204 
4205 	bool firstInputTypeDefinition() const pure @nogc @safe {
4206 		return this.lex.front.type == TokenType.input;
4207 	}
4208 
4209 	InputTypeDefinition parseInputTypeDefinition() {
4210 		try {
4211 			return this.parseInputTypeDefinitionImpl();
4212 		} catch(ParseException e) {
4213 			throw new ParseException(
4214 				"While parsing a InputTypeDefinition an Exception was thrown.",
4215 				e, __FILE__, __LINE__
4216 			);
4217 		}
4218 	}
4219 
4220 	InputTypeDefinition parseInputTypeDefinitionImpl() {
4221 		string[] subRules;
4222 		subRules = ["NDE", "NE"];
4223 		if(this.lex.front.type == TokenType.input) {
4224 			this.lex.popFront();
4225 			subRules = ["NDE", "NE"];
4226 			if(this.lex.front.type == TokenType.name) {
4227 				Token name = this.lex.front;
4228 				this.lex.popFront();
4229 				subRules = ["NDE"];
4230 				if(this.firstDirectives()) {
4231 					Directives dir = this.parseDirectives();
4232 					subRules = ["NDE"];
4233 					if(this.lex.front.type == TokenType.lcurly) {
4234 						this.lex.popFront();
4235 						subRules = ["NDE"];
4236 						if(this.firstInputValueDefinitions()) {
4237 							InputValueDefinitions ivds = this.parseInputValueDefinitions();
4238 							subRules = ["NDE"];
4239 							if(this.lex.front.type == TokenType.rcurly) {
4240 								this.lex.popFront();
4241 
4242 								return new InputTypeDefinition(InputTypeDefinitionEnum.NDE
4243 									, name
4244 									, dir
4245 									, ivds
4246 								);
4247 							}
4248 							auto app = appender!string();
4249 							formattedWrite(app, 
4250 								"Found a '%s' while looking for", 
4251 								this.lex.front
4252 							);
4253 							throw new ParseException(app.data,
4254 								__FILE__, __LINE__,
4255 								subRules,
4256 								["rcurly"]
4257 							);
4258 
4259 						}
4260 						auto app = appender!string();
4261 						formattedWrite(app, 
4262 							"Found a '%s' while looking for", 
4263 							this.lex.front
4264 						);
4265 						throw new ParseException(app.data,
4266 							__FILE__, __LINE__,
4267 							subRules,
4268 							["name -> InputValueDefinition"]
4269 						);
4270 
4271 					}
4272 					auto app = appender!string();
4273 					formattedWrite(app, 
4274 						"Found a '%s' while looking for", 
4275 						this.lex.front
4276 					);
4277 					throw new ParseException(app.data,
4278 						__FILE__, __LINE__,
4279 						subRules,
4280 						["lcurly"]
4281 					);
4282 
4283 				} else if(this.lex.front.type == TokenType.lcurly) {
4284 					this.lex.popFront();
4285 					subRules = ["NE"];
4286 					if(this.firstInputValueDefinitions()) {
4287 						InputValueDefinitions ivds = this.parseInputValueDefinitions();
4288 						subRules = ["NE"];
4289 						if(this.lex.front.type == TokenType.rcurly) {
4290 							this.lex.popFront();
4291 
4292 							return new InputTypeDefinition(InputTypeDefinitionEnum.NE
4293 								, name
4294 								, ivds
4295 							);
4296 						}
4297 						auto app = appender!string();
4298 						formattedWrite(app, 
4299 							"Found a '%s' while looking for", 
4300 							this.lex.front
4301 						);
4302 						throw new ParseException(app.data,
4303 							__FILE__, __LINE__,
4304 							subRules,
4305 							["rcurly"]
4306 						);
4307 
4308 					}
4309 					auto app = appender!string();
4310 					formattedWrite(app, 
4311 						"Found a '%s' while looking for", 
4312 						this.lex.front
4313 					);
4314 					throw new ParseException(app.data,
4315 						__FILE__, __LINE__,
4316 						subRules,
4317 						["name -> InputValueDefinition"]
4318 					);
4319 
4320 				}
4321 				auto app = appender!string();
4322 				formattedWrite(app, 
4323 					"Found a '%s' while looking for", 
4324 					this.lex.front
4325 				);
4326 				throw new ParseException(app.data,
4327 					__FILE__, __LINE__,
4328 					subRules,
4329 					["at -> Directive","lcurly"]
4330 				);
4331 
4332 			}
4333 			auto app = appender!string();
4334 			formattedWrite(app, 
4335 				"Found a '%s' while looking for", 
4336 				this.lex.front
4337 			);
4338 			throw new ParseException(app.data,
4339 				__FILE__, __LINE__,
4340 				subRules,
4341 				["name"]
4342 			);
4343 
4344 		}
4345 		auto app = appender!string();
4346 		formattedWrite(app, 
4347 			"Found a '%s' while looking for", 
4348 			this.lex.front
4349 		);
4350 		throw new ParseException(app.data,
4351 			__FILE__, __LINE__,
4352 			subRules,
4353 			["input"]
4354 		);
4355 
4356 	}
4357 
4358 	bool firstTypeExtensionDefinition() const pure @nogc @safe {
4359 		return this.lex.front.type == TokenType.extend;
4360 	}
4361 
4362 	TypeExtensionDefinition parseTypeExtensionDefinition() {
4363 		try {
4364 			return this.parseTypeExtensionDefinitionImpl();
4365 		} catch(ParseException e) {
4366 			throw new ParseException(
4367 				"While parsing a TypeExtensionDefinition an Exception was thrown.",
4368 				e, __FILE__, __LINE__
4369 			);
4370 		}
4371 	}
4372 
4373 	TypeExtensionDefinition parseTypeExtensionDefinitionImpl() {
4374 		string[] subRules;
4375 		subRules = ["O"];
4376 		if(this.lex.front.type == TokenType.extend) {
4377 			this.lex.popFront();
4378 			subRules = ["O"];
4379 			if(this.firstObjectTypeDefinition()) {
4380 				ObjectTypeDefinition otd = this.parseObjectTypeDefinition();
4381 
4382 				return new TypeExtensionDefinition(TypeExtensionDefinitionEnum.O
4383 					, otd
4384 				);
4385 			}
4386 			auto app = appender!string();
4387 			formattedWrite(app, 
4388 				"Found a '%s' while looking for", 
4389 				this.lex.front
4390 			);
4391 			throw new ParseException(app.data,
4392 				__FILE__, __LINE__,
4393 				subRules,
4394 				["type"]
4395 			);
4396 
4397 		}
4398 		auto app = appender!string();
4399 		formattedWrite(app, 
4400 			"Found a '%s' while looking for", 
4401 			this.lex.front
4402 		);
4403 		throw new ParseException(app.data,
4404 			__FILE__, __LINE__,
4405 			subRules,
4406 			["extend"]
4407 		);
4408 
4409 	}
4410 
4411 	bool firstDirectiveDefinition() const pure @nogc @safe {
4412 		return this.lex.front.type == TokenType.directive;
4413 	}
4414 
4415 	DirectiveDefinition parseDirectiveDefinition() {
4416 		try {
4417 			return this.parseDirectiveDefinitionImpl();
4418 		} catch(ParseException e) {
4419 			throw new ParseException(
4420 				"While parsing a DirectiveDefinition an Exception was thrown.",
4421 				e, __FILE__, __LINE__
4422 			);
4423 		}
4424 	}
4425 
4426 	DirectiveDefinition parseDirectiveDefinitionImpl() {
4427 		string[] subRules;
4428 		subRules = ["AD", "D"];
4429 		if(this.lex.front.type == TokenType.directive) {
4430 			this.lex.popFront();
4431 			subRules = ["AD", "D"];
4432 			if(this.lex.front.type == TokenType.at) {
4433 				this.lex.popFront();
4434 				subRules = ["AD", "D"];
4435 				if(this.lex.front.type == TokenType.name) {
4436 					Token name = this.lex.front;
4437 					this.lex.popFront();
4438 					subRules = ["AD"];
4439 					if(this.firstArgumentsDefinition()) {
4440 						ArgumentsDefinition ad = this.parseArgumentsDefinition();
4441 						subRules = ["AD"];
4442 						if(this.lex.front.type == TokenType.on_) {
4443 							this.lex.popFront();
4444 							subRules = ["AD"];
4445 							if(this.firstDirectiveLocations()) {
4446 								DirectiveLocations dl = this.parseDirectiveLocations();
4447 
4448 								return new DirectiveDefinition(DirectiveDefinitionEnum.AD
4449 									, name
4450 									, ad
4451 									, dl
4452 								);
4453 							}
4454 							auto app = appender!string();
4455 							formattedWrite(app, 
4456 								"Found a '%s' while looking for", 
4457 								this.lex.front
4458 							);
4459 							throw new ParseException(app.data,
4460 								__FILE__, __LINE__,
4461 								subRules,
4462 								["name"]
4463 							);
4464 
4465 						}
4466 						auto app = appender!string();
4467 						formattedWrite(app, 
4468 							"Found a '%s' while looking for", 
4469 							this.lex.front
4470 						);
4471 						throw new ParseException(app.data,
4472 							__FILE__, __LINE__,
4473 							subRules,
4474 							["on_"]
4475 						);
4476 
4477 					} else if(this.lex.front.type == TokenType.on_) {
4478 						this.lex.popFront();
4479 						subRules = ["D"];
4480 						if(this.firstDirectiveLocations()) {
4481 							DirectiveLocations dl = this.parseDirectiveLocations();
4482 
4483 							return new DirectiveDefinition(DirectiveDefinitionEnum.D
4484 								, name
4485 								, dl
4486 							);
4487 						}
4488 						auto app = appender!string();
4489 						formattedWrite(app, 
4490 							"Found a '%s' while looking for", 
4491 							this.lex.front
4492 						);
4493 						throw new ParseException(app.data,
4494 							__FILE__, __LINE__,
4495 							subRules,
4496 							["name"]
4497 						);
4498 
4499 					}
4500 					auto app = appender!string();
4501 					formattedWrite(app, 
4502 						"Found a '%s' while looking for", 
4503 						this.lex.front
4504 					);
4505 					throw new ParseException(app.data,
4506 						__FILE__, __LINE__,
4507 						subRules,
4508 						["lparen","on_"]
4509 					);
4510 
4511 				}
4512 				auto app = appender!string();
4513 				formattedWrite(app, 
4514 					"Found a '%s' while looking for", 
4515 					this.lex.front
4516 				);
4517 				throw new ParseException(app.data,
4518 					__FILE__, __LINE__,
4519 					subRules,
4520 					["name"]
4521 				);
4522 
4523 			}
4524 			auto app = appender!string();
4525 			formattedWrite(app, 
4526 				"Found a '%s' while looking for", 
4527 				this.lex.front
4528 			);
4529 			throw new ParseException(app.data,
4530 				__FILE__, __LINE__,
4531 				subRules,
4532 				["at"]
4533 			);
4534 
4535 		}
4536 		auto app = appender!string();
4537 		formattedWrite(app, 
4538 			"Found a '%s' while looking for", 
4539 			this.lex.front
4540 		);
4541 		throw new ParseException(app.data,
4542 			__FILE__, __LINE__,
4543 			subRules,
4544 			["directive"]
4545 		);
4546 
4547 	}
4548 
4549 	bool firstDirectiveLocations() const pure @nogc @safe {
4550 		return this.lex.front.type == TokenType.name;
4551 	}
4552 
4553 	DirectiveLocations parseDirectiveLocations() {
4554 		try {
4555 			return this.parseDirectiveLocationsImpl();
4556 		} catch(ParseException e) {
4557 			throw new ParseException(
4558 				"While parsing a DirectiveLocations an Exception was thrown.",
4559 				e, __FILE__, __LINE__
4560 			);
4561 		}
4562 	}
4563 
4564 	DirectiveLocations parseDirectiveLocationsImpl() {
4565 		string[] subRules;
4566 		subRules = ["N", "NF", "NPF"];
4567 		if(this.lex.front.type == TokenType.name) {
4568 			Token name = this.lex.front;
4569 			this.lex.popFront();
4570 			subRules = ["NPF"];
4571 			if(this.lex.front.type == TokenType.pipe) {
4572 				this.lex.popFront();
4573 				subRules = ["NPF"];
4574 				if(this.firstDirectiveLocations()) {
4575 					DirectiveLocations follow = this.parseDirectiveLocations();
4576 
4577 					return new DirectiveLocations(DirectiveLocationsEnum.NPF
4578 						, name
4579 						, follow
4580 					);
4581 				}
4582 				auto app = appender!string();
4583 				formattedWrite(app, 
4584 					"Found a '%s' while looking for", 
4585 					this.lex.front
4586 				);
4587 				throw new ParseException(app.data,
4588 					__FILE__, __LINE__,
4589 					subRules,
4590 					["name"]
4591 				);
4592 
4593 			} else if(this.firstDirectiveLocations()) {
4594 				DirectiveLocations follow = this.parseDirectiveLocations();
4595 
4596 				return new DirectiveLocations(DirectiveLocationsEnum.NF
4597 					, name
4598 					, follow
4599 				);
4600 			}
4601 			return new DirectiveLocations(DirectiveLocationsEnum.N
4602 				, name
4603 			);
4604 		}
4605 		auto app = appender!string();
4606 		formattedWrite(app, 
4607 			"Found a '%s' while looking for", 
4608 			this.lex.front
4609 		);
4610 		throw new ParseException(app.data,
4611 			__FILE__, __LINE__,
4612 			subRules,
4613 			["name"]
4614 		);
4615 
4616 	}
4617 
4618 	bool firstInputObjectTypeDefinition() const pure @nogc @safe {
4619 		return this.lex.front.type == TokenType.input;
4620 	}
4621 
4622 	InputObjectTypeDefinition parseInputObjectTypeDefinition() {
4623 		try {
4624 			return this.parseInputObjectTypeDefinitionImpl();
4625 		} catch(ParseException e) {
4626 			throw new ParseException(
4627 				"While parsing a InputObjectTypeDefinition an Exception was thrown.",
4628 				e, __FILE__, __LINE__
4629 			);
4630 		}
4631 	}
4632 
4633 	InputObjectTypeDefinition parseInputObjectTypeDefinitionImpl() {
4634 		string[] subRules;
4635 		subRules = ["NDI", "NI"];
4636 		if(this.lex.front.type == TokenType.input) {
4637 			this.lex.popFront();
4638 			subRules = ["NDI", "NI"];
4639 			if(this.lex.front.type == TokenType.name) {
4640 				Token name = this.lex.front;
4641 				this.lex.popFront();
4642 				subRules = ["NDI"];
4643 				if(this.firstDirectives()) {
4644 					Directives dirs = this.parseDirectives();
4645 					subRules = ["NDI"];
4646 					if(this.lex.front.type == TokenType.lcurly) {
4647 						this.lex.popFront();
4648 						subRules = ["NDI"];
4649 						if(this.firstInputValueDefinitions()) {
4650 							this.parseInputValueDefinitions();
4651 							subRules = ["NDI"];
4652 							if(this.lex.front.type == TokenType.rcurly) {
4653 								this.lex.popFront();
4654 
4655 								return new InputObjectTypeDefinition(InputObjectTypeDefinitionEnum.NDI
4656 									, name
4657 									, dirs
4658 								);
4659 							}
4660 							auto app = appender!string();
4661 							formattedWrite(app, 
4662 								"Found a '%s' while looking for", 
4663 								this.lex.front
4664 							);
4665 							throw new ParseException(app.data,
4666 								__FILE__, __LINE__,
4667 								subRules,
4668 								["rcurly"]
4669 							);
4670 
4671 						}
4672 						auto app = appender!string();
4673 						formattedWrite(app, 
4674 							"Found a '%s' while looking for", 
4675 							this.lex.front
4676 						);
4677 						throw new ParseException(app.data,
4678 							__FILE__, __LINE__,
4679 							subRules,
4680 							["name -> InputValueDefinition"]
4681 						);
4682 
4683 					}
4684 					auto app = appender!string();
4685 					formattedWrite(app, 
4686 						"Found a '%s' while looking for", 
4687 						this.lex.front
4688 					);
4689 					throw new ParseException(app.data,
4690 						__FILE__, __LINE__,
4691 						subRules,
4692 						["lcurly"]
4693 					);
4694 
4695 				} else if(this.lex.front.type == TokenType.lcurly) {
4696 					this.lex.popFront();
4697 					subRules = ["NI"];
4698 					if(this.firstInputValueDefinitions()) {
4699 						this.parseInputValueDefinitions();
4700 						subRules = ["NI"];
4701 						if(this.lex.front.type == TokenType.rcurly) {
4702 							this.lex.popFront();
4703 
4704 							return new InputObjectTypeDefinition(InputObjectTypeDefinitionEnum.NI
4705 								, name
4706 							);
4707 						}
4708 						auto app = appender!string();
4709 						formattedWrite(app, 
4710 							"Found a '%s' while looking for", 
4711 							this.lex.front
4712 						);
4713 						throw new ParseException(app.data,
4714 							__FILE__, __LINE__,
4715 							subRules,
4716 							["rcurly"]
4717 						);
4718 
4719 					}
4720 					auto app = appender!string();
4721 					formattedWrite(app, 
4722 						"Found a '%s' while looking for", 
4723 						this.lex.front
4724 					);
4725 					throw new ParseException(app.data,
4726 						__FILE__, __LINE__,
4727 						subRules,
4728 						["name -> InputValueDefinition"]
4729 					);
4730 
4731 				}
4732 				auto app = appender!string();
4733 				formattedWrite(app, 
4734 					"Found a '%s' while looking for", 
4735 					this.lex.front
4736 				);
4737 				throw new ParseException(app.data,
4738 					__FILE__, __LINE__,
4739 					subRules,
4740 					["at -> Directive","lcurly"]
4741 				);
4742 
4743 			}
4744 			auto app = appender!string();
4745 			formattedWrite(app, 
4746 				"Found a '%s' while looking for", 
4747 				this.lex.front
4748 			);
4749 			throw new ParseException(app.data,
4750 				__FILE__, __LINE__,
4751 				subRules,
4752 				["name"]
4753 			);
4754 
4755 		}
4756 		auto app = appender!string();
4757 		formattedWrite(app, 
4758 			"Found a '%s' while looking for", 
4759 			this.lex.front
4760 		);
4761 		throw new ParseException(app.data,
4762 			__FILE__, __LINE__,
4763 			subRules,
4764 			["input"]
4765 		);
4766 
4767 	}
4768 
4769 }