blitz_query_cpp
968 строк · 26.5 Кб
1#include <parser/parser.hpp>
2
3using namespace blitz_query_cpp;
4
5bool parser_t::unexpected_token()
6{
7return report_error(error_code_t::UnexpectedToken,
8"UnexpectedToken {}",
9current_token.value);
10}
11
12bool parser_t::create_new_node(syntax_node_type type, bool is_leaf)
13{
14syntax_node &parent = *nodes_stack.top();
15syntax_node &node = doc.all_nodes.emplace_back();
16node.parent = &parent;
17node.pos = current_token.pos;
18node.type = type;
19
20if (current_description.size() > 0)
21{
22node.description = current_description;
23current_description = std::string_view{};
24}
25
26if (!parent.add_child(&node))
27return false;
28if (!is_leaf)
29nodes_stack.push(&node);
30return true;
31}
32
33bool parser_t::parse()
34{
35index_t token_count = count_tokens();
36// reserve node storage to avoid future reallocations
37doc.all_nodes.reserve(token_count);
38
39while (current_token.type != token_type::End && current_token.type != token_type::InvalidToken)
40{
41if (!parse_definitions())
42{
43return false;
44}
45}
46if (current_token.type == token_type::InvalidToken)
47{
48return unexpected_token();
49}
50return true;
51}
52
53bool parser_t::expect_token(token_type expected_types)
54{
55if (!current_token.of_type(expected_types))
56{
57return unexpected_token();
58}
59return next_token();
60}
61
62bool parser_t::parse_keyword_token(syntax_node_type type, std::string_view keyword)
63{
64if (!current_token.of_type(token_type::Name) || current_token.value != keyword)
65{
66return report_error(error_code_t::UnexpectedToken,
67"Expected keyword '{}' got: '{}'",
68keyword,
69current_token.value);
70}
71return parse_node(type, token_type::Name);
72}
73
74bool parser_t::expect_keyword_token(std::string_view keyword, bool optional)
75{
76if (!current_token.of_type(token_type::Name) || current_token.value != keyword)
77{
78if (optional)
79return false;
80return report_error(error_code_t::UnexpectedToken,
81"Expected keyword '{}' got: '{}'",
82keyword,
83current_token.value);
84}
85return next_token();
86}
87
88index_t parser_t::count_tokens()
89{
90tokenizer_t local_tokenizer{doc.doc_value};
91token_t t;
92index_t count = 0;
93do
94{
95t = local_tokenizer.next_token();
96count++;
97} while (!t.of_type(token_type::End | token_type::InvalidToken));
98return count;
99}
100
101bool parser_t::next_token()
102{
103last_token_end = current_token.pos + current_token.size;
104current_token = tokenizer.next_token();
105return true;
106}
107
108void parser_t::update_node_size_and_content()
109{
110syntax_node &node = current_node();
111node.size = last_token_end - node.pos;
112std::string_view doc_view = doc.doc_value;
113node.content = doc_view.substr(node.pos, node.size);
114}
115
116bool parser_t::parse_description()
117{
118if (current_token.of_type(token_type::StringBlock | token_type::StringLiteral))
119{
120current_description = current_token.value;
121return next_token();
122}
123return true;
124}
125
126bool parser_t::parse_definitions()
127{
128if (!parse_description())
129return false;
130
131if (current_token.type == token_type::Name)
132{
133switch (hash_crc32(current_token.value))
134{
135case "query"_crc32:
136case "mutation"_crc32:
137case "subscription"_crc32:
138return parse_operation_definition();
139case "fragment"_crc32:
140return parse_fragment_definition();
141case "directive"_crc32:
142return parse_directive_definition();
143case "schema"_crc32:
144return parse_schema_definition(syntax_node_type::SchemaDefinition);
145case "scalar"_crc32:
146return parse_scalar_type_definition(syntax_node_type::ScalarTypeDefinition);
147case "type"_crc32:
148return parse_object_type_definition(syntax_node_type::ObjectTypeDefinition, "type");
149case "interface"_crc32:
150return parse_object_type_definition(syntax_node_type::ObjectTypeDefinition, "interface");
151case "union"_crc32:
152return parse_union_type_definition(syntax_node_type::UnionTypeDefinition);
153case "enum"_crc32:
154return parse_enum_type_definition(syntax_node_type::EnumTypeDefinition);
155case "input"_crc32:
156return parse_input_object_type_definition(syntax_node_type::InputObjectTypeDefinition);
157case "extend"_crc32:
158return parse_type_extension();
159}
160}
161if (current_token.type == token_type::LBrace)
162{
163return parse_short_operation_definition();
164}
165return unexpected_token();
166}
167
168bool parser_t::parse_node(syntax_node_type type, token_type expected_types, NodeParseOptions opts)
169{
170if (!current_token.of_type(expected_types))
171{
172if (has_any_flag(opts, ParseNodeIfMatch))
173return false;
174return unexpected_token();
175}
176
177if (!create_new_node(type, has_any_flag(opts, NodeIsLeaf)))
178return false;
179syntax_node &node = last_node();
180node.pos = current_token.pos;
181node.size = current_token.size;
182node.content = current_token.value;
183
184return next_token();
185}
186
187bool parser_t::parse_operation_definition()
188{
189operation_type_t op_type = parse_operation_type(current_token.value);
190if (op_type == operation_type_t::None)
191{
192report_error(error_code_t::InvalidOperationType, "Invalid operation type {}", last_node().content);
193return false;
194}
195
196if (!parse_node(syntax_node_type::OperationDefinition, token_type::Name))
197return false;
198syntax_node &operation_node = current_node();
199operation_node.operation_type = op_type;
200doc.operation = &operation_node;
201
202if (current_token.type == token_type::Name)
203{
204if (!parse_name())
205return false;
206}
207
208if (!parse_variable_definitions())
209return false;
210if (!parse_directives(false))
211return false;
212if (!parse_selection_set())
213return false;
214
215return pop_node();
216}
217
218bool parser_t::parse_short_operation_definition()
219{
220if (!create_new_node(syntax_node_type::OperationDefinition, false))
221return false;
222auto &node = current_node();
223doc.operation = &node;
224node.operation_type = operation_type_t::Query;
225node.size = doc.doc_value.size() - node.pos;
226if (!parse_selection_set())
227return false;
228return pop_node();
229}
230
231bool parser_t::parse_variable_definitions()
232{
233size_t child_count = current_node().children.size();
234if (!current_token.of_type(token_type::LParen))
235return true;
236
237if (!next_token())
238return false;
239
240while (!current_token.of_type(token_type::RParen))
241{
242if (!parse_variable_definition())
243{
244return false;
245}
246}
247auto &node = current_node();
248node.variables = node.children.subspan(child_count);
249return expect_token(token_type::RParen);
250}
251
252bool parser_t::parse_variable_definition()
253{
254if (!current_token.of_type(token_type::ParameterLiteral))
255{
256return unexpected_token();
257}
258if (!parse_node(syntax_node_type::VariableDefinition, token_type::ParameterLiteral))
259return false;
260auto &var_node = current_node();
261var_node.name = var_node.content;
262
263if (!expect_token(token_type::Colon))
264return false;
265if (!parse_type_reference())
266return false;
267
268if (current_token.of_type(token_type::Equal))
269{
270if (!next_token())
271return false;
272if (!parse_value_literal(true))
273return false;
274}
275size_t child_count = var_node.children.size();
276if (!parse_directives(true))
277return false;
278
279var_node.directives = var_node.children.subspan(child_count);
280
281return pop_node();
282}
283
284bool parser_t::parse_value_literal(bool is_constant)
285{
286if (current_token.of_type(token_type::LBracket))
287return parse_list(is_constant);
288
289if (current_token.of_type(token_type::LBrace))
290return parse_object(is_constant);
291
292if (parse_node(syntax_node_type::StringValue, token_type::StringLiteral | token_type::StringBlock, NodeIsLeaf | ParseNodeIfMatch))
293return true;
294
295if (parse_node(syntax_node_type::IntValue, token_type::IntLiteral, NodeIsLeaf | ParseNodeIfMatch))
296{
297syntax_node &node = last_node();
298long long value = 0;
299auto res = std::from_chars(node.content.begin(), node.content.end(), value);
300if(res.ec != std::errc{})
301return report_error(error_code_t::SyntaxError, "Failed to parse int value. Error: {}", (int)res.ec);
302node.intValue = value;
303return true;
304}
305
306if (parse_node(syntax_node_type::FloatValue, token_type::FloatLiteral, NodeIsLeaf | ParseNodeIfMatch))
307{
308syntax_node &node = last_node();
309node.floatValue = std::stod(node.content.data());
310return true;
311}
312
313if (parse_node(syntax_node_type::EnumValue, token_type::Name, NodeIsLeaf | ParseNodeIfMatch))
314{
315syntax_node &node = last_node();
316if (node.content == "true")
317{
318node.type = syntax_node_type::BoolValue;
319node.boolValue = true;
320}
321if (node.content == "false")
322{
323node.type = syntax_node_type::BoolValue;
324node.boolValue = false;
325}
326if (node.content == "null")
327node.type = syntax_node_type::NullValue;
328return true;
329}
330
331if (!is_constant && parse_node(syntax_node_type::Variable, token_type::ParameterLiteral, NodeIsLeaf | ParseNodeIfMatch))
332{
333syntax_node &node = last_node();
334node.name = node.content;
335return true;
336}
337
338return unexpected_token();
339}
340
341bool parser_t::parse_list(bool is_constant)
342{
343if (!parse_node(syntax_node_type::ListValue, token_type::LBracket))
344return false;
345
346while (!current_token.of_type(token_type::RBracket))
347{
348if (!parse_value_literal(is_constant))
349return false;
350}
351
352if (!expect_token(token_type::RBrace))
353return false;
354
355return pop_node();
356}
357
358bool parser_t::parse_object(bool is_constant)
359{
360if (!parse_node(syntax_node_type::ObjectValue, token_type::LBrace))
361return false;
362
363while (!current_token.of_type(token_type::RBrace))
364{
365if (!create_new_node(syntax_node_type::ObjectField, false))
366return false;
367if (!parse_name())
368return false;
369if (!expect_token(token_type::Colon))
370return false;
371if (!parse_value_literal(is_constant))
372return false;
373
374pop_node();
375}
376
377if (!expect_token(token_type::RBrace))
378return false;
379
380return pop_node();
381}
382
383bool parser_t::parse_type_reference()
384{
385if (parse_node(syntax_node_type::ListType, token_type::LBracket, ParseNodeIfMatch))
386{
387if (!parse_type_reference())
388return false;
389if (!expect_token(token_type::RBracket))
390return false;
391}
392else
393{
394if (!parse_named_type())
395return false;
396}
397
398auto &node = current_node();
399index_t size = last_token_end - node.pos;
400node.name = std::string_view(doc.doc_value).substr(node.pos, size);
401
402if (current_token.of_type(token_type::NotNull))
403{
404current_node().nullability = nullability_t::Required;
405if (!next_token())
406return false;
407}
408else
409{
410current_node().nullability = nullability_t::Optional;
411}
412
413current_node().parent->definition_type = ¤t_node();
414return pop_node();
415}
416
417bool parser_t::parse_directives(bool is_constant)
418{
419size_t child_count = current_node().children.size();
420while (current_token.of_type(token_type::Directive))
421{
422if (!parse_directive(is_constant))
423return false;
424}
425auto &node = current_node();
426node.directives = node.children.subspan(child_count);
427return true;
428}
429
430bool parser_t::parse_directive(bool is_constant)
431{
432if (!parse_node(syntax_node_type::Directive, token_type::Directive))
433return false;
434syntax_node &directive_node = current_node();
435directive_node.name = directive_node.content;
436
437if (!parse_arguments(is_constant))
438return false;
439
440return pop_node();
441}
442
443bool parser_t::parse_arguments(bool is_constant)
444{
445if (!current_token.of_type(token_type::LParen))
446return true;
447
448size_t child_count = current_node().children.size();
449
450if (!next_token())
451return false;
452
453while (!current_token.of_type(token_type::RParen))
454{
455if (!create_new_node(syntax_node_type::Argument, false))
456return false;
457if (!parse_name())
458return false;
459if (!expect_token(token_type::Colon))
460return false;
461if (!parse_value_literal(is_constant))
462return false;
463
464pop_node();
465}
466
467auto &node = current_node();
468node.variables = node.children.subspan(child_count);
469
470return expect_token(token_type::RParen);
471}
472
473bool parser_t::parse_selection_set()
474{
475if (!parse_node(syntax_node_type::SelectionSet, token_type::LBrace))
476return false;
477syntax_node &selection_set_node = current_node();
478selection_set_node.parent->selection_set = &selection_set_node;
479
480while (!current_token.of_type(token_type::RBrace))
481{
482if (!parse_selection())
483return false;
484}
485if (!expect_token(token_type::RBrace))
486return false;
487
488return pop_node();
489}
490
491bool parser_t::parse_selection()
492{
493if (parse_fragment())
494return true;
495if (parse_field())
496return true;
497return false;
498}
499
500bool parser_t::parse_field()
501{
502if (parse_node(syntax_node_type::Comment, token_type::Comment, ParseNodeIfMatch | NodeIsLeaf))
503return true;
504
505if (!parse_node(syntax_node_type::Field, token_type::Name))
506{
507report_error(error_code_t::NameExpected, "Field name expected at {}", current_token.pos);
508return false;
509}
510syntax_node &selection_node = current_node();
511selection_node.alias = selection_node.name = selection_node.content;
512
513if (current_token.of_type(token_type::Colon))
514{
515if (!expect_token(token_type::Colon))
516return false;
517if (!parse_name())
518{
519report_error(error_code_t::NameExpected, "Field name expected at {}", current_token.pos);
520return false;
521}
522
523selection_node.name = current_token.value;
524selection_node.alias = selection_node.content;
525selection_node.size = selection_node.pos;
526}
527
528if (!parse_arguments(false))
529return false;
530
531if (!parse_directives(false))
532return false;
533
534if (current_token.of_type(token_type::LBrace))
535{
536if (!parse_selection_set())
537return false;
538}
539
540return pop_node();
541}
542
543bool parser_t::parse_fragment()
544{
545if (!parse_node(syntax_node_type::FragmentSpread, token_type::FragmentSpread, ParseNodeIfMatch))
546return false;
547
548if (!current_token.of_type(token_type::Name))
549return report_error(error_code_t::SyntaxError, "fragment name or inline fragment expected");
550
551auto &node = current_node();
552// inline fragment
553if (current_token.value == "on")
554{
555if (!next_token())
556return false;
557if (!parse_node(syntax_node_type::NamedType, token_type::Name, NodeIsLeaf))
558return false;
559node.definition_type = &last_node();
560
561if (!parse_directives(false))
562return false;
563
564if (!parse_selection_set())
565return false;
566}
567else
568{
569node.name = current_token.value;
570if (!parse_directives(false))
571return false;
572}
573return pop_node();
574}
575
576bool parser_t::parse_type_extension()
577{
578if (!next_token())
579return report_error(error_code_t::UnexpectedEndOfDocument, "Type extension expected");
580switch (hash_crc32(current_token.value))
581{
582case "scalar"_crc32:
583return parse_scalar_type_definition(syntax_node_type::ScalarTypeExtension);
584case "union"_crc32:
585return parse_union_type_definition(syntax_node_type::UnionTypeExtension);
586case "enum"_crc32:
587return parse_enum_type_definition(syntax_node_type::EnumTypeExtension);
588case "type"_crc32:
589return parse_object_type_definition(syntax_node_type::ObjectTypeExtension, "type");
590case "interface"_crc32:
591return parse_object_type_definition(syntax_node_type::InterfaceTypeDefinition, "interface");
592case "imput"_crc32:
593return parse_input_object_type_definition(syntax_node_type::InterfaceTypeDefinition);
594}
595return report_error(error_code_t::InvalidToken, "Expected type, scalar, union, enum, interface or union. Got: {}", current_token.value);
596}
597
598bool parser_t::parse_input_object_type_definition(syntax_node_type node_type)
599{
600if (!parse_keyword_token(node_type, "input"))
601return false;
602
603if (!parse_name())
604return false;
605
606if (!parse_directives(false))
607return false;
608
609if(node_type == syntax_node_type::InputObjectTypeExtension && !current_token.of_type(token_type::LBrace))
610return pop_node();
611
612if (!parse_argument_definitions(token_type::LBrace, token_type::RBrace))
613return false;
614
615return pop_node();
616}
617
618bool parser_t::parse_enum_type_definition(syntax_node_type node_type)
619{
620if (!parse_keyword_token(node_type, "enum"))
621return false;
622
623if (!parse_name())
624return false;
625
626if (!parse_directives(false))
627return false;
628
629if (node_type == syntax_node_type::EnumTypeExtension && !current_token.of_type(token_type::LBrace))
630return pop_node();
631
632if (!expect_token(token_type::LBrace))
633return false;
634
635if (!parse_enum_values())
636return false;
637
638if (!expect_token(token_type::RBrace))
639return false;
640
641return pop_node();
642}
643
644bool parser_t::parse_enum_values()
645{
646while (!current_token.of_type(token_type::RBrace))
647{
648if (!parse_enum_value())
649{
650return false;
651}
652}
653return true;
654}
655
656bool parser_t::parse_enum_value()
657{
658if (!create_new_node(syntax_node_type::EnumValueDefinition, false))
659return false;
660if (!parse_name())
661return false;
662if (!parse_directives(true))
663return false;
664return pop_node();
665}
666
667bool parser_t::parse_union_type_definition(syntax_node_type node_type)
668{
669if (!parse_keyword_token(node_type, "union"))
670return false;
671
672if (!parse_name())
673return false;
674
675if (!parse_directives(false))
676return false;
677
678if (node_type == syntax_node_type::UnionTypeExtension && !current_token.of_type(token_type::Equal))
679return pop_node();
680
681if (!expect_token(token_type::Equal))
682return false;
683
684if (current_token.of_type(token_type::Union))
685{
686if (!next_token())
687return false;
688}
689size_t child_count = current_node().children.size();
690do
691{
692if (!parse_named_type(NodeIsLeaf))
693return false;
694
695if (!current_token.of_type(token_type::Union))
696break;
697
698if (!next_token())
699break;
700
701} while (true);
702auto &node = current_node();
703node.implements = node.children.subspan(child_count);
704
705return pop_node();
706}
707
708bool parser_t::parse_object_type_definition(syntax_node_type type, std::string_view keyword)
709{
710if (!parse_keyword_token(type, keyword))
711return false;
712
713if (!parse_name())
714return false;
715
716if (!parse_implements_interfaces())
717return false;
718
719if (!parse_directives(false))
720return false;
721
722if (!expect_token(token_type::LBrace))
723return false;
724
725while (!current_token.of_type(token_type::RBrace))
726{
727if (!parse_description())
728return false;
729if (!create_new_node(syntax_node_type::FieldDefinition, false))
730return false;
731if (!parse_name())
732return false;
733if (!parse_argument_definitions())
734return false;
735if (!expect_token(token_type::Colon))
736return false;
737if (!parse_type_reference())
738return false;
739if (!parse_directives(true))
740return false;
741pop_node();
742}
743pop_node();
744return expect_token(token_type::RBrace);
745}
746
747bool parser_t::parse_implements_interfaces()
748{
749if (!expect_keyword_token("implements", true))
750return true;
751
752if (current_token.of_type(token_type::And))
753{
754if (!next_token())
755return false;
756}
757size_t child_count = current_node().children.size();
758
759while (current_token.of_type(token_type::Name))
760{
761if (!parse_named_type(NodeIsLeaf))
762return false;
763
764if (current_token.of_type(token_type::And))
765{
766if (!next_token())
767return false;
768}
769}
770auto &node = current_node();
771node.implements = node.children.subspan(child_count);
772
773return true;
774}
775
776bool parser_t::parse_argument_definitions(token_type start, token_type end)
777{
778size_t child_count = current_node().children.size();
779if (!current_token.of_type(start))
780return true;
781
782if (!next_token())
783return false;
784
785while (!current_token.of_type(end))
786{
787if (!parse_argument_definition())
788{
789return false;
790}
791}
792auto &node = current_node();
793node.arguments = node.children.subspan(child_count);
794return expect_token(end);
795}
796
797bool parser_t::parse_argument_definition()
798{
799if (!parse_description())
800return false;
801if (!create_new_node(syntax_node_type::InputValueDefinition, false))
802return false;
803if (!parse_name())
804return false;
805if (!expect_token(token_type::Colon))
806return false;
807if (!parse_type_reference())
808return false;
809if (current_token.of_type(token_type::Equal))
810{
811if (!next_token())
812return false;
813if (!parse_value_literal(true))
814return false;
815}
816if (!parse_directives(true))
817return false;
818return pop_node();
819}
820
821bool parser_t::parse_name(token_type name_type)
822{
823if (!current_token.of_type(name_type))
824{
825return unexpected_token();
826}
827syntax_node &parent = current_node();
828
829parent.name = current_token.value;
830return next_token();
831}
832
833bool parser_t::parse_scalar_type_definition(syntax_node_type node_type)
834{
835if (!parse_node(node_type, token_type::Name))
836return false;
837
838if (!parse_name())
839return false;
840
841if (!parse_directives(true))
842return false;
843
844return pop_node();
845}
846
847bool parser_t::parse_schema_definition(syntax_node_type node_type)
848{
849if (!parse_keyword_token(node_type, "schema"))
850return false;
851
852if (!parse_directives(true))
853return false;
854
855if(node_type == syntax_node_type::SchemaExtension && !current_token.of_type(token_type::LBrace))
856return pop_node();
857
858if (!expect_token(token_type::LBrace))
859return false;
860
861while (!current_token.of_type(token_type::RBrace))
862{
863if (!parse_operation_type_definition())
864return false;
865}
866
867if (!expect_token(token_type::RBrace))
868return false;
869
870return pop_node();
871}
872
873bool parser_t::parse_operation_type_definition()
874{
875if (!create_new_node(syntax_node_type::OperationTypeDefinition, false))
876return false;
877
878auto op_type = parse_operation_type(current_token.value);
879if (op_type == operation_type_t::None)
880{
881report_error(error_code_t::InvalidOperationType, "Invalid Operation Type: {}", current_token.value);
882return false;
883}
884current_node().operation_type = op_type;
885
886if (!expect_token(token_type::Name))
887return false;
888
889if (!expect_token(token_type::Colon))
890return false;
891if (!parse_named_type(NodeIsLeaf))
892return false;
893
894return pop_node();
895}
896
897bool parser_t::parse_named_type(NodeParseOptions opts)
898{
899if (!parse_node(syntax_node_type::NamedType, token_type::Name, opts))
900return false;
901last_node().name = last_node().content;
902return true;
903}
904
905bool parser_t::parse_directive_definition()
906{
907if (!parse_keyword_token(syntax_node_type::DirectiveDefinition, "directive"))
908return false;
909
910if (!parse_name(token_type::Directive))
911return false;
912
913if (!parse_argument_definitions())
914return false;
915
916if (!current_token.of_type(token_type::Name))
917return report_error(error_code_t::UnexpectedToken, "Expected to see 'on' or 'repeatable' keyword while parsing directive '{}' at {}", current_node().name, current_token.pos);
918
919if (expect_keyword_token("repeatable", true))
920current_node().directive_target = directive_target_t::IsRepeatable;
921
922if (!expect_keyword_token("on"))
923return false;
924
925directive_target_t target = directive_target_t::None;
926do
927{
928if (current_token.of_type(token_type::Union))
929{
930if (!next_token())
931return false;
932}
933if (!current_token.of_type(token_type::Name))
934{
935break;
936}
937target = parse_directive_target(current_token.value);
938if (target == directive_target_t::None)
939{
940break;
941}
942current_node().directive_target |= target;
943if (!next_token())
944return false;
945
946} while (target != directive_target_t::None);
947
948return pop_node();
949}
950
951bool parser_t::parse_fragment_definition()
952{
953if (!parse_keyword_token(syntax_node_type::FragmentDefinition, "fragment"))
954return false;
955if (!parse_name())
956return false;
957if (!parse_variable_definitions())
958return false;
959if (!expect_keyword_token("on"))
960return false;
961if (!parse_named_type(NodeIsLeaf))
962return false;
963if (!parse_directives(false))
964return false;
965if (!parse_selection_set())
966return false;
967return pop_node();
968}