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