graphql-c_parser 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,942 @@
1
+ %require "3.8"
2
+ %define api.pure full
3
+ %define parse.error detailed
4
+
5
+ %{
6
+ // C Declarations
7
+ #include <ruby.h>
8
+ #define YYSTYPE VALUE
9
+ int yylex(YYSTYPE *, VALUE, VALUE);
10
+ void yyerror(VALUE, VALUE, const char*);
11
+
12
+ static VALUE GraphQL_Language_Nodes_NONE;
13
+ static VALUE r_string_query;
14
+
15
+ #define MAKE_AST_NODE(node_class_name, nargs, ...) rb_funcall(GraphQL_Language_Nodes_##node_class_name, rb_intern("from_a"), nargs + 1, filename,__VA_ARGS__)
16
+
17
+ #define SETUP_NODE_CLASS_VARIABLE(node_class_name) static VALUE GraphQL_Language_Nodes_##node_class_name;
18
+
19
+ SETUP_NODE_CLASS_VARIABLE(Argument)
20
+ SETUP_NODE_CLASS_VARIABLE(Directive)
21
+ SETUP_NODE_CLASS_VARIABLE(Document)
22
+ SETUP_NODE_CLASS_VARIABLE(Enum)
23
+ SETUP_NODE_CLASS_VARIABLE(Field)
24
+ SETUP_NODE_CLASS_VARIABLE(FragmentDefinition)
25
+ SETUP_NODE_CLASS_VARIABLE(FragmentSpread)
26
+ SETUP_NODE_CLASS_VARIABLE(InlineFragment)
27
+ SETUP_NODE_CLASS_VARIABLE(InputObject)
28
+ SETUP_NODE_CLASS_VARIABLE(ListType)
29
+ SETUP_NODE_CLASS_VARIABLE(NonNullType)
30
+ SETUP_NODE_CLASS_VARIABLE(NullValue)
31
+ SETUP_NODE_CLASS_VARIABLE(OperationDefinition)
32
+ SETUP_NODE_CLASS_VARIABLE(TypeName)
33
+ SETUP_NODE_CLASS_VARIABLE(VariableDefinition)
34
+ SETUP_NODE_CLASS_VARIABLE(VariableIdentifier)
35
+
36
+ SETUP_NODE_CLASS_VARIABLE(ScalarTypeDefinition)
37
+ SETUP_NODE_CLASS_VARIABLE(ObjectTypeDefinition)
38
+ SETUP_NODE_CLASS_VARIABLE(InterfaceTypeDefinition)
39
+ SETUP_NODE_CLASS_VARIABLE(UnionTypeDefinition)
40
+ SETUP_NODE_CLASS_VARIABLE(EnumTypeDefinition)
41
+ SETUP_NODE_CLASS_VARIABLE(InputObjectTypeDefinition)
42
+ SETUP_NODE_CLASS_VARIABLE(EnumValueDefinition)
43
+ SETUP_NODE_CLASS_VARIABLE(DirectiveDefinition)
44
+ SETUP_NODE_CLASS_VARIABLE(DirectiveLocation)
45
+ SETUP_NODE_CLASS_VARIABLE(FieldDefinition)
46
+ SETUP_NODE_CLASS_VARIABLE(InputValueDefinition)
47
+ SETUP_NODE_CLASS_VARIABLE(SchemaDefinition)
48
+
49
+ SETUP_NODE_CLASS_VARIABLE(ScalarTypeExtension)
50
+ SETUP_NODE_CLASS_VARIABLE(ObjectTypeExtension)
51
+ SETUP_NODE_CLASS_VARIABLE(InterfaceTypeExtension)
52
+ SETUP_NODE_CLASS_VARIABLE(UnionTypeExtension)
53
+ SETUP_NODE_CLASS_VARIABLE(EnumTypeExtension)
54
+ SETUP_NODE_CLASS_VARIABLE(InputObjectTypeExtension)
55
+ SETUP_NODE_CLASS_VARIABLE(SchemaExtension)
56
+ %}
57
+
58
+ %param {VALUE parser}
59
+ %param {VALUE filename}
60
+
61
+ // YACC Declarations
62
+ %token AMP 200
63
+ %token BANG 201
64
+ %token COLON 202
65
+ %token DIRECTIVE 203
66
+ %token DIR_SIGN 204
67
+ %token ENUM 205
68
+ %token ELLIPSIS 206
69
+ %token EQUALS 207
70
+ %token EXTEND 208
71
+ %token FALSE_LITERAL 209
72
+ %token FLOAT 210
73
+ %token FRAGMENT 211
74
+ %token IDENTIFIER 212
75
+ %token INPUT 213
76
+ %token IMPLEMENTS 214
77
+ %token INT 215
78
+ %token INTERFACE 216
79
+ %token LBRACKET 217
80
+ %token LCURLY 218
81
+ %token LPAREN 219
82
+ %token MUTATION 220
83
+ %token NULL_LITERAL 221
84
+ %token ON 222
85
+ %token PIPE 223
86
+ %token QUERY 224
87
+ %token RBRACKET 225
88
+ %token RCURLY 226
89
+ %token REPEATABLE 227
90
+ %token RPAREN 228
91
+ %token SCALAR 229
92
+ %token SCHEMA 230
93
+ %token STRING 231
94
+ %token SUBSCRIPTION 232
95
+ %token TRUE_LITERAL 233
96
+ %token TYPE_LITERAL 234
97
+ %token UNION 235
98
+ %token VAR_SIGN 236
99
+
100
+ %%
101
+
102
+ // YACC Rules
103
+ start: document { rb_ivar_set(parser, rb_intern("@result"), $1); }
104
+
105
+ document: definitions_list {
106
+ VALUE position_source = rb_ary_entry($1, 0);
107
+ VALUE line, col;
108
+ if (RB_TEST(position_source)) {
109
+ line = rb_funcall(position_source, rb_intern("line"), 0);
110
+ col = rb_funcall(position_source, rb_intern("col"), 0);
111
+ } else {
112
+ line = INT2FIX(1);
113
+ col = INT2FIX(1);
114
+ }
115
+ $$ = MAKE_AST_NODE(Document, 3, line, col, $1);
116
+ }
117
+
118
+ definitions_list:
119
+ definition { $$ = rb_ary_new_from_args(1, $1); }
120
+ | definitions_list definition { rb_ary_push($$, $2); }
121
+
122
+ definition:
123
+ executable_definition
124
+ | type_system_definition
125
+ | type_system_extension
126
+
127
+ executable_definition:
128
+ operation_definition
129
+ | fragment_definition
130
+
131
+ operation_definition:
132
+ operation_type operation_name_opt variable_definitions_opt directives_list_opt selection_set {
133
+ $$ = MAKE_AST_NODE(OperationDefinition, 7,
134
+ rb_ary_entry($1, 1),
135
+ rb_ary_entry($1, 2),
136
+ rb_ary_entry($1, 3),
137
+ (RB_TEST($2) ? rb_ary_entry($2, 3) : Qnil),
138
+ $3,
139
+ $4,
140
+ $5
141
+ );
142
+ }
143
+ | LCURLY selection_list RCURLY {
144
+ $$ = MAKE_AST_NODE(OperationDefinition, 7,
145
+ rb_ary_entry($1, 1),
146
+ rb_ary_entry($1, 2),
147
+ r_string_query,
148
+ Qnil,
149
+ GraphQL_Language_Nodes_NONE,
150
+ GraphQL_Language_Nodes_NONE,
151
+ $2
152
+ );
153
+ }
154
+ | LCURLY RCURLY {
155
+ $$ = MAKE_AST_NODE(OperationDefinition, 7,
156
+ rb_ary_entry($1, 1),
157
+ rb_ary_entry($1, 2),
158
+ r_string_query,
159
+ Qnil,
160
+ GraphQL_Language_Nodes_NONE,
161
+ GraphQL_Language_Nodes_NONE,
162
+ GraphQL_Language_Nodes_NONE
163
+ );
164
+ }
165
+
166
+ operation_type:
167
+ QUERY
168
+ | MUTATION
169
+ | SUBSCRIPTION
170
+
171
+ operation_name_opt:
172
+ /* none */ { $$ = Qnil; }
173
+ | name
174
+
175
+ variable_definitions_opt:
176
+ /* none */ { $$ = GraphQL_Language_Nodes_NONE; }
177
+ | LPAREN variable_definitions_list RPAREN { $$ = $2; }
178
+
179
+ variable_definitions_list:
180
+ variable_definition { $$ = rb_ary_new_from_args(1, $1); }
181
+ | variable_definitions_list variable_definition { rb_ary_push($$, $2); }
182
+
183
+ variable_definition:
184
+ VAR_SIGN name COLON type default_value_opt {
185
+ $$ = MAKE_AST_NODE(VariableDefinition, 5,
186
+ rb_ary_entry($1, 1),
187
+ rb_ary_entry($1, 2),
188
+ rb_ary_entry($2, 3),
189
+ $4,
190
+ $5
191
+ );
192
+ }
193
+
194
+ default_value_opt:
195
+ /* none */ { $$ = Qnil; }
196
+ | EQUALS literal_value { $$ = $2; }
197
+
198
+ selection_list:
199
+ selection { $$ = rb_ary_new_from_args(1, $1); }
200
+ | selection_list selection { rb_ary_push($$, $2); }
201
+
202
+ selection:
203
+ field
204
+ | fragment_spread
205
+ | inline_fragment
206
+
207
+ selection_set:
208
+ LCURLY selection_list RCURLY { $$ = $2; }
209
+
210
+ selection_set_opt:
211
+ /* none */ { $$ = rb_ary_new(); }
212
+ | selection_set
213
+
214
+ field:
215
+ name COLON name arguments_opt directives_list_opt selection_set_opt {
216
+ $$ = MAKE_AST_NODE(Field, 7,
217
+ rb_ary_entry($1, 1),
218
+ rb_ary_entry($1, 2),
219
+ rb_ary_entry($1, 3), // alias
220
+ rb_ary_entry($3, 3), // name
221
+ $4, // args
222
+ $5, // directives
223
+ $6 // subselections
224
+ );
225
+ }
226
+ | name arguments_opt directives_list_opt selection_set_opt {
227
+ $$ = MAKE_AST_NODE(Field, 7,
228
+ rb_ary_entry($1, 1),
229
+ rb_ary_entry($1, 2),
230
+ Qnil, // alias
231
+ rb_ary_entry($1, 3), // name
232
+ $2, // args
233
+ $3, // directives
234
+ $4 // subselections
235
+ );
236
+ }
237
+
238
+ arguments_opt:
239
+ /* none */ { $$ = GraphQL_Language_Nodes_NONE; }
240
+ | LPAREN arguments_list RPAREN { $$ = $2; }
241
+
242
+ arguments_list:
243
+ argument { $$ = rb_ary_new_from_args(1, $1); }
244
+ | arguments_list argument { rb_ary_push($$, $2); }
245
+
246
+ argument:
247
+ name COLON input_value {
248
+ $$ = MAKE_AST_NODE(Argument, 4,
249
+ rb_ary_entry($1, 1),
250
+ rb_ary_entry($1, 2),
251
+ rb_ary_entry($1, 3),
252
+ $3
253
+ );
254
+ }
255
+
256
+ literal_value:
257
+ FLOAT { $$ = rb_funcall(rb_ary_entry($1, 3), rb_intern("to_f"), 0); }
258
+ | INT { $$ = rb_funcall(rb_ary_entry($1, 3), rb_intern("to_i"), 0); }
259
+ | STRING { $$ = rb_ary_entry($1, 3); }
260
+ | TRUE_LITERAL { $$ = Qtrue; }
261
+ | FALSE_LITERAL { $$ = Qfalse; }
262
+ | null_value
263
+ | enum_value
264
+ | list_value
265
+ | object_literal_value
266
+
267
+ input_value:
268
+ literal_value
269
+ | variable
270
+ | object_value
271
+
272
+ null_value: NULL_LITERAL {
273
+ $$ = MAKE_AST_NODE(NullValue, 3,
274
+ rb_ary_entry($1, 1),
275
+ rb_ary_entry($1, 2),
276
+ rb_ary_entry($1, 3)
277
+ );
278
+ }
279
+
280
+ variable: VAR_SIGN name {
281
+ $$ = MAKE_AST_NODE(VariableIdentifier, 3,
282
+ rb_ary_entry($1, 1),
283
+ rb_ary_entry($1, 2),
284
+ rb_ary_entry($2, 3)
285
+ );
286
+ }
287
+
288
+ list_value:
289
+ LBRACKET RBRACKET { $$ = GraphQL_Language_Nodes_NONE; }
290
+ | LBRACKET list_value_list RBRACKET { $$ = $2; }
291
+
292
+ list_value_list:
293
+ input_value { $$ = rb_ary_new_from_args(1, $1); }
294
+ | list_value_list input_value { rb_ary_push($$, $2); }
295
+
296
+ enum_name: /* any identifier, but not "true", "false" or "null" */
297
+ IDENTIFIER
298
+ | FRAGMENT
299
+ | REPEATABLE
300
+ | ON
301
+ | operation_type
302
+ | schema_keyword
303
+
304
+ enum_value: enum_name {
305
+ $$ = MAKE_AST_NODE(Enum, 3,
306
+ rb_ary_entry($1, 1),
307
+ rb_ary_entry($1, 2),
308
+ rb_ary_entry($1, 3)
309
+ );
310
+ }
311
+
312
+ object_value:
313
+ LCURLY object_value_list_opt RCURLY {
314
+ $$ = MAKE_AST_NODE(InputObject, 3,
315
+ rb_ary_entry($1, 1),
316
+ rb_ary_entry($1, 2),
317
+ $2
318
+ );
319
+ }
320
+
321
+ object_value_list_opt:
322
+ /* nothing */ { $$ = GraphQL_Language_Nodes_NONE; }
323
+ | object_value_list
324
+
325
+ object_value_list:
326
+ object_value_field { $$ = rb_ary_new_from_args(1, $1); }
327
+ | object_value_list object_value_field { rb_ary_push($$, $2); }
328
+
329
+ object_value_field:
330
+ name COLON input_value {
331
+ $$ = MAKE_AST_NODE(Argument, 4,
332
+ rb_ary_entry($1, 1),
333
+ rb_ary_entry($1, 2),
334
+ rb_ary_entry($1, 3),
335
+ $3
336
+ );
337
+ }
338
+
339
+ /* like the previous, but with literals only: */
340
+ object_literal_value:
341
+ LCURLY object_literal_value_list_opt RCURLY {
342
+ $$ = MAKE_AST_NODE(InputObject, 3,
343
+ rb_ary_entry($1, 1),
344
+ rb_ary_entry($1, 2),
345
+ $2
346
+ );
347
+ }
348
+
349
+ object_literal_value_list_opt:
350
+ /* nothing */ { $$ = GraphQL_Language_Nodes_NONE; }
351
+ | object_literal_value_list
352
+
353
+ object_literal_value_list:
354
+ object_literal_value_field { $$ = rb_ary_new_from_args(1, $1); }
355
+ | object_literal_value_list object_literal_value_field { rb_ary_push($$, $2); }
356
+
357
+ object_literal_value_field:
358
+ name COLON literal_value {
359
+ $$ = MAKE_AST_NODE(Argument, 4,
360
+ rb_ary_entry($1, 1),
361
+ rb_ary_entry($1, 2),
362
+ rb_ary_entry($1, 3),
363
+ $3
364
+ );
365
+ }
366
+
367
+
368
+ directives_list_opt:
369
+ /* none */ { $$ = GraphQL_Language_Nodes_NONE; }
370
+ | directives_list
371
+
372
+ directives_list:
373
+ directive { $$ = rb_ary_new_from_args(1, $1); }
374
+ | directives_list directive { rb_ary_push($$, $2); }
375
+
376
+ directive: DIR_SIGN name arguments_opt {
377
+ $$ = MAKE_AST_NODE(Directive, 4,
378
+ rb_ary_entry($1, 1),
379
+ rb_ary_entry($1, 2),
380
+ rb_ary_entry($2, 3),
381
+ $3
382
+ );
383
+ }
384
+
385
+ name:
386
+ name_without_on
387
+ | ON
388
+
389
+ schema_keyword:
390
+ SCHEMA
391
+ | SCALAR
392
+ | TYPE_LITERAL
393
+ | IMPLEMENTS
394
+ | INTERFACE
395
+ | UNION
396
+ | ENUM
397
+ | INPUT
398
+ | DIRECTIVE
399
+
400
+ name_without_on:
401
+ IDENTIFIER
402
+ | FRAGMENT
403
+ | REPEATABLE
404
+ | TRUE_LITERAL
405
+ | FALSE_LITERAL
406
+ | operation_type
407
+ | schema_keyword
408
+
409
+
410
+ fragment_spread:
411
+ ELLIPSIS name_without_on directives_list_opt {
412
+ $$ = MAKE_AST_NODE(FragmentSpread, 4,
413
+ rb_ary_entry($1, 1),
414
+ rb_ary_entry($1, 2),
415
+ rb_ary_entry($2, 3),
416
+ $3
417
+ );
418
+ }
419
+
420
+ inline_fragment:
421
+ ELLIPSIS ON type directives_list_opt selection_set {
422
+ $$ = MAKE_AST_NODE(InlineFragment, 5,
423
+ rb_ary_entry($1, 1),
424
+ rb_ary_entry($1, 2),
425
+ $3,
426
+ $4,
427
+ $5
428
+ );
429
+ }
430
+ | ELLIPSIS directives_list_opt selection_set {
431
+ $$ = MAKE_AST_NODE(InlineFragment, 5,
432
+ rb_ary_entry($1, 1),
433
+ rb_ary_entry($1, 2),
434
+ Qnil,
435
+ $2,
436
+ $3
437
+ );
438
+ }
439
+
440
+ fragment_definition:
441
+ FRAGMENT fragment_name_opt ON type directives_list_opt selection_set {
442
+ $$ = MAKE_AST_NODE(FragmentDefinition, 6,
443
+ rb_ary_entry($1, 1),
444
+ rb_ary_entry($1, 2),
445
+ $2,
446
+ $4,
447
+ $5,
448
+ $6
449
+ );
450
+ }
451
+
452
+ fragment_name_opt:
453
+ /* none */ { $$ = Qnil; }
454
+ | name_without_on { $$ = rb_ary_entry($1, 3); }
455
+
456
+ type:
457
+ nullable_type
458
+ | nullable_type BANG { $$ = MAKE_AST_NODE(NonNullType, 3, rb_funcall($1, rb_intern("line"), 0), rb_funcall($1, rb_intern("col"), 0), $1); }
459
+
460
+ nullable_type:
461
+ name {
462
+ $$ = MAKE_AST_NODE(TypeName, 3,
463
+ rb_ary_entry($1, 1),
464
+ rb_ary_entry($1, 2),
465
+ rb_ary_entry($1, 3)
466
+ );
467
+ }
468
+ | LBRACKET type RBRACKET {
469
+ $$ = MAKE_AST_NODE(ListType, 3,
470
+ rb_funcall($2, rb_intern("line"), 0),
471
+ rb_funcall($2, rb_intern("col"), 0),
472
+ $2
473
+ );
474
+ }
475
+
476
+ type_system_definition:
477
+ schema_definition
478
+ | type_definition
479
+ | directive_definition
480
+
481
+ schema_definition:
482
+ SCHEMA directives_list_opt operation_type_definition_list_opt {
483
+ $$ = MAKE_AST_NODE(SchemaDefinition, 6,
484
+ rb_ary_entry($1, 1),
485
+ rb_ary_entry($1, 2),
486
+ // TODO use static strings:
487
+ rb_hash_aref($3, rb_str_new_cstr("query")),
488
+ rb_hash_aref($3, rb_str_new_cstr("mutation")),
489
+ rb_hash_aref($3, rb_str_new_cstr("subscription")),
490
+ $2
491
+ );
492
+ }
493
+
494
+ operation_type_definition_list_opt:
495
+ /* none */ { $$ = rb_hash_new(); }
496
+ | LCURLY operation_type_definition_list RCURLY { $$ = $2; }
497
+
498
+ operation_type_definition_list:
499
+ operation_type_definition {
500
+ $$ = rb_hash_new();
501
+ rb_hash_aset($$, rb_ary_entry($1, 0), rb_ary_entry($1, 1));
502
+ }
503
+ | operation_type_definition_list operation_type_definition {
504
+ rb_hash_aset($$, rb_ary_entry($2, 0), rb_ary_entry($2, 1));
505
+ }
506
+
507
+ operation_type_definition:
508
+ operation_type COLON name {
509
+ $$ = rb_ary_new_from_args(2, rb_ary_entry($1, 3), rb_ary_entry($3, 3));
510
+ }
511
+
512
+ type_definition:
513
+ scalar_type_definition
514
+ | object_type_definition
515
+ | interface_type_definition
516
+ | union_type_definition
517
+ | enum_type_definition
518
+ | input_object_type_definition
519
+
520
+ description: STRING
521
+
522
+ description_opt:
523
+ /* none */ { $$ = Qnil; }
524
+ | description
525
+
526
+ scalar_type_definition:
527
+ description_opt SCALAR name directives_list_opt {
528
+ $$ = MAKE_AST_NODE(ScalarTypeDefinition, 5,
529
+ rb_ary_entry($2, 1),
530
+ rb_ary_entry($2, 2),
531
+ rb_ary_entry($3, 3),
532
+ // TODO see get_description for reading a description from comments
533
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
534
+ $4
535
+ );
536
+ }
537
+
538
+ object_type_definition:
539
+ description_opt TYPE_LITERAL name implements_opt directives_list_opt field_definition_list_opt {
540
+ $$ = MAKE_AST_NODE(ObjectTypeDefinition, 7,
541
+ rb_ary_entry($2, 1),
542
+ rb_ary_entry($2, 2),
543
+ rb_ary_entry($3, 3),
544
+ $4, // implements
545
+ // TODO see get_description for reading a description from comments
546
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
547
+ $5,
548
+ $6
549
+ );
550
+ }
551
+
552
+ implements_opt:
553
+ /* none */ { $$ = GraphQL_Language_Nodes_NONE; }
554
+ | IMPLEMENTS AMP interfaces_list { $$ = $3; }
555
+ | IMPLEMENTS interfaces_list { $$ = $2; }
556
+ | IMPLEMENTS legacy_interfaces_list { $$ = $2; }
557
+
558
+ interfaces_list:
559
+ name {
560
+ VALUE new_name = MAKE_AST_NODE(TypeName, 3,
561
+ rb_ary_entry($1, 1),
562
+ rb_ary_entry($1, 2),
563
+ rb_ary_entry($1, 3)
564
+ );
565
+ $$ = rb_ary_new_from_args(1, new_name);
566
+ }
567
+ | interfaces_list AMP name {
568
+ VALUE new_name = MAKE_AST_NODE(TypeName, 3, rb_ary_entry($3, 1), rb_ary_entry($3, 2), rb_ary_entry($3, 3));
569
+ rb_ary_push($$, new_name);
570
+ }
571
+
572
+ legacy_interfaces_list:
573
+ name {
574
+ VALUE new_name = MAKE_AST_NODE(TypeName, 3,
575
+ rb_ary_entry($1, 1),
576
+ rb_ary_entry($1, 2),
577
+ rb_ary_entry($1, 3)
578
+ );
579
+ $$ = rb_ary_new_from_args(1, new_name);
580
+ }
581
+ | legacy_interfaces_list name {
582
+ rb_ary_push($$, MAKE_AST_NODE(TypeName, 3, rb_ary_entry($2, 1), rb_ary_entry($2, 2), rb_ary_entry($2, 3)));
583
+ }
584
+
585
+ input_value_definition:
586
+ description_opt name COLON type default_value_opt directives_list_opt {
587
+ $$ = MAKE_AST_NODE(InputValueDefinition, 7,
588
+ rb_ary_entry($2, 1),
589
+ rb_ary_entry($2, 2),
590
+ rb_ary_entry($2, 3),
591
+ $4,
592
+ $5,
593
+ // TODO see get_description for reading a description from comments
594
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
595
+ $6
596
+ );
597
+ }
598
+
599
+ input_value_definition_list:
600
+ input_value_definition { $$ = rb_ary_new_from_args(1, $1); }
601
+ | input_value_definition_list input_value_definition { rb_ary_push($$, $2); }
602
+
603
+ arguments_definitions_opt:
604
+ /* none */ { $$ = GraphQL_Language_Nodes_NONE; }
605
+ | LPAREN input_value_definition_list RPAREN { $$ = $2; }
606
+
607
+ field_definition:
608
+ description_opt name arguments_definitions_opt COLON type directives_list_opt {
609
+ $$ = MAKE_AST_NODE(FieldDefinition, 7,
610
+ rb_ary_entry($2, 1),
611
+ rb_ary_entry($2, 2),
612
+ rb_ary_entry($2, 3),
613
+ $5,
614
+ // TODO see get_description for reading a description from comments
615
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
616
+ $3,
617
+ $6
618
+ );
619
+ }
620
+
621
+ field_definition_list_opt:
622
+ /* none */ { $$ = GraphQL_Language_Nodes_NONE; }
623
+ | LCURLY field_definition_list RCURLY { $$ = $2; }
624
+
625
+ field_definition_list:
626
+ /* none - this is not actually valid but graphql-ruby used to print this */ { $$ = GraphQL_Language_Nodes_NONE; }
627
+ | field_definition { $$ = rb_ary_new_from_args(1, $1); }
628
+ | field_definition_list field_definition { rb_ary_push($$, $2); }
629
+
630
+ interface_type_definition:
631
+ description_opt INTERFACE name implements_opt directives_list_opt field_definition_list_opt {
632
+ $$ = MAKE_AST_NODE(InterfaceTypeDefinition, 7,
633
+ rb_ary_entry($2, 1),
634
+ rb_ary_entry($2, 2),
635
+ rb_ary_entry($3, 3),
636
+ // TODO see get_description for reading a description from comments
637
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
638
+ $4,
639
+ $5,
640
+ $6
641
+ );
642
+ }
643
+
644
+ union_members:
645
+ name {
646
+ VALUE new_member = MAKE_AST_NODE(TypeName, 3,
647
+ rb_ary_entry($1, 1),
648
+ rb_ary_entry($1, 2),
649
+ rb_ary_entry($1, 3)
650
+ );
651
+ $$ = rb_ary_new_from_args(1, new_member);
652
+ }
653
+ | union_members PIPE name {
654
+ rb_ary_push($$, MAKE_AST_NODE(TypeName, 3, rb_ary_entry($3, 1), rb_ary_entry($3, 2), rb_ary_entry($3, 3)));
655
+ }
656
+
657
+ union_type_definition:
658
+ description_opt UNION name directives_list_opt EQUALS union_members {
659
+ $$ = MAKE_AST_NODE(UnionTypeDefinition, 6,
660
+ rb_ary_entry($2, 1),
661
+ rb_ary_entry($2, 2),
662
+ rb_ary_entry($3, 3),
663
+ $6, // types
664
+ // TODO see get_description for reading a description from comments
665
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
666
+ $4
667
+ );
668
+ }
669
+
670
+ enum_type_definition:
671
+ description_opt ENUM name directives_list_opt LCURLY enum_value_definitions RCURLY {
672
+ $$ = MAKE_AST_NODE(EnumTypeDefinition, 6,
673
+ rb_ary_entry($2, 1),
674
+ rb_ary_entry($2, 2),
675
+ rb_ary_entry($3, 3),
676
+ // TODO see get_description for reading a description from comments
677
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
678
+ $4,
679
+ $6
680
+ );
681
+ }
682
+
683
+ enum_value_definition:
684
+ description_opt enum_name directives_list_opt {
685
+ $$ = MAKE_AST_NODE(EnumValueDefinition, 5,
686
+ rb_ary_entry($2, 1),
687
+ rb_ary_entry($2, 2),
688
+ rb_ary_entry($2, 3),
689
+ // TODO see get_description for reading a description from comments
690
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
691
+ $3
692
+ );
693
+ }
694
+
695
+ enum_value_definitions:
696
+ enum_value_definition { $$ = rb_ary_new_from_args(1, $1); }
697
+ | enum_value_definitions enum_value_definition { rb_ary_push($$, $2); }
698
+
699
+ input_object_type_definition:
700
+ description_opt INPUT name directives_list_opt LCURLY input_value_definition_list RCURLY {
701
+ $$ = MAKE_AST_NODE(InputObjectTypeDefinition, 6,
702
+ rb_ary_entry($2, 1),
703
+ rb_ary_entry($2, 2),
704
+ rb_ary_entry($3, 3),
705
+ // TODO see get_description for reading a description from comments
706
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
707
+ $4,
708
+ $6
709
+ );
710
+ }
711
+
712
+ directive_definition:
713
+ description_opt DIRECTIVE DIR_SIGN name arguments_definitions_opt directive_repeatable_opt ON directive_locations {
714
+ $$ = MAKE_AST_NODE(DirectiveDefinition, 7,
715
+ rb_ary_entry($2, 1),
716
+ rb_ary_entry($2, 2),
717
+ rb_ary_entry($4, 3),
718
+ (RB_TEST($6) ? Qtrue : Qfalse), // repeatable
719
+ // TODO see get_description for reading a description from comments
720
+ (RB_TEST($1) ? rb_ary_entry($1, 3) : Qnil),
721
+ $5,
722
+ $8
723
+ );
724
+ }
725
+
726
+ directive_repeatable_opt:
727
+ /* nothing */ { $$ = Qnil; }
728
+ | REPEATABLE { $$ = Qtrue; }
729
+
730
+ directive_locations:
731
+ name { $$ = rb_ary_new_from_args(1, MAKE_AST_NODE(DirectiveLocation, 3, rb_ary_entry($1, 1), rb_ary_entry($1, 2), rb_ary_entry($1, 3))); }
732
+ | directive_locations PIPE name { rb_ary_push($$, MAKE_AST_NODE(DirectiveLocation, 3, rb_ary_entry($3, 1), rb_ary_entry($3, 2), rb_ary_entry($3, 3))); }
733
+
734
+
735
+ type_system_extension:
736
+ schema_extension
737
+ | type_extension
738
+
739
+ schema_extension:
740
+ EXTEND SCHEMA directives_list_opt LCURLY operation_type_definition_list RCURLY {
741
+ $$ = MAKE_AST_NODE(SchemaExtension, 6,
742
+ rb_ary_entry($1, 1),
743
+ rb_ary_entry($1, 2),
744
+ // TODO use static strings:
745
+ rb_hash_aref($5, rb_str_new_cstr("query")),
746
+ rb_hash_aref($5, rb_str_new_cstr("mutation")),
747
+ rb_hash_aref($5, rb_str_new_cstr("subscription")),
748
+ $3
749
+ );
750
+ }
751
+ | EXTEND SCHEMA directives_list {
752
+ $$ = MAKE_AST_NODE(SchemaExtension, 6,
753
+ rb_ary_entry($1, 1),
754
+ rb_ary_entry($1, 2),
755
+ Qnil,
756
+ Qnil,
757
+ Qnil,
758
+ $3
759
+ );
760
+ }
761
+
762
+ type_extension:
763
+ scalar_type_extension
764
+ | object_type_extension
765
+ | interface_type_extension
766
+ | union_type_extension
767
+ | enum_type_extension
768
+ | input_object_type_extension
769
+
770
+ scalar_type_extension: EXTEND SCALAR name directives_list {
771
+ $$ = MAKE_AST_NODE(ScalarTypeExtension, 4,
772
+ rb_ary_entry($1, 1),
773
+ rb_ary_entry($1, 2),
774
+ rb_ary_entry($3, 3),
775
+ $4
776
+ );
777
+ }
778
+
779
+ object_type_extension:
780
+ EXTEND TYPE_LITERAL name implements_opt directives_list_opt field_definition_list_opt {
781
+ $$ = MAKE_AST_NODE(ObjectTypeExtension, 6,
782
+ rb_ary_entry($1, 1),
783
+ rb_ary_entry($1, 2),
784
+ rb_ary_entry($3, 3),
785
+ $4, // implements
786
+ $5,
787
+ $6
788
+ );
789
+ }
790
+
791
+ interface_type_extension:
792
+ EXTEND INTERFACE name implements_opt directives_list_opt field_definition_list_opt {
793
+ $$ = MAKE_AST_NODE(InterfaceTypeExtension, 6,
794
+ rb_ary_entry($1, 1),
795
+ rb_ary_entry($1, 2),
796
+ rb_ary_entry($3, 3),
797
+ $4,
798
+ $5,
799
+ $6
800
+ );
801
+ }
802
+
803
+ union_type_extension:
804
+ EXTEND UNION name directives_list_opt EQUALS union_members {
805
+ $$ = MAKE_AST_NODE(UnionTypeExtension, 5,
806
+ rb_ary_entry($1, 1),
807
+ rb_ary_entry($1, 2),
808
+ rb_ary_entry($3, 3),
809
+ $6, // types
810
+ $4
811
+ );
812
+ }
813
+ | EXTEND UNION name directives_list {
814
+ $$ = MAKE_AST_NODE(UnionTypeExtension, 5,
815
+ rb_ary_entry($1, 1),
816
+ rb_ary_entry($1, 2),
817
+ rb_ary_entry($3, 3),
818
+ GraphQL_Language_Nodes_NONE, // types
819
+ $4
820
+ );
821
+ }
822
+
823
+ enum_type_extension:
824
+ EXTEND ENUM name directives_list_opt LCURLY enum_value_definitions RCURLY {
825
+ $$ = MAKE_AST_NODE(EnumTypeExtension, 5,
826
+ rb_ary_entry($1, 1),
827
+ rb_ary_entry($1, 2),
828
+ rb_ary_entry($3, 3),
829
+ $4,
830
+ $6
831
+ );
832
+ }
833
+ | EXTEND ENUM name directives_list {
834
+ $$ = MAKE_AST_NODE(EnumTypeExtension, 5,
835
+ rb_ary_entry($1, 1),
836
+ rb_ary_entry($1, 2),
837
+ rb_ary_entry($3, 3),
838
+ $4,
839
+ GraphQL_Language_Nodes_NONE
840
+ );
841
+ }
842
+
843
+ input_object_type_extension:
844
+ EXTEND INPUT name directives_list_opt LCURLY input_value_definition_list RCURLY {
845
+ $$ = MAKE_AST_NODE(InputObjectTypeExtension, 5,
846
+ rb_ary_entry($1, 1),
847
+ rb_ary_entry($1, 2),
848
+ rb_ary_entry($3, 3),
849
+ $4,
850
+ $6
851
+ );
852
+ }
853
+ | EXTEND INPUT name directives_list {
854
+ $$ = MAKE_AST_NODE(InputObjectTypeExtension, 5,
855
+ rb_ary_entry($1, 1),
856
+ rb_ary_entry($1, 2),
857
+ rb_ary_entry($3, 3),
858
+ $4,
859
+ GraphQL_Language_Nodes_NONE
860
+ );
861
+ }
862
+
863
+ %%
864
+
865
+ // Custom functions
866
+ int yylex (YYSTYPE *lvalp, VALUE parser, VALUE filename) {
867
+ int next_token_idx = FIX2INT(rb_ivar_get(parser, rb_intern("@next_token_index")));
868
+ VALUE tokens = rb_ivar_get(parser, rb_intern("@tokens"));
869
+ VALUE next_token = rb_ary_entry(tokens, next_token_idx);
870
+
871
+ if (!RB_TEST(next_token)) {
872
+ return YYEOF;
873
+ }
874
+ rb_ivar_set(parser, rb_intern("@next_token_index"), INT2FIX(next_token_idx + 1));
875
+ VALUE token_type_rb_int = rb_ary_entry(next_token, 5);
876
+ int next_token_type = FIX2INT(token_type_rb_int);
877
+
878
+ *lvalp = next_token;
879
+ return next_token_type;
880
+ }
881
+
882
+ void yyerror(VALUE parser, VALUE filename, const char *msg) {
883
+ VALUE mGraphQL = rb_const_get_at(rb_cObject, rb_intern("GraphQL"));
884
+ VALUE mCParser = rb_const_get_at(mGraphQL, rb_intern("CParser"));
885
+ VALUE rb_message = rb_str_new_cstr(msg);
886
+ VALUE exception = rb_funcall(
887
+ mCParser, rb_intern("prepare_parse_error"), 2,
888
+ rb_message,
889
+ parser
890
+ );
891
+ rb_exc_raise(exception);
892
+ }
893
+
894
+ #define INITIALIZE_NODE_CLASS_VARIABLE(node_class_name) GraphQL_Language_Nodes_##node_class_name = rb_const_get_at(mGraphQLLanguageNodes, rb_intern(#node_class_name));
895
+
896
+ void initialize_node_class_variables() {
897
+ VALUE mGraphQL = rb_const_get_at(rb_cObject, rb_intern("GraphQL"));
898
+ VALUE mGraphQLLanguage = rb_const_get_at(mGraphQL, rb_intern("Language"));
899
+ VALUE mGraphQLLanguageNodes = rb_const_get_at(mGraphQLLanguage, rb_intern("Nodes"));
900
+ GraphQL_Language_Nodes_NONE = rb_const_get_at(mGraphQLLanguageNodes, rb_intern("NONE"));
901
+ r_string_query = rb_str_new_cstr("query");
902
+ rb_global_variable(&r_string_query);
903
+ rb_str_freeze(r_string_query);
904
+
905
+ INITIALIZE_NODE_CLASS_VARIABLE(Argument)
906
+ INITIALIZE_NODE_CLASS_VARIABLE(Directive)
907
+ INITIALIZE_NODE_CLASS_VARIABLE(Document)
908
+ INITIALIZE_NODE_CLASS_VARIABLE(Enum)
909
+ INITIALIZE_NODE_CLASS_VARIABLE(Field)
910
+ INITIALIZE_NODE_CLASS_VARIABLE(FragmentDefinition)
911
+ INITIALIZE_NODE_CLASS_VARIABLE(FragmentSpread)
912
+ INITIALIZE_NODE_CLASS_VARIABLE(InlineFragment)
913
+ INITIALIZE_NODE_CLASS_VARIABLE(InputObject)
914
+ INITIALIZE_NODE_CLASS_VARIABLE(ListType)
915
+ INITIALIZE_NODE_CLASS_VARIABLE(NonNullType)
916
+ INITIALIZE_NODE_CLASS_VARIABLE(NullValue)
917
+ INITIALIZE_NODE_CLASS_VARIABLE(OperationDefinition)
918
+ INITIALIZE_NODE_CLASS_VARIABLE(TypeName)
919
+ INITIALIZE_NODE_CLASS_VARIABLE(VariableDefinition)
920
+ INITIALIZE_NODE_CLASS_VARIABLE(VariableIdentifier)
921
+
922
+ INITIALIZE_NODE_CLASS_VARIABLE(ScalarTypeDefinition)
923
+ INITIALIZE_NODE_CLASS_VARIABLE(ObjectTypeDefinition)
924
+ INITIALIZE_NODE_CLASS_VARIABLE(InterfaceTypeDefinition)
925
+ INITIALIZE_NODE_CLASS_VARIABLE(UnionTypeDefinition)
926
+ INITIALIZE_NODE_CLASS_VARIABLE(EnumTypeDefinition)
927
+ INITIALIZE_NODE_CLASS_VARIABLE(InputObjectTypeDefinition)
928
+ INITIALIZE_NODE_CLASS_VARIABLE(EnumValueDefinition)
929
+ INITIALIZE_NODE_CLASS_VARIABLE(DirectiveDefinition)
930
+ INITIALIZE_NODE_CLASS_VARIABLE(DirectiveLocation)
931
+ INITIALIZE_NODE_CLASS_VARIABLE(FieldDefinition)
932
+ INITIALIZE_NODE_CLASS_VARIABLE(InputValueDefinition)
933
+ INITIALIZE_NODE_CLASS_VARIABLE(SchemaDefinition)
934
+
935
+ INITIALIZE_NODE_CLASS_VARIABLE(ScalarTypeExtension)
936
+ INITIALIZE_NODE_CLASS_VARIABLE(ObjectTypeExtension)
937
+ INITIALIZE_NODE_CLASS_VARIABLE(InterfaceTypeExtension)
938
+ INITIALIZE_NODE_CLASS_VARIABLE(UnionTypeExtension)
939
+ INITIALIZE_NODE_CLASS_VARIABLE(EnumTypeExtension)
940
+ INITIALIZE_NODE_CLASS_VARIABLE(InputObjectTypeExtension)
941
+ INITIALIZE_NODE_CLASS_VARIABLE(SchemaExtension)
942
+ }