blob: 5bbbb8c9520afb26ac61e1df7a9f3b7dbac4489a [file] [log] [blame]
George Mountc09acd42015-01-07 16:34:06 -08001/*
2 * This grammar is a tweaked subset of that in Java.g4, which has a
3 * BSD license and is redistributed along with this.
4 */
5grammar BindingExpression;
6
7bindingSyntax
George Mountc09acd42015-01-07 16:34:06 -08008 : expression defaults?
9 ;
10
11defaults
12 : ',' 'default' '=' constantValue
13 ;
14constantValue
15 : literal
16 | ResourceReference
George Mountc09acd42015-01-07 16:34:06 -080017 | identifier
18 ;
19
20expression
21 : '(' expression ')' # Grouping
22// this isn't allowed yet.
23// | THIS # Primary
24 | literal # Primary
25 | identifier # Primary
26 | classExtraction # Primary
27 | ResourceReference # Resource
George Mountd0717692015-01-26 16:57:04 -080028// | typeArguments (explicitGenericInvocationSuffix | 'this' arguments) # GenericCall
George Mountc09acd42015-01-07 16:34:06 -080029 | expression '.' Identifier # DotOp
30// | expression '.' 'this' # ThisReference
George Mountd0717692015-01-26 16:57:04 -080031// | expression '.' explicitGenericInvocation # ExplicitGenericInvocationOp
George Mountc09acd42015-01-07 16:34:06 -080032 | expression '[' expression ']' # BracketOp
Yigit Boyard7af42b2015-01-09 14:23:33 -080033 | target=expression '.' methodName=Identifier '(' args=expressionList? ')' # MethodInvocation
George Mountc09acd42015-01-07 16:34:06 -080034 | '(' type ')' expression # CastOp
George Mountd0717692015-01-26 16:57:04 -080035 | op=('+'|'-') expression # UnaryOp
36 | op=('~'|'!') expression # UnaryOp
Yigit Boyar35e303e2015-01-09 10:43:24 -080037 | left=expression op=('*'|'/'|'%') right=expression # MathOp
38 | left=expression op=('+'|'-') right=expression # MathOp
39 | left=expression op=('<<' | '>>>' | '>>') right=expression # BitShiftOp
40 | left=expression op=('<=' | '>=' | '>' | '<') right=expression # ComparisonOp
George Mountc09acd42015-01-07 16:34:06 -080041 | expression 'instanceof' type # InstanceOfOp
Yigit Boyar35e303e2015-01-09 10:43:24 -080042 | left=expression op=('==' | '!=') right=expression # ComparisonOp
43 | left=expression op='&' right=expression # BinaryOp
44 | left=expression op='^' right=expression # BinaryOp
45 | left=expression op='|' right=expression # BinaryOp
46 | left=expression op='&&' right=expression # AndOrOp
47 | left=expression op='||' right=expression # AndOrOp
48 | left=expression op='?' iftrue=expression ':' iffalse=expression # TernaryOp
49 | left=expression op='??' right=expression # QuestionQuestionOp
George Mountc09acd42015-01-07 16:34:06 -080050 ;
51
52THIS
53 : 'this'
54 ;
55
56classExtraction
57 : type '.' 'class'
58 | 'void' '.' 'class'
59 ;
60
61expressionList
62 : expression (',' expression)*
63 ;
64
65literal
66 : javaLiteral
67 | stringLiteral
68 ;
69
70identifier
71 : Identifier
72 ;
73
74javaLiteral
75 : IntegerLiteral
76 | FloatingPointLiteral
77 | BooleanLiteral
78 | NullLiteral
79 | CharacterLiteral
80 ;
81
82stringLiteral
83 : SingleQuoteString
84 | DoubleQuoteString
85 ;
86
87explicitGenericInvocation
88 : typeArguments explicitGenericInvocationSuffix
89 ;
90
91typeArguments
92 : '<' type (',' type)* '>'
93 ;
94
95type
96 : classOrInterfaceType ('[' ']')*
97 | primitiveType ('[' ']')*
98 ;
99
100explicitGenericInvocationSuffix
101 : Identifier arguments
102 ;
103
104arguments
105 : '(' expressionList? ')'
106 ;
107
108classOrInterfaceType
109 : identifier typeArguments? ('.' Identifier typeArguments? )*
110 ;
111
112primitiveType
113 : 'boolean'
114 | 'char'
115 | 'byte'
116 | 'short'
117 | 'int'
118 | 'long'
119 | 'float'
120 | 'double'
121 ;
122
123// LEXER
124
125// §3.10.1 Integer Literals
126
127IntegerLiteral
128 : DecimalIntegerLiteral
129 | HexIntegerLiteral
130 | OctalIntegerLiteral
131 | BinaryIntegerLiteral
132 ;
133
134fragment
135DecimalIntegerLiteral
136 : DecimalNumeral IntegerTypeSuffix?
137 ;
138
139fragment
140HexIntegerLiteral
141 : HexNumeral IntegerTypeSuffix?
142 ;
143
144fragment
145OctalIntegerLiteral
146 : OctalNumeral IntegerTypeSuffix?
147 ;
148
149fragment
150BinaryIntegerLiteral
151 : BinaryNumeral IntegerTypeSuffix?
152 ;
153
154fragment
155IntegerTypeSuffix
156 : [lL]
157 ;
158
159fragment
160DecimalNumeral
161 : '0'
162 | NonZeroDigit (Digits? | Underscores Digits)
163 ;
164
165fragment
166Digits
167 : Digit (DigitOrUnderscore* Digit)?
168 ;
169
170fragment
171Digit
172 : '0'
173 | NonZeroDigit
174 ;
175
176fragment
177NonZeroDigit
178 : [1-9]
179 ;
180
181fragment
182DigitOrUnderscore
183 : Digit
184 | '_'
185 ;
186
187fragment
188Underscores
189 : '_'+
190 ;
191
192fragment
193HexNumeral
194 : '0' [xX] HexDigits
195 ;
196
197fragment
198HexDigits
199 : HexDigit (HexDigitOrUnderscore* HexDigit)?
200 ;
201
202fragment
203HexDigit
204 : [0-9a-fA-F]
205 ;
206
207fragment
208HexDigitOrUnderscore
209 : HexDigit
210 | '_'
211 ;
212
213fragment
214OctalNumeral
215 : '0' Underscores? OctalDigits
216 ;
217
218fragment
219OctalDigits
220 : OctalDigit (OctalDigitOrUnderscore* OctalDigit)?
221 ;
222
223fragment
224OctalDigit
225 : [0-7]
226 ;
227
228fragment
229OctalDigitOrUnderscore
230 : OctalDigit
231 | '_'
232 ;
233
234fragment
235BinaryNumeral
236 : '0' [bB] BinaryDigits
237 ;
238
239fragment
240BinaryDigits
241 : BinaryDigit (BinaryDigitOrUnderscore* BinaryDigit)?
242 ;
243
244fragment
245BinaryDigit
246 : [01]
247 ;
248
249fragment
250BinaryDigitOrUnderscore
251 : BinaryDigit
252 | '_'
253 ;
254
255// §3.10.2 Floating-Point Literals
256
257FloatingPointLiteral
258 : DecimalFloatingPointLiteral
259 | HexadecimalFloatingPointLiteral
260 ;
261
262fragment
263DecimalFloatingPointLiteral
264 : Digits '.' Digits? ExponentPart? FloatTypeSuffix?
265 | '.' Digits ExponentPart? FloatTypeSuffix?
266 | Digits ExponentPart FloatTypeSuffix?
267 | Digits FloatTypeSuffix
268 ;
269
270fragment
271ExponentPart
272 : ExponentIndicator SignedInteger
273 ;
274
275fragment
276ExponentIndicator
277 : [eE]
278 ;
279
280fragment
281SignedInteger
282 : Sign? Digits
283 ;
284
285fragment
286Sign
287 : [+-]
288 ;
289
290fragment
291FloatTypeSuffix
292 : [fFdD]
293 ;
294
295fragment
296HexadecimalFloatingPointLiteral
297 : HexSignificand BinaryExponent FloatTypeSuffix?
298 ;
299
300fragment
301HexSignificand
302 : HexNumeral '.'?
303 | '0' [xX] HexDigits? '.' HexDigits
304 ;
305
306fragment
307BinaryExponent
308 : BinaryExponentIndicator SignedInteger
309 ;
310
311fragment
312BinaryExponentIndicator
313 : [pP]
314 ;
315
316// §3.10.3 Boolean Literals
317
318BooleanLiteral
319 : 'true'
320 | 'false'
321 ;
322
323// §3.10.4 Character Literals
324
325CharacterLiteral
326 : '\'' SingleCharacter '\''
327 | '\'' EscapeSequence '\''
328 ;
329
330fragment
331SingleCharacter
332 : ~['\\]
333 ;
334// §3.10.5 String Literals
335SingleQuoteString
George Mount7920e172015-02-05 16:02:46 -0800336 : '`' SingleQuoteStringCharacter* '`'
George Mountc09acd42015-01-07 16:34:06 -0800337 ;
338
339DoubleQuoteString
340 : '"' StringCharacters? '"'
341 ;
342
343fragment
344StringCharacters
345 : StringCharacter+
346 ;
347fragment
348StringCharacter
349 : ~["\\]
350 | EscapeSequence
351 ;
352fragment
353SingleQuoteStringCharacter
354 : ~[`\\]
355 | EscapeSequence
356 ;
357
358// §3.10.6 Escape Sequences for Character and String Literals
359fragment
360EscapeSequence
361 : '\\' [btnfr"'`\\]
362 | OctalEscape
363 | UnicodeEscape
364 ;
365
366fragment
367OctalEscape
368 : '\\' OctalDigit
369 | '\\' OctalDigit OctalDigit
370 | '\\' ZeroToThree OctalDigit OctalDigit
371 ;
372
373fragment
374UnicodeEscape
375 : '\\' 'u' HexDigit HexDigit HexDigit HexDigit
376 ;
377
378fragment
379ZeroToThree
380 : [0-3]
381 ;
382
383// §3.10.7 The Null Literal
384
385NullLiteral
386 : 'null'
387 ;
388
389// §3.8 Identifiers (must appear after all keywords in the grammar)
390
391Identifier
392 : JavaLetter JavaLetterOrDigit*
393 ;
394
395fragment
396JavaLetter
397 : [a-zA-Z$_] // these are the "java letters" below 0xFF
398 | // covers all characters above 0xFF which are not a surrogate
399 ~[\u0000-\u00FF\uD800-\uDBFF]
400 {Character.isJavaIdentifierStart(_input.LA(-1))}?
401 | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
402 [\uD800-\uDBFF] [\uDC00-\uDFFF]
403 {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
404 ;
405
406fragment
407JavaLetterOrDigit
408 : [a-zA-Z0-9$_] // these are the "java letters or digits" below 0xFF
409 | // covers all characters above 0xFF which are not a surrogate
410 ~[\u0000-\u00FF\uD800-\uDBFF]
411 {Character.isJavaIdentifierPart(_input.LA(-1))}?
412 | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
413 [\uD800-\uDBFF] [\uDC00-\uDFFF]
414 {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
415 ;
416
417//
418// Whitespace and comments
419//
420
421WS : [ \t\r\n\u000C]+ -> skip
422 ;
423
424//
425// Resource references
426//
427
428ResourceReference
429 : '@' (PackageName ':')? ResourceType '/' ResourceName
430 ;
431
432fragment
433PackageName
434 : 'android'
435 | Identifier
436 ;
437
438fragment
439ResourceType
440 : 'anim'
441 | 'animator'
George Mountc09acd42015-01-07 16:34:06 -0800442 | 'bool'
443 | 'color'
George Mountc752a5f2015-01-21 16:24:43 -0800444 | 'colorStateList'
George Mountc09acd42015-01-07 16:34:06 -0800445 | 'dimen'
George Mountc752a5f2015-01-21 16:24:43 -0800446 | 'dimenOffset'
447 | 'dimenSize'
George Mountc09acd42015-01-07 16:34:06 -0800448 | 'drawable'
449 | 'fraction'
450 | 'id'
451 | 'integer'
George Mountc752a5f2015-01-21 16:24:43 -0800452 | 'intArray'
George Mountc09acd42015-01-07 16:34:06 -0800453 | 'interpolator'
454 | 'layout'
George Mountc09acd42015-01-07 16:34:06 -0800455 | 'plurals'
George Mountc752a5f2015-01-21 16:24:43 -0800456 | 'stateListAnimator'
George Mountc09acd42015-01-07 16:34:06 -0800457 | 'string'
George Mountc752a5f2015-01-21 16:24:43 -0800458 | 'stringArray'
George Mountc09acd42015-01-07 16:34:06 -0800459 | 'transition'
George Mountc752a5f2015-01-21 16:24:43 -0800460 | 'typedArray'
George Mountc09acd42015-01-07 16:34:06 -0800461 ;
462
463ResourceName
464 : ResourceLetter ResourceLetterOrDigit*
465 ;
466
467fragment
468ResourceLetter
469 : [a-z$_] // these are the "lower-case java letters" below 0xFF
470 | // covers all characters above 0xFF which are not a surrogate
471 ~[\u0000-\u00FF\uD800-\uDBFF]
472 {Character.isJavaIdentifierStart(_input.LA(-1)) && !Character.isUpperCase(_input.LA(-1))}?
473 | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
474 [\uD800-\uDBFF] [\uDC00-\uDFFF]
475 {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))) && !Character.isUpperCase(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
476 ;
477
478fragment
479ResourceLetterOrDigit
480 : [a-z0-9$_] // these are the "java letters or digits" below 0xFF
481 | // covers all characters above 0xFF which are not a surrogate
482 ~[\u0000-\u00FF\uD800-\uDBFF]
483 {Character.isJavaIdentifierPart(_input.LA(-1)) && !Character.isUpperCase(_input.LA(-1))}?
484 | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
485 [\uD800-\uDBFF] [\uDC00-\uDFFF]
486 {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1))) && !Character.isUpperCase(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
487 ;