a3d9dbd1dcefd91d60f4ef0af60e1e55d0d68349
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.parser / src / main / antlr3 / org / eclipse / linuxtools / ctf / parser / CTFParser.g
1 parser grammar CTFParser;
2
3 options {
4 language = Java;
5 output = AST;
6 ASTLabelType = CommonTree;
7 tokenVocab = CTFLexer;
8 }
9
10 tokens {
11 ROOT;
12
13 EVENT;
14 STREAM;
15 TRACE;
16 ENV;
17 CLOCK;
18 CALLSITE;
19
20 DECLARATION;
21 SV_DECLARATION;
22 TYPE_SPECIFIER_LIST;
23 TYPE_DECLARATOR_LIST;
24 TYPE_DECLARATOR;
25
26 STRUCT;
27 STRUCT_NAME;
28 STRUCT_BODY;
29 ALIGN;
30
31 CTF_EXPRESSION_TYPE;
32 CTF_EXPRESSION_VAL;
33 CTF_LEFT;
34 CTF_RIGHT;
35
36 UNARY_EXPRESSION_STRING;
37 UNARY_EXPRESSION_STRING_QUOTES;
38 UNARY_EXPRESSION_DEC;
39 UNARY_EXPRESSION_HEX;
40 UNARY_EXPRESSION_OCT;
41 LENGTH;
42
43 TYPEDEF;
44
45 TYPEALIAS;
46 TYPEALIAS_TARGET;
47 TYPEALIAS_ALIAS;
48
49 INTEGER;
50 STRING;
51 FLOATING_POINT;
52
53 ENUM;
54 ENUM_CONTAINER_TYPE;
55 ENUM_ENUMERATOR;
56 ENUM_NAME;
57 ENUM_VALUE;
58 ENUM_VALUE_RANGE;
59 ENUM_BODY;
60
61 VARIANT;
62 VARIANT_NAME;
63 VARIANT_TAG;
64 VARIANT_BODY;
65
66 DECLARATOR;
67 LENGTH;
68 }
69
70 /*
71 * Scope for the tracking of types.
72 * For now we just track the names (it's a simple Set), but
73 * later we will have to track the info about the target type.
74 */
75 scope Symbols {
76 Set<String> types;
77 }
78
79 @header {
80 package org.eclipse.linuxtools.ctf.parser;
81 import java.util.Set;
82 import java.util.HashSet;
83 }
84
85 @members {
86 public CTFParser(TokenStream input, boolean verbose) {
87 this(input);
88 this.verbose = verbose;
89 }
90
91 /**
92 * This method is overriden to disable automatic error recovery.
93 * On a mismatched token, it simply re-throw an exception.
94 */
95 @Override
96 protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException {
97 throw new MismatchedTokenException(ttype, input);
98 }
99
100 /**
101 * Checks if a given name has been defined has a type.
102 * From: http://www.antlr.org/grammar/1153358328744/C.g
103 *
104 * @param name The name to check.
105 * @return True if is is a type, false otherwise.
106 */
107 boolean isTypeName(String name) {
108 for (int i = Symbols_stack.size() - 1; i >= 0; i--) {
109 Symbols_scope scope = (Symbols_scope) Symbols_stack.get(i);
110 if (scope.types.contains(name)) {
111 return true;
112 }
113 }
114 return false;
115 }
116
117 void addTypeName(String name) {
118 $Symbols::types.add(name);
119 if (verbose) {
120 debug_print("New type: " + name);
121 }
122 }
123
124 boolean _inTypedef = false;
125
126 void typedefOn() {
127 debug_print("typedefOn");
128 _inTypedef = true;
129 }
130
131 void typedefOff() {
132 debug_print("typedefOff");
133 _inTypedef = false;
134 }
135
136 boolean inTypedef() {
137 return _inTypedef;
138 }
139
140 boolean _inTypealiasAlias = false;
141
142 void typealiasAliasOn() {
143 debug_print("typealiasAliasOn");
144 _inTypealiasAlias = true;
145 }
146
147 void typealiasAliasOff() {
148 debug_print("typealiasAliasOff");
149 _inTypealiasAlias = false;
150 }
151
152 boolean inTypealiasAlias() {
153 return _inTypealiasAlias;
154 }
155
156 void debug_print(String str) {
157 if (verbose) {
158 System.out.println(str);
159 }
160 }
161
162 /* Prints rule entry and exit while parsing */
163 boolean verbose = false;
164 }
165
166 /*
167 * Override the catch clause to disable automatic error recovery.
168 * By default, the catch block of every rule simple rethrows the error.
169 */
170 @rulecatch {
171 catch (RecognitionException e) {
172 throw e;
173 }
174 }
175
176 /* The top-level rule. */
177 parse
178 scope Symbols;
179 @init {
180 $Symbols::types = new HashSet<String>();
181 }
182 : declaration+ EOF -> ^(ROOT declaration+)
183 ;
184
185 numberLiteral
186 : SIGN*
187 ( HEX_LITERAL -> ^(UNARY_EXPRESSION_HEX HEX_LITERAL SIGN*)
188 | DECIMAL_LITERAL -> ^(UNARY_EXPRESSION_DEC DECIMAL_LITERAL SIGN*)
189 | OCTAL_LITERAL -> ^(UNARY_EXPRESSION_OCT OCTAL_LITERAL SIGN*)
190 )
191 ;
192
193 primaryExpression
194 : (IDENTIFIER) => IDENTIFIER
195 -> ^(UNARY_EXPRESSION_STRING IDENTIFIER)
196 | (ctfKeyword) => ctfKeyword -> ^(UNARY_EXPRESSION_STRING ctfKeyword)
197 | (STRING_LITERAL) => STRING_LITERAL
198 -> ^(UNARY_EXPRESSION_STRING_QUOTES STRING_LITERAL)
199 /*| (LPAREN unaryExpression RPAREN)*/ // Not supported yet
200 | numberLiteral
201 | enumConstant
202 | CHARACTER_LITERAL
203 ;
204
205 postfixExpressionSuffix
206 : OPENBRAC unaryExpression CLOSEBRAC!
207 | (ref=DOT | ref=ARROW) IDENTIFIER
208 -> ^($ref ^(UNARY_EXPRESSION_STRING IDENTIFIER))
209 ;
210
211 postfixExpression
212 : primaryExpression postfixExpressionSuffix*
213 | ctfSpecifierHead postfixExpressionSuffix+ // added for ctf-v1.8
214 ;
215
216 unaryExpression
217 : postfixExpression
218 /* | ((SIGN postfixExpression[true]) | postfixExpression[false]) */
219 ;
220
221 enumConstant
222 : STRING_LITERAL -> ^(UNARY_EXPRESSION_STRING_QUOTES STRING_LITERAL)
223 | IDENTIFIER -> ^(UNARY_EXPRESSION_STRING IDENTIFIER)
224 | ctfKeyword -> ^(UNARY_EXPRESSION_STRING ctfKeyword)
225 ;
226
227 // 2.2
228
229 declaration
230 @after {
231 if (inTypedef()) {
232 typedefOff();
233 }
234 }
235 : declarationSpecifiers declaratorList? TERM
236 // When the declaration is completely parsed and was a typedef,
237 // we add the declarators to the symbol table.
238 -> {inTypedef()}?
239 ^(DECLARATION ^(TYPEDEF declaratorList declarationSpecifiers))
240 -> ^(DECLARATION declarationSpecifiers declaratorList?)
241 | ctfSpecifier TERM!
242 ;
243
244 declarationSpecifiers
245 : (
246 // We don't want to keep the typedef keyword in the specifier list.
247 // Instead, we keep track that we encountered a typedef in the declaration.
248 storageClassSpecifier
249 | typeQualifier
250 | typeSpecifier
251 )+ -> ^(TYPE_SPECIFIER_LIST typeQualifier* typeSpecifier*)
252 ;
253
254 declaratorList
255 : declarator (SEPARATOR declarator)*
256 -> ^(TYPE_DECLARATOR_LIST declarator+)
257 ;
258
259 abstractDeclaratorList
260 : abstractDeclarator (SEPARATOR abstractDeclarator)*
261 -> ^(TYPE_DECLARATOR_LIST abstractDeclarator+)
262 ;
263
264 storageClassSpecifier
265 : TYPEDEFTOK { typedefOn(); }
266 ;
267
268 typeSpecifier
269 : FLOATTOK
270 | INTTOK
271 | LONGTOK
272 | SHORTTOK
273 | SIGNEDTOK
274 | UNSIGNEDTOK
275 | CHARTOK
276 | DOUBLETOK
277 | VOIDTOK
278 | BOOLTOK
279 | COMPLEXTOK
280 | IMAGINARYTOK
281 | structSpecifier
282 | variantSpecifier
283 | enumSpecifier
284 | ctfTypeSpecifier
285 | { inTypealiasAlias() || isTypeName(input.LT(1).getText()) }? => typedefName
286 ;
287
288 typeQualifier
289 : CONSTTOK
290 ;
291
292 alignAttribute
293 : ALIGNTOK LPAREN unaryExpression RPAREN -> ^(ALIGN unaryExpression)
294 ;
295
296 // you can have an empty struct but not an empty variant
297 structBody
298 scope Symbols;
299 @init {
300 $Symbols::types = new HashSet<String>();
301 }
302 : LCURL structOrVariantDeclarationList? RCURL
303 -> ^(STRUCT_BODY structOrVariantDeclarationList?)
304 ;
305
306 structSpecifier
307 : STRUCTTOK
308 (
309 // We have an IDENTIFIER after 'struct'
310 (
311 structName
312 (
313 alignAttribute
314 |
315 (
316 structBody
317 ( /* structBody can return an empty tree, so we need those ? */
318 alignAttribute
319 |
320 /* empty */
321 )
322 )
323 |
324 /* empty */
325 )
326 )
327 |
328 // We have a body after 'struct'
329 (
330 structBody
331 (
332 alignAttribute
333 |
334 /* empty */
335 )
336 )
337 ) -> ^(STRUCT structName? structBody? alignAttribute?)
338 ;
339
340 structName
341 : IDENTIFIER -> ^(STRUCT_NAME IDENTIFIER)
342 ;
343
344 structOrVariantDeclarationList
345 : structOrVariantDeclaration+
346 ;
347
348 structOrVariantDeclaration
349 :
350 (
351 (
352 declarationSpecifiers
353 (
354 /* If we met a "typedef" */
355 {inTypedef()}? => declaratorList {typedefOff();}
356 -> ^(TYPEDEF declaratorList declarationSpecifiers)
357 | structOrVariantDeclaratorList
358 -> ^(SV_DECLARATION declarationSpecifiers structOrVariantDeclaratorList)
359 )
360 )
361 |
362 // Lines 3 and 4
363 typealiasDecl -> typealiasDecl
364 )
365 TERM
366 ;
367
368 specifierQualifierList
369 : (typeQualifier | typeSpecifier)+
370 -> ^(TYPE_SPECIFIER_LIST typeQualifier* typeSpecifier*)
371 ;
372
373 structOrVariantDeclaratorList
374 : structOrVariantDeclarator (SEPARATOR structOrVariantDeclarator)*
375 -> ^(TYPE_DECLARATOR_LIST structOrVariantDeclarator+)
376 ;
377
378 structOrVariantDeclarator
379 :
380 /* Bitfields not supported yet */
381 (declarator (COLON numberLiteral)?) -> declarator
382 /*| (COLON numberLiteral)*/
383 ;
384
385 variantSpecifier
386 : VARIANTTOK
387 (
388 (
389 variantName
390 (
391 (
392 variantTag
393 (
394 variantBody
395 |
396 /* empty */
397 )
398 )
399 |
400 variantBody
401 )
402 )
403 | (variantTag variantBody)
404 | variantBody
405 ) -> ^(VARIANT variantName? variantTag? variantBody?)
406 ;
407
408 variantName
409 : IDENTIFIER -> ^(VARIANT_NAME IDENTIFIER)
410 ;
411
412 variantBody
413 scope Symbols;
414 @init {
415 $Symbols::types = new HashSet<String>();
416 }
417 : LCURL structOrVariantDeclarationList RCURL
418 -> ^(VARIANT_BODY structOrVariantDeclarationList)
419 ;
420
421 variantTag
422 : LT IDENTIFIER GT -> ^(VARIANT_TAG IDENTIFIER)
423 ;
424
425 enumSpecifier
426 : ENUMTOK
427 (
428 // Lines 1 to 5, when we have "ENUMTOK IDENTIFIER".
429 (
430 enumName
431 (
432 enumContainerType enumBody
433 |
434 enumBody
435 |
436 // no enumDeclarator or enumBodym
437 )
438 )
439 |
440 // Lines 1, 2, 4, 5, when we have no IDENTIFIER.
441 (
442 enumContainerType enumBody
443 |
444 enumBody
445 )
446 ) -> ^(ENUM enumName? enumContainerType? enumBody?)
447 ;
448
449 enumName
450 : IDENTIFIER -> ^(ENUM_NAME IDENTIFIER)
451 ;
452
453 enumBody
454 : LCURL enumeratorList SEPARATOR? RCURL -> ^(ENUM_BODY enumeratorList)
455 ;
456
457 enumContainerType
458 : COLON declarationSpecifiers -> ^(ENUM_CONTAINER_TYPE declarationSpecifiers)
459 ;
460
461 enumeratorList
462 : enumerator (SEPARATOR enumerator)* -> (^(ENUM_ENUMERATOR enumerator))+
463 ;
464
465 enumerator
466 : enumConstant enumeratorValue?
467 ;
468
469 enumeratorValue
470 : ASSIGNMENT e1=unaryExpression
471 ( /* empty */
472 -> ^(ENUM_VALUE $e1)
473 | ELIPSES e2=unaryExpression
474 -> ^(ENUM_VALUE_RANGE $e1 $e2)
475 )
476 ;
477
478 declarator
479 : pointer* directDeclarator
480 -> ^(TYPE_DECLARATOR pointer* directDeclarator)
481 ;
482
483 directDeclarator
484 : (
485 IDENTIFIER
486 { if (inTypedef()) addTypeName($IDENTIFIER.text); }
487 { debug_print($IDENTIFIER.text); }
488 /*| LPAREN declarator RPAREN*/ /* Not supported yet */
489 )
490 directDeclaratorSuffix*
491 ;
492
493 directDeclaratorSuffix
494 : OPENBRAC directDeclaratorLength CLOSEBRAC
495 -> ^(LENGTH directDeclaratorLength)
496 ;
497
498 directDeclaratorLength
499 : unaryExpression
500 ;
501
502 abstractDeclarator
503 : pointer+ directAbstractDeclarator?
504 -> ^(TYPE_DECLARATOR pointer+ directAbstractDeclarator?)
505 | directAbstractDeclarator
506 -> ^(TYPE_DECLARATOR directAbstractDeclarator)
507 ;
508
509 /**
510 * In the CTF grammar, direct-abstract-declarator can be empty (because of
511 * identifier-opt). We take care of that by appending a '?' to each use of
512 * "abstractDeclaratorList".
513 */
514 directAbstractDeclarator
515 : (
516 IDENTIFIER
517 | (LPAREN abstractDeclarator RPAREN)
518 ) (
519 OPENBRAC unaryExpression? CLOSEBRAC
520 )?
521 ;
522
523 pointer
524 : POINTER typeQualifierList? -> ^(POINTER typeQualifierList?)
525 ;
526
527 typeQualifierList
528 : typeQualifier+
529 ;
530
531 typedefName
532 : {inTypealiasAlias() || isTypeName(input.LT(1).getText())}? IDENTIFIER { if ((inTypedef() || inTypealiasAlias()) && !isTypeName($IDENTIFIER.text)) { addTypeName($IDENTIFIER.text); } }
533 ;
534
535 /**
536 * What goes in the target part of a typealias.
537 *
538 * For example, the integer part in:
539 * typealias integer {...} := my_new_integer;
540 */
541 typealiasTarget
542 : declarationSpecifiers abstractDeclaratorList?
543 ;
544
545 /**
546 * What goes in the alias part of a typealias.
547 *
548 * For example, the my_new_integer part in:
549 * typealias integer {...} := my_new_integer;
550 */
551 typealiasAlias
552 @init {
553 typealiasAliasOn();
554 }
555 @after {
556 typealiasAliasOff();
557 }
558 : abstractDeclaratorList
559 | declarationSpecifiers abstractDeclaratorList?
560 ;
561
562 typealiasDecl
563 : TYPEALIASTOK typealiasTarget TYPE_ASSIGNMENT typealiasAlias
564 -> ^(TYPEALIAS
565 ^(TYPEALIAS_TARGET typealiasTarget)
566 ^(TYPEALIAS_ALIAS typealiasAlias))
567 ;
568
569 // 2.3 CTF stuff
570
571 // TODO: Ajouter ceux qui manquent
572 ctfKeyword
573 : ALIGNTOK
574 | EVENTTOK
575 | SIGNEDTOK
576 | STRINGTOK
577 ;
578
579 ctfSpecifier
580 // event {...}, stream {...}, trace {...}
581 : ctfSpecifierHead ctfBody -> ^(ctfSpecifierHead ctfBody)
582 // typealias
583 | typealiasDecl -> ^(DECLARATION typealiasDecl)
584 ;
585
586 ctfSpecifierHead
587 : EVENTTOK -> EVENT
588 | STREAMTOK -> STREAM
589 | TRACETOK -> TRACE
590 | ENVTOK -> ENV
591 | CLOCKTOK -> CLOCK
592 | CALLSITETOK -> CALLSITE
593 ;
594
595 ctfTypeSpecifier
596 /* ctfBody can return an empty tree if the body is empty */
597 : FLOATINGPOINTTOK ctfBody -> ^(FLOATING_POINT ctfBody?)
598 | INTEGERTOK ctfBody -> ^(INTEGER ctfBody?)
599 | STRINGTOK ctfBody? -> ^(STRING ctfBody?)
600 ;
601
602 ctfBody
603 scope Symbols;
604 @init {
605 $Symbols::types = new HashSet<String>();
606 }
607 : LCURL ctfAssignmentExpressionList? RCURL -> ctfAssignmentExpressionList?
608 ;
609
610 ctfAssignmentExpressionList
611 : (ctfAssignmentExpression TERM!)+
612 ;
613
614 ctfAssignmentExpression
615 @after {
616 if (inTypedef()) {
617 typedefOff();
618 }
619 }
620 : left=unaryExpression
621 ( assignment=ASSIGNMENT right1=unaryExpression
622 -> ^(CTF_EXPRESSION_VAL
623 ^(CTF_LEFT $left)
624 ^(CTF_RIGHT $right1))
625 | type_assignment=TYPE_ASSIGNMENT right2=typeSpecifier
626 -> ^(CTF_EXPRESSION_TYPE
627 ^(CTF_LEFT $left)
628 ^(CTF_RIGHT ^(TYPE_SPECIFIER_LIST $right2)))
629 )
630 | (declarationSpecifiers {inTypedef()}? declaratorList)
631 -> ^(TYPEDEF declaratorList declarationSpecifiers)
632 | typealiasDecl
633 ;
This page took 0.054202 seconds and 4 git commands to generate.