1/** 2 * Copyright (c) 2015-present, Facebook, Inc. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8/* %require "3" */ 9 10%skeleton "lalr1.cc" 11 12%defines 13%define parser_class_name {GraphQLParserImpl} 14 15%define api.token.prefix {TOK_} 16 17%define parse.error verbose 18 19%code requires 20{ 21#include <cstdlib> 22#include <cstring> 23#include <iostream> 24#include <sstream> 25#include <string> 26 27#include "Ast.h" 28 29using facebook::graphql::ast::Node; 30using facebook::graphql::ast::Name; 31using facebook::graphql::ast::Definition; 32using facebook::graphql::ast::Document; 33using facebook::graphql::ast::OperationDefinition; 34using facebook::graphql::ast::VariableDefinition; 35using facebook::graphql::ast::Variable; 36using facebook::graphql::ast::SelectionSet; 37using facebook::graphql::ast::Selection; 38using facebook::graphql::ast::Field; 39using facebook::graphql::ast::Argument; 40using facebook::graphql::ast::FragmentSpread; 41using facebook::graphql::ast::InlineFragment; 42using facebook::graphql::ast::FragmentDefinition; 43using facebook::graphql::ast::Value; 44using facebook::graphql::ast::IntValue; 45using facebook::graphql::ast::FloatValue; 46using facebook::graphql::ast::StringValue; 47using facebook::graphql::ast::BooleanValue; 48using facebook::graphql::ast::NullValue; 49using facebook::graphql::ast::EnumValue; 50using facebook::graphql::ast::ListValue; 51using facebook::graphql::ast::ObjectValue; 52using facebook::graphql::ast::ObjectField; 53using facebook::graphql::ast::Directive; 54using facebook::graphql::ast::Type; 55using facebook::graphql::ast::NamedType; 56using facebook::graphql::ast::ListType; 57using facebook::graphql::ast::NonNullType; 58 59// Experimental schema support. 60using facebook::graphql::ast::SchemaDefinition; 61using facebook::graphql::ast::ScalarTypeDefinition; 62using facebook::graphql::ast::ObjectTypeDefinition; 63using facebook::graphql::ast::InterfaceTypeDefinition; 64using facebook::graphql::ast::UnionTypeDefinition; 65using facebook::graphql::ast::EnumTypeDefinition; 66using facebook::graphql::ast::InputObjectTypeDefinition; 67using facebook::graphql::ast::TypeExtensionDefinition; 68using facebook::graphql::ast::DirectiveDefinition; 69using facebook::graphql::ast::SchemaDefinition; 70using facebook::graphql::ast::OperationTypeDefinition; 71using facebook::graphql::ast::ScalarTypeDefinition; 72using facebook::graphql::ast::ObjectTypeDefinition; 73using facebook::graphql::ast::FieldDefinition; 74using facebook::graphql::ast::InputValueDefinition; 75using facebook::graphql::ast::InterfaceTypeDefinition; 76using facebook::graphql::ast::UnionTypeDefinition; 77using facebook::graphql::ast::EnumTypeDefinition; 78using facebook::graphql::ast::EnumValueDefinition; 79using facebook::graphql::ast::InputObjectTypeDefinition; 80using facebook::graphql::ast::TypeExtensionDefinition; 81using facebook::graphql::ast::DirectiveDefinition; 82 83union yystype { \ 84 const char *str; \ 85 const char *heapStr; \ 86 Name *name; \ 87 Definition *definition; \ 88 Document *document; \ 89 OperationDefinition *operationDefinition; \ 90 VariableDefinition *variableDefinition; \ 91 Variable *variable; \ 92 SelectionSet *selectionSet; \ 93 Selection *selection; \ 94 Field *field; \ 95 Argument *argument; \ 96 FragmentSpread *fragmentSpread; \ 97 InlineFragment *inlineFragment; \ 98 FragmentDefinition *fragmentDefinition; \ 99 Value *value; \ 100 IntValue *intValue; \ 101 FloatValue *floatValue; \ 102 StringValue *stringValue; \ 103 BooleanValue *booleanValue; \ 104 NullValue *nullValue; \ 105 EnumValue *enumValue; \ 106 ListValue *arrayValue; \ 107 ObjectValue *objectValue; \ 108 ObjectField *objectField; \ 109 Directive *directive; \ 110 Type *type; \ 111 NamedType *namedType; \ 112 ListType *listType; \ 113 NonNullType *nonNullType; \ 114 \ 115 std::vector<std::unique_ptr<Definition>> *definitionList; \ 116 std::vector<std::unique_ptr<VariableDefinition>> *variableDefinitionList; \ 117 std::vector<std::unique_ptr<Selection>> *selectionList; \ 118 std::vector<std::unique_ptr<Field>> *fieldList; \ 119 std::vector<std::unique_ptr<Argument>> *argumentList; \ 120 std::vector<std::unique_ptr<Value>> *valueList; \ 121 std::vector<std::unique_ptr<ObjectField>> *objectFieldList; \ 122 std::vector<std::unique_ptr<Directive>> *directiveList; \ 123 \ 124 SchemaDefinition *schemaDefinition; \ 125 ScalarTypeDefinition *scalarTypeDefinition; \ 126 ObjectTypeDefinition *objectTypeDefinition; \ 127 InterfaceTypeDefinition *interfaceTypeDefinition; \ 128 UnionTypeDefinition *unionTypeDefinition; \ 129 EnumTypeDefinition *enumTypeDefinition; \ 130 InputObjectTypeDefinition *inputObjectTypeDefinition; \ 131 TypeExtensionDefinition *typeExtensionDefinition; \ 132 DirectiveDefinition *directiveDefinition; \ 133 OperationTypeDefinition *operationTypeDefinition; \ 134 InputValueDefinition *inputValueDefinition; \ 135 FieldDefinition *fieldDefinition; \ 136 EnumValueDefinition *enumValueDefinition; \ 137 \ 138 std::vector<std::unique_ptr<OperationTypeDefinition>> *operationTypeDefinitionList; \ 139 std::vector<std::unique_ptr<NamedType>> *typeNameList; \ 140 std::vector<std::unique_ptr<InputValueDefinition>> *inputValueDefinitionList; \ 141 std::vector<std::unique_ptr<FieldDefinition>> *fieldDefinitionList; \ 142 std::vector<std::unique_ptr<Name>> *nameList; \ 143 std::vector<std::unique_ptr<EnumValueDefinition>> *enumValueDefinitionList; \ 144}; 145 146#define YYSTYPE union yystype 147#define YYLTYPE yy::location 148 149} 150 151%lex-param { void *scanner } 152%parse-param { bool enableSchema } { Node **outAST } { const char **outError } { void *scanner } 153 154%locations 155 156%code 157{ 158#include "lexer.h" 159#include "syntaxdefs.h" 160} 161 162%token EOF 0 163%token <str> DIRECTIVE "directive" 164%token <str> ENUM "enum" 165%token <str> EXTEND "extend" 166%token <str> FALSE "false" 167%token <str> FRAGMENT "fragment" 168%token <str> IMPLEMENTS "implements" 169%token <str> INPUT "input" 170%token <str> INTERFACE "interface" 171%token <str> MUTATION "mutation" 172%token <str> NULL "null" 173%token <str> QUERY "query" 174%token <str> ON "on" 175%token <str> SCALAR "scalar" 176%token <str> SCHEMA "schema" 177%token <str> SUBSCRIPTION "subscription" 178%token <str> TRUE "true" 179%token <str> TYPE "type" 180%token <str> UNION "union" 181%token BANG "!" 182%token LPAREN "(" 183%token RPAREN ")" 184%token ELLIPSIS "..." 185%token COLON ":" 186%token EQUAL "=" 187%token AT "@" 188%token LBRACKET "[" 189%token RBRACKET "]" 190%token LBRACE "{" 191%token PIPE "|" 192%token RBRACE "}" 193 194%token <str> VARIABLE 195%token <str> INTEGER 196%token <str> FLOAT 197%token <str> STRING 198%token <str> IDENTIFIER 199 200%type <variable> variable 201%type <intValue> int_value 202%type <floatValue> float_value 203%type <stringValue> string_value 204 205%type <document> start 206%type <document> document 207%type <name> fragment_name 208%type <name> name 209%type <name> name_opt 210 211%type <definitionList> definition_list 212%type <definition> definition 213%type <definition> schema_gate 214 215%type <operationDefinition> operation_definition 216%type <variableDefinitionList> variable_definitions 217%type <variableDefinitionList> variable_definition_list 218%type <variableDefinition> variable_definition 219%type <value> default_value_opt 220%type <value> default_value 221%type <selectionSet> selection_set 222%type <selectionSet> selection_set_opt 223%type <selectionList> selection_list 224%type <selection> selection 225%type <field> field 226%type <argumentList> arguments_opt 227%type <argumentList> arguments 228%type <argumentList> argument_list 229%type <argument> argument 230 231%type <fragmentSpread> fragment_spread 232%type <inlineFragment> inline_fragment 233%type <fragmentDefinition> fragment_definition 234%type <namedType> type_condition 235 236%type <value> value 237%type <value> value_const 238%type <booleanValue> boolean_value 239%type <nullValue> null_value 240%type <enumValue> enum_value 241%type <arrayValue> list_value 242%type <arrayValue> list_value_const 243%type <valueList> value_list 244%type <valueList> value_const_list 245%type <objectValue> object_value 246%type <objectValue> object_value_const 247%type <objectFieldList> object_field_list 248%type <objectFieldList> object_field_const_list 249%type <objectField> object_field 250%type <objectField> object_field_const 251 252 253%type <directiveList> directives 254%type <directiveList> directives_opt 255%type <directiveList> directive_list 256%type <directive> directive 257 258%type <type> type 259%type <namedType> type_name 260%type <listType> list_type 261%type <nonNullType> non_null_type 262 263%type <heapStr> operation_type 264 265%type <schemaDefinition> schema_definition; 266%type <scalarTypeDefinition> scalar_type_definition; 267%type <objectTypeDefinition> object_type_definition; 268%type <interfaceTypeDefinition> interface_type_definition; 269%type <unionTypeDefinition> union_type_definition; 270%type <enumTypeDefinition> enum_type_definition; 271%type <inputObjectTypeDefinition> input_object_type_definition; 272%type <typeExtensionDefinition> type_extension_definition; 273%type <directiveDefinition> directive_definition; 274%type <operationTypeDefinition> operation_type_definition; 275%type <operationTypeDefinitionList> operation_type_definition_list; 276%type <typeNameList> type_name_list; 277%type <typeNameList> implements_interfaces_opt; 278%type <typeNameList> union_members; 279%type <fieldDefinition> field_definition; 280%type <fieldDefinitionList> field_definition_list; 281%type <inputValueDefinitionList> arguments_definition_opt; 282%type <inputValueDefinitionList> arguments_definition; 283%type <inputValueDefinitionList> input_value_definition_list; 284%type <inputValueDefinition> input_value_definition; 285%type <enumValueDefinition> enum_value_definition; 286%type <nameList> directive_locations; 287%type <enumValueDefinitionList> enum_value_definition_list; 288 289%destructor { } <str> 290%destructor { free((void *)$$); } <heapStr> 291%destructor { } <document> /* we steal it and put it in outAST, don't free! */ 292%destructor { delete $$; } <*> 293 294%printer { yyoutput << $$; } <str> 295 296%% 297 298start: document { *outAST = $1; } 299 ; 300 301/* All of the non-identifier tokens are to accommodate various flavors 302 of name that don't include those tokens. */ 303fragment_name: DIRECTIVE { $$ = new Name(@1, strdup($1)); } 304 | ENUM { $$ = new Name(@1, strdup($1)); } 305 | EXTEND { $$ = new Name(@1, strdup($1)); } 306 | FALSE { $$ = new Name(@1, strdup($1)); } 307 | FRAGMENT { $$ = new Name(@1, strdup($1)); } 308 | IDENTIFIER { $$ = new Name(@1, strdup($1)); } 309 | IMPLEMENTS { $$ = new Name(@1, strdup($1)); } 310 | INPUT { $$ = new Name(@1, strdup($1)); } 311 | INTERFACE { $$ = new Name(@1, strdup($1)); } 312 | MUTATION { $$ = new Name(@1, strdup($1)); } 313 | NULL { $$ = new Name(@1, strdup($1)); } 314 | QUERY { $$ = new Name(@1, strdup($1)); } 315 | SCALAR { $$ = new Name(@1, strdup($1)); } 316 | SCHEMA { $$ = new Name(@1, strdup($1)); } 317 | SUBSCRIPTION { $$ = new Name(@1, strdup($1)); } 318 | TRUE { $$ = new Name(@1, strdup($1)); } 319 | TYPE { $$ = new Name(@1, strdup($1)); } 320 | UNION { $$ = new Name(@1, strdup($1)); } 321 ; 322 323name: fragment_name 324 | ON { $$ = new Name(@1, strdup($1)); } 325 ; 326 327name_opt: 328 %empty {$$ = nullptr;} 329 | name 330 ; 331 332/* 2.2 Document */ 333 334document: definition_list { $$ = new Document(@$, $1); } 335 ; 336 337definition_list:definition { $$ = new std::vector<std::unique_ptr<Definition>>(); $$->emplace_back($1); } 338 | definition_list definition { $1->emplace_back($2); $$ = $1; } 339 ; 340 341definition: operation_definition { $$ = static_cast<Definition *>($1); } 342 | fragment_definition { $$ = static_cast<Definition *>($1); } 343 | schema_gate { 344 if (!enableSchema) { 345 error(@$, "schema support disabled"); 346 // %destructor doesn't work with YYERROR. See 347 // https://www.gnu.org/software/bison/manual/html_node/Destructor-Decl.html 348 delete $$; 349 YYERROR; 350 } 351 $$ = static_cast<Definition *>($1); 352 } 353 ; 354 355schema_gate: schema_definition { $$ = static_cast<Definition *>($1); } 356 | scalar_type_definition { $$ = static_cast<Definition *>($1); } 357 | object_type_definition { $$ = static_cast<Definition *>($1); } 358 | interface_type_definition { $$ = static_cast<Definition *>($1); } 359 | union_type_definition { $$ = static_cast<Definition *>($1); } 360 | enum_type_definition { $$ = static_cast<Definition *>($1); } 361 | input_object_type_definition { $$ = static_cast<Definition *>($1); } 362 | type_extension_definition { $$ = static_cast<Definition *>($1); } 363 | directive_definition { $$ = static_cast<Definition *>($1); } 364 ; 365 366 367/* 2.2.1 Operations */ 368operation_definition: 369 selection_set { $$ = new OperationDefinition(@$, strdup("query"), nullptr, nullptr, nullptr, $1); } 370 | operation_type name_opt selection_set { $$ = new OperationDefinition(@$, $1, $2, nullptr, nullptr, $3); } 371 | operation_type name_opt variable_definitions selection_set { $$ = new OperationDefinition(@$, $1, $2, $3, nullptr, $4); } 372 | operation_type name_opt directives selection_set { $$ = new OperationDefinition(@$, $1, $2, nullptr, $3, $4); } 373 | operation_type name_opt variable_definitions directives selection_set { $$ = new OperationDefinition(@$, $1, $2, $3, $4, $5); } 374 ; 375 376operation_type: QUERY { $$ = strdup($1); } 377 | MUTATION { $$ = strdup($1); } 378 | SUBSCRIPTION { $$ = strdup($1); } 379 ; 380 381variable_definitions: 382 "(" variable_definition_list ")" { $$ = $2; } 383 ; 384 385variable_definition_list: 386 variable_definition { $$ = new std::vector<std::unique_ptr<VariableDefinition>>(); $$->emplace_back($1); } 387 | variable_definition_list variable_definition { $1->emplace_back($2); $$ = $1; } 388 ; 389 390variable: VARIABLE { $$ = new Variable(@$, new Name(@1, strdup($1))); } 391 ; 392 393variable_definition: 394 variable ":" type default_value_opt { $$ = new VariableDefinition(@$, $1, $3, $4); } 395 ; 396 397default_value_opt: 398 %empty { $$ = nullptr; } 399 | default_value 400 ; 401 402default_value: "=" value_const { $$ = $2; } 403 ; 404 405selection_set: 406 "{" selection_list "}" { $$ = new SelectionSet(@$, $2); } 407 ; 408 409selection_set_opt: 410 %empty { $$ = nullptr; } 411 | selection_set 412 ; 413selection_list: selection { $$ = new std::vector<std::unique_ptr<Selection>>(); $$->emplace_back($1); } 414 | selection_list selection { $1->emplace_back($2); $$ = $1; } 415 ; 416 417selection: field { $$ = static_cast<Selection *>($1); } 418 | fragment_spread { $$ = static_cast<Selection *>($1); } 419 | inline_fragment { $$ = static_cast<Selection *>($1); } 420 ; 421 422field: name arguments_opt directives_opt selection_set_opt { $$ = new Field(@$, nullptr, $1, $2, $3, $4); } 423 | name ":" name arguments_opt directives_opt selection_set_opt { $$ = new Field(@$, $1, $3, $4, $5, $6); } 424 ; 425 426arguments: "(" argument_list ")" { $$ = $2; } 427 ; 428 429arguments_opt: %empty { $$ = nullptr; } 430 | arguments { $$ = $1; } 431 ; 432 433argument_list: argument { $$ = new std::vector<std::unique_ptr<Argument>>(); $$->emplace_back($1); } 434 | argument_list argument { $1->emplace_back($2); $$ = $1; } 435 ; 436 437argument: name ":" value { $$ = new Argument(@$, $1, $3); } 438 ; 439 440/* 2.2.6 Fragments */ 441fragment_spread: 442 "..." fragment_name directives_opt { $$ = new FragmentSpread(@$, $2, $3); } 443 ; 444 445inline_fragment: 446 "..." "on" type_condition directives_opt selection_set { $$ = new InlineFragment(@$, $3, $4, $5); } 447 | "..." directives_opt selection_set { $$ = new InlineFragment(@$, nullptr, $2, $3); } 448 ; 449 450fragment_definition: 451 "fragment" fragment_name "on" type_condition directives_opt selection_set { $$ = new FragmentDefinition(@$, $2, $4, $5, $6); } 452 ; 453 454type_condition: type_name 455 ; 456 457/* 2.2.7 Input Values */ 458value: variable { $$ = static_cast<Value *>($1); } 459 | int_value { $$ = static_cast<Value *>($1); } 460 | float_value { $$ = static_cast<Value *>($1); } 461 | string_value { $$ = static_cast<Value *>($1); } 462 | boolean_value { $$ = static_cast<Value *>($1); } 463 | null_value { $$ = static_cast<Value *>($1); } 464 | enum_value { $$ = static_cast<Value *>($1); } 465 | list_value { $$ = static_cast<Value *>($1); } 466 | object_value { $$ = static_cast<Value *>($1); } 467 ; 468 469int_value: INTEGER { $$ = new IntValue(@$, strdup($1)); } 470 ; 471 472float_value: FLOAT { $$ = new FloatValue(@$, strdup($1)); } 473 ; 474 475string_value: STRING { $$ = new StringValue(@$, strdup($1)); } 476 ; 477 478value_const: int_value { $$ = static_cast<Value *>($1); } 479 | float_value { $$ = static_cast<Value *>($1); } 480 | string_value { $$ = static_cast<Value *>($1); } 481 | boolean_value { $$ = static_cast<Value *>($1); } 482 | null_value { $$ = static_cast<Value *>($1); } 483 | enum_value { $$ = static_cast<Value *>($1); } 484 | list_value_const { $$ = static_cast<Value *>($1); } 485 | object_value_const { $$ = static_cast<Value *>($1); } 486 ; 487 488boolean_value: TRUE { $$ = new BooleanValue(@$, true); } 489 | FALSE { $$ = new BooleanValue(@$, false); } 490 ; 491 492null_value: NULL { $$ = new NullValue(@$); } 493 ; 494 495enum_value: DIRECTIVE { $$ = new EnumValue(@$, strdup($1)); } 496 | ENUM { $$ = new EnumValue(@$, strdup($1)); } 497 | EXTEND { $$ = new EnumValue(@$, strdup($1)); } 498 | FRAGMENT { $$ = new EnumValue(@$, strdup($1)); } 499 | IDENTIFIER { $$ = new EnumValue(@$, strdup($1)); } 500 | IMPLEMENTS { $$ = new EnumValue(@$, strdup($1)); } 501 | INPUT { $$ = new EnumValue(@$, strdup($1)); } 502 | INTERFACE { $$ = new EnumValue(@$, strdup($1)); } 503 | MUTATION { $$ = new EnumValue(@$, strdup($1)); } 504 | ON { $$ = new EnumValue(@$, strdup($1)); } 505 | QUERY { $$ = new EnumValue(@$, strdup($1)); } 506 | SCALAR { $$ = new EnumValue(@$, strdup($1)); } 507 | SCHEMA { $$ = new EnumValue(@$, strdup($1)); } 508 | SUBSCRIPTION { $$ = new EnumValue(@$, strdup($1)); } 509 | TYPE { $$ = new EnumValue(@$, strdup($1)); } 510 | UNION { $$ = new EnumValue(@$, strdup($1)); } 511 ; 512 513/* 2.2.7.6 List Value */ 514 515/* REVIEW: the empty case is inefficient; consider implementing 516 ListValue manually. Don't forget to also do list_value_const. */ 517list_value: "[" "]" { $$ = new ListValue(@$, new std::vector<std::unique_ptr<Value>>()); } 518 | "[" value_list "]" { $$ = new ListValue(@$, $2); } 519 ; 520 521value_list: value { $$ = new std::vector<std::unique_ptr<Value>>(); $$->emplace_back($1); } 522 | value_list value { $1->emplace_back($2); $$ = $1; } 523 ; 524 525list_value_const: 526 "[" "]" { $$ = new ListValue(@$, new std::vector<std::unique_ptr<Value>>()); } 527 | "[" value_const_list "]" { $$ = new ListValue(@$, $2); } 528 ; 529 530value_const_list: 531 value_const { $$ = new std::vector<std::unique_ptr<Value>>(); $$->emplace_back($1); } 532 | value_const_list value_const { $1->emplace_back($2); $$ = $1; } 533 ; 534 535/* 2.2.7.7 Object Value */ 536/* REVIEW: Inefficient, like ListValue. */ 537object_value: "{" "}" { $$ = new ObjectValue(@$, new std::vector<std::unique_ptr<ObjectField>>()); } 538 | "{" object_field_list "}" { $$ = new ObjectValue(@$, $2); } 539 ; 540 541object_field_list: 542 object_field { $$ = new std::vector<std::unique_ptr<ObjectField>>(); $$->emplace_back($1); } 543 | object_field_list object_field { $1->emplace_back($2); $$ = $1; } 544 ; 545 546object_field: name ":" value { $$ = new ObjectField(@$, $1, $3); } 547 ; 548 549object_value_const: 550 "{" "}" { $$ = new ObjectValue(@$, new std::vector<std::unique_ptr<ObjectField>>()); } 551 | "{" object_field_const_list "}" { $$ = new ObjectValue(@$, $2); } 552 ; 553 554object_field_const_list: 555 object_field_const { $$ = new std::vector<std::unique_ptr<ObjectField>>(); $$->emplace_back($1); } 556 | object_field_const_list object_field_const { $1->emplace_back($2); $$ = $1; } 557 ; 558 559object_field_const: name ":" value_const { $$ = new ObjectField(@$, $1, $3); } 560 ; 561 562/* 2.2.10 Directives */ 563 564directives: directive_list 565 ; 566 567directives_opt: %empty { $$ = nullptr; } 568 | directives 569 ; 570 571directive_list: directive { $$ = new std::vector<std::unique_ptr<Directive>>(); $$->emplace_back($1); } 572 | directive_list directive { $1->emplace_back($2); $$ = $1; } 573 ; 574 575directive: "@" name arguments_opt { $$ = new Directive(@$, $2, $3); } 576 ; 577 578/* 2.2.9 Types */ 579 580type: type_name { $$ = static_cast<Type *>($1); } 581 | list_type { $$ = static_cast<Type *>($1); } 582 | non_null_type { $$ = static_cast<Type *>($1); } 583 ; 584 585type_name: name { $$ = new NamedType(@$, $1); } 586 ; 587 588list_type: "[" type "]" { $$ = new ListType(@$, $2); } 589 ; 590 591non_null_type: type_name "!" { $$ = new NonNullType(@$, $1); } 592 | list_type "!" { $$ = new NonNullType(@$, $1); } 593 ; 594 595/* Experimental schema parsing support. */ 596 597schema_definition: SCHEMA directives_opt "{" operation_type_definition_list "}" { $$ = new SchemaDefinition(@$, $2, $4); } 598 ; 599 600operation_type_definition_list: 601 operation_type_definition { $$ = new std::vector<std::unique_ptr<OperationTypeDefinition>>(); $$->emplace_back($1); } 602 | operation_type_definition_list operation_type_definition { $1->emplace_back($2); $$ = $1; } 603 ; 604 605operation_type_definition: 606 operation_type ":" type_name { $$ = new OperationTypeDefinition(@$, $1, $3); } 607 ; 608 609scalar_type_definition: SCALAR name directives_opt { $$ = new ScalarTypeDefinition(@$, $2, $3); } 610 ; 611 612object_type_definition: TYPE name implements_interfaces_opt directives_opt "{" field_definition_list "}" { $$ = new ObjectTypeDefinition(@$, $2, $3, $4, $6); } 613 ; 614 615implements_interfaces_opt: %empty { $$ = nullptr; } 616 | IMPLEMENTS type_name_list { $$ = $2; } 617 ; 618 619type_name_list: type_name { $$ = new std::vector<std::unique_ptr<NamedType>>(); $$->emplace_back($1); } 620 | type_name_list type_name { $1->emplace_back($2); $$ = $1; } 621 ; 622 623field_definition: name arguments_definition_opt ":" type directives_opt { $$ = new FieldDefinition(@$, $1, $2, $4, $5); } 624 ; 625 626field_definition_list: 627 field_definition { $$ = new std::vector<std::unique_ptr<FieldDefinition>>(); $$->emplace_back($1); } 628 | field_definition_list field_definition { $1->emplace_back($2); $$ = $1; } 629 ; 630 631arguments_definition_opt: %empty { $$ = nullptr; } 632 | arguments_definition { $$ = $1; } 633 ; 634 635arguments_definition: "(" input_value_definition_list ")" { $$ = $2; } 636 ; 637 638input_value_definition_list: input_value_definition { $$ = new std::vector<std::unique_ptr<InputValueDefinition>>(); $$->emplace_back($1); } 639 | input_value_definition_list input_value_definition { $1->emplace_back($2); $$ = $1; } 640 ; 641 642input_value_definition: name ":" type default_value_opt directives_opt { $$ = new InputValueDefinition(@$, $1, $3, $4, $5); } 643 644interface_type_definition: INTERFACE name directives_opt "{" field_definition_list "}" { $$ = new InterfaceTypeDefinition(@$, $2, $3, $5); } 645 ; 646 647union_type_definition: UNION name directives_opt "=" union_members { $$ = new UnionTypeDefinition(@$, $2, $3, $5); } 648 ; 649 650union_members: type_name { $$ = new std::vector<std::unique_ptr<NamedType>>(); $$->emplace_back($1); } 651 | union_members "|" type_name { $1->emplace_back($3); $$ = $1; } 652 ; 653 654enum_type_definition: ENUM name directives_opt "{" enum_value_definition_list "}" { $$ = new EnumTypeDefinition(@$, $2, $3, $5); } 655 ; 656 657enum_value_definition: name directives_opt { $$ = new EnumValueDefinition(@$, $1, $2); } 658 ; 659 660enum_value_definition_list: 661 enum_value_definition { $$ = new std::vector<std::unique_ptr<EnumValueDefinition>>(); $$->emplace_back($1); } 662 | enum_value_definition_list enum_value_definition { $1->emplace_back($2); $$ = $1; } 663 ; 664 665input_object_type_definition: INPUT name directives_opt "{" input_value_definition_list "}" { $$ = new InputObjectTypeDefinition(@$, $2, $3, $5); } 666 ; 667 668type_extension_definition: EXTEND object_type_definition { $$ = new TypeExtensionDefinition(@$, $2); } 669 ; 670 671directive_definition: DIRECTIVE "@" name arguments_definition_opt ON directive_locations { $$ = new DirectiveDefinition(@$, $3, $4, $6); } 672 ; 673 674directive_locations: 675 name { $$ = new std::vector<std::unique_ptr<Name>>(); $$->emplace_back($1); } 676 | directive_locations "|" name { $1->emplace_back($3); $$ = $1; } 677 ; 678 679%% 680 681void yy::GraphQLParserImpl::error(const yy::location &loc, const std::string &str) { 682 std::ostringstream out; 683 out << loc << ": " << str; 684 if (outError) { 685 *outError = strdup(out.str().c_str()); 686 } 687} 688 689/* Workaround for syntax_error ctor being marked inline, which causes link 690 errors if used from lexer.lpp. */ 691yy::GraphQLParserImpl::syntax_error make_error(const yy::location &loc, const std::string &str) { 692 return yy::GraphQLParserImpl::syntax_error(loc, str); 693} 694