1
1
/*
2
2
The MIT License (MIT)
3
-
3
+
4
4
Copyright (c) 2015 Joseph T. McBride
5
-
5
+
6
6
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
7
7
associated documentation files (the "Software"), to deal in the Software without restriction,
8
8
including without limitation the rights to use, copy, modify, merge, publish, distribute,
9
9
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
10
10
furnished to do so, subject to the following conditions:
11
-
11
+
12
12
The above copyright notice and this permission notice shall be included in all copies or
13
13
substantial portions of the Software.
14
-
14
+
15
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
16
16
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
18
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
19
19
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
-
20
+
21
21
GraphQL grammar derived from:
22
-
22
+
23
23
GraphQL Draft Specification - July 2015
24
-
25
- http://facebook.github.io/graphql/ https://github.com/facebook/graphql
26
-
24
+
25
+ http://facebook.github.io/graphql/ https://github.com/facebook/graphql
26
+
27
27
AB:10-sep19: replaced type with type_ to resolve conflict for golang generator
28
-
28
+
29
29
AB: 13-oct-19: added type system as per June 2018 specs
30
30
AB: 26-oct-19: added ID type
31
31
AB: 30-Oct-19: description, boolean, schema & Block string fix.
34
34
*/
35
35
grammar GraphQL;
36
36
37
- document : description* definition+;
37
+ document : definition+;
38
38
39
39
definition :
40
40
execDefinition
@@ -50,12 +50,8 @@ typeSystemDefinition:
50
50
51
51
// https://graphql.github.io/graphql-spec/June2018/#sec-Schema
52
52
schemaDefinition :
53
- ' schema' directives? rootOperationTypeDefinitionList ;
53
+ ' schema' directives? ' { ' rootOperationTypeDefinition+ ' } ' ;
54
54
55
- rootOperationTypeDefinitionList :
56
- ' {' rootOperationTypeDefinition (
57
- ' ,' ? rootOperationTypeDefinition
58
- )* ' }' ;
59
55
rootOperationTypeDefinition : operationType ' :' namedType;
60
56
namedType : NAME ;
61
57
@@ -68,38 +64,39 @@ typeDefinition:
68
64
| enumTypeDefinition
69
65
| inputObjectTypeDefinition;
70
66
71
- scalarTypeDefinition : description? ' scalar' NAME directives;
67
+ scalarTypeDefinition : description? ' scalar' NAME directives? ;
72
68
description : String_;
73
69
74
70
// https://graphql.github.io/graphql-spec/June2018/#sec-Objects
75
- objectTypeDefinition
76
- : description? ' type' NAME
77
- implementsInterfaces ?
78
- directives ?
79
- fieldsDefinitions ?;
80
-
81
- implementsInterfaces : ' implements' ' &' ? type_ |
82
- implementsInterfaces ' &' type_;
71
+ objectTypeDefinition : description?
72
+ ' type' NAME
73
+ implementsInterfaces?
74
+ directives?
75
+ fieldsDefinition?;
76
+
77
+ implementsInterfaces : ' implements' ' &' ? namedType
78
+ | implementsInterfaces ' &' namedType
79
+ ;
83
80
84
81
85
- fieldsDefinitions : ' {' fieldsDefinition+ ' }' ;
86
- fieldsDefinition : description? NAME argumentsDefinition? ' :' type_ directives? ;
87
- argumentsDefinition : ' (' inputValueDefinition ( ' , ' inputValueDefinition)* ' )' ;
82
+ fieldsDefinition : ' {' fieldDefinition+ ' }' ;
83
+ fieldDefinition : description? NAME argumentsDefinition? ' :' type_ directives? ;
84
+ argumentsDefinition : ' (' inputValueDefinition+ ' )' ;
88
85
inputValueDefinition : description? NAME ' :' type_ defaultValue? directives?;
89
86
90
87
// https://graphql.github.io/graphql-spec/June2018/#sec-Interfaces
91
88
interfaceTypeDefinition
92
- : description? ' interface' NAME directives? fieldsDefinitions ?;
89
+ : description? ' interface' NAME directives? fieldsDefinition ?;
93
90
94
91
// https://graphql.github.io/graphql-spec/June2018/#sec-Unions
95
92
unionTypeDefinition : description? ' union' NAME directives? unionMemberTypes?;
96
- unionMemberTypes : ' =' type_ (' |' type_)* ;
93
+ unionMemberTypes : ' =' ' | ' ? type_ (' |' type_)* ;
97
94
98
95
unionTypeExtension : ' extend' unionTypeDefinition;
99
96
100
- enumTypeDefinition : description? ' enum' NAME directives? enumValuesDefinitions?;
101
- enumValuesDefinitions : ' {' ( description? enumElementValue directives?)+ ' }' ;
102
- enumElementValue : NAME ; // not (nullValue | booleanValue)
97
+ enumTypeDefinition : description? ' enum' NAME directives? enumValuesDefinition?;
98
+ enumValuesDefinition : ' {' ( description? enumValue directives?)+ ' }' ;
99
+ enumValue : NAME ; // { not (nullValue | booleanValue) };
103
100
104
101
enumTypeExtension : ' extend' enumTypeDefinition;
105
102
@@ -112,7 +109,7 @@ directiveDefinition: description? 'directive' '@' NAME argumentsDefinition? 'on'
112
109
directiveLocations : directiveLocation (' |' directiveLocations)*;
113
110
directiveLocation : executableDirectiveLocation | typeSystemDirectiveLocation;
114
111
115
- executableDirectiveLocation :
112
+ executableDirectiveLocation :
116
113
' QUERY' |
117
114
' MUTATION' |
118
115
' SUBSCRIPTION' |
@@ -140,29 +137,29 @@ typeSystemExtension: schemaExtension | typeExtension;
140
137
schemaExtension : ' extend' schemaDefinition ;
141
138
typeExtension : ' extend' typeDefinition;
142
139
143
- // original code: execution definitions
140
+ // original code: execution definitions
144
141
// GraphQL Draft Specification - July 2015
145
142
execDefinition : operationDefinition | fragmentDefinition;
146
143
147
144
operationDefinition :
148
145
selectionSet
149
- | operationType NAME variableDefinitions? directives? selectionSet;
146
+ | operationType NAME ? variableDefinitions? directives? selectionSet;
150
147
151
- selectionSet : ' {' selection ( ' , ' ? selection)* ' }' ;
148
+ selectionSet : ' {' selection+ ' }' ;
152
149
153
150
operationType : ' query' | ' mutation' | ' subscription' ;
154
151
155
152
selection : field | fragmentSpread | inlineFragment;
156
153
157
- field : fieldName arguments? directives? selectionSet?;
154
+ field : alias? fieldName arguments? directives? selectionSet?;
158
155
159
- fieldName : alias | NAME ;
156
+ fieldName : NAME ;
160
157
161
- alias : NAME ' :' NAME ;
158
+ alias : NAME ' :' ;
162
159
163
- arguments : ' (' argument ( ' , ' argument)* ' )' ;
160
+ arguments : ' (' argument+ ' )' ;
164
161
165
- argument : NAME ' :' valueOrVariable ;
162
+ argument : NAME ' :' value ;
166
163
167
164
fragmentSpread : ' ...' fragmentName directives?;
168
165
@@ -177,47 +174,51 @@ fragmentName: NAME;
177
174
directives : directive+;
178
175
179
176
directive :
180
- ' @' NAME ' :' valueOrVariable
181
- | ' @' NAME
182
- | ' @' NAME ' (' argument ' )' ;
177
+ ' @' NAME arguments?;
183
178
184
179
typeCondition : typeName;
185
180
186
- variableDefinitions :
187
- ' (' variableDefinition (' ,' variableDefinition)* ' )' ;
181
+ variableDefinitions : ' (' variableDefinition+ ' )' ;
188
182
189
183
variableDefinition : variable ' :' type_ defaultValue?;
190
184
191
185
variable : ' $' NAME ;
192
186
193
187
defaultValue : ' =' value;
194
188
195
- valueOrVariable : value | variable;
196
-
197
189
value :
198
- String_ # stringValue
199
- | NAME # enumValue
200
- | NUMBER # numberValue
190
+ variable # variableValue
191
+ | NUMBER # numberValue
192
+ | String_ # stringValue
201
193
| BooleanLiteral # booleanValue
202
- | array # arrayValue
203
- | ID # idValue // The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache. The ID type is serialized in the same way as a String; however, defining it as an ID signifies that it is not intended to be human‐readable.
204
- | ' null' # nullValue
194
+ | ' null' # nullValue
195
+ | enumValue # constValue
196
+ | array # arrayValue
197
+ | object # objectValue
205
198
;
206
199
200
+ object : ' {' ' }'
201
+ | ' {' objectField ' }'
202
+ ;
203
+
204
+ objectField : NAME ' :' value;
205
+
207
206
BooleanLiteral
208
207
: ' true'
209
208
| ' false'
210
209
;
211
210
212
- type_ : typeName nonNullType ? | listType nonNullType ?;
211
+ type_ : typeName nonNull ? | listType nonNull ?;
213
212
214
213
typeName : NAME ;
215
214
216
215
listType : ' [' type_ ' ]' ;
217
216
218
- nonNullType : ' !' ;
217
+ nonNull : ' !' ;
219
218
220
- array : ' [' value ( ' ,' value)* ' ]' | ' [' ' ]' ;
219
+ array : ' [' value+ ' ]'
220
+ | ' [' ' ]'
221
+ ;
221
222
222
223
NAME : [_A -Za-z] [_0 -9A-Za-z]*;
223
224
@@ -231,14 +232,24 @@ BLOCK_STRING
231
232
232
233
ID: STRING;
233
234
234
-
235
235
fragment ESC: ' \\' ( ["\\ /bfnrt] | UNICODE);
236
236
237
237
fragment UNICODE: ' u' HEX HEX HEX HEX;
238
238
239
239
fragment HEX: [0-9a-fA-F];
240
240
241
241
NUMBER: ' -' ? INT ' .' [0-9]+ EXP? | ' -' ? INT EXP | ' -' ? INT;
242
+ PUNCTUATOR: ' !'
243
+ | ' $'
244
+ | ' (' | ' )'
245
+ | ' ...'
246
+ | ' :'
247
+ | ' ='
248
+ | ' @'
249
+ | ' [' | ' ]'
250
+ | ' {' | ' } '
251
+ | ' |'
252
+ ;
242
253
243
254
fragment INT: ' 0' | [1-9] [0-9]*;
244
255
@@ -249,8 +260,18 @@ fragment EXP: [Ee] [+\-]? INT;
249
260
// \- since - means "range" inside [...]
250
261
251
262
WS: [ \t\n\r ]+ -> skip;
252
-
263
+ COMMA: ' , ' -> skip;
253
264
LineComment
254
265
: ' #' ~[\r\n ]*
255
266
-> skip
256
267
;
268
+
269
+ UNICODE_BOM: (UTF8_BOM
270
+ | UTF16_BOM
271
+ | UTF32_BOM
272
+ ) -> skip
273
+ ;
274
+
275
+ UTF8_BOM: ' \uEFBBBF' ;
276
+ UTF16_BOM: ' \uFEFF' ;
277
+ UTF32_BOM: ' \u0000FEFF' ;
0 commit comments