1 parser grammar CTFParser;
6 ASTLabelType = CommonTree;
36 UNARY_EXPRESSION_STRING;
37 UNARY_EXPRESSION_STRING_QUOTES;
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.
80 package org.eclipse.linuxtools.ctf.parser;
82 import java.util.HashSet;
86 public CTFParser(TokenStream input, boolean verbose) {
88 this.verbose = verbose;
91 /* To disable automatic error recovery. When we have a mismatched token, simply throw an exception. */
93 protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException {
94 throw new MismatchedTokenException(ttype, input);
98 * Checks if a given name has been defined has a type.
99 * From: http://www.antlr.org/grammar/1153358328744/C.g
101 * @param name The name to check.
102 * @return True if is is a type, false otherwise.
104 boolean isTypeName(String name) {
105 for (int i = Symbols_stack.size() - 1; i >= 0; i--) {
106 Symbols_scope scope = (Symbols_scope) Symbols_stack.get(i);
107 if (scope.types.contains(name)) {
114 void addTypeName(String name) {
115 $Symbols::types.add(name);
117 debug_print("New type: " + name);
121 boolean _inTypedef = false;
124 debug_print("typedefOn");
129 debug_print("typedefOff");
133 boolean inTypedef() {
137 boolean _inTypealiasAlias = false;
139 void typealiasAliasOn() {
140 debug_print("typealiasAliasOn");
141 _inTypealiasAlias = true;
144 void typealiasAliasOff() {
145 debug_print("typealiasAliasOff");
146 _inTypealiasAlias = false;
149 boolean inTypealiasAlias() {
150 return _inTypealiasAlias;
153 void print_tabs(int n) {
154 for (int i = 0; i < n; i++) {
155 System.out.print(" ");
159 void enter(String name) {
161 if (state.backtracking == 0) {
163 debug_print("+ " + name);
169 void exit(String name) {
173 debug_print("- " + name);
177 void debug_print(String str) {
179 System.out.println(str);
185 /* Prints rule entry and exit while parsing */
186 boolean verbose = false;
189 /* To disable automatic error recovery. By default, the catch block of every rule simple rethrows the error. */
191 catch (RecognitionException e) {
196 /* The top-level rule. */
201 debug_print("Scope push " + Symbols_stack.size());
202 $Symbols::types = new HashSet<String>();
205 debug_print("Scope pop " + Symbols_stack.size());
208 debug_print("Final depth, should be 0: " + depth);
210 : declaration+ EOF -> ^(ROOT declaration+)
215 enter("numberLiteral");
218 debug_print($numberLiteral.text);
219 exit("numberLiteral");
221 : SIGN* (HEX_LITERAL -> ^(UNARY_EXPRESSION_HEX HEX_LITERAL SIGN*)
222 | DECIMAL_LITERAL -> ^(UNARY_EXPRESSION_DEC DECIMAL_LITERAL SIGN*)
223 | OCTAL_LITERAL -> ^(UNARY_EXPRESSION_OCT OCTAL_LITERAL SIGN*))
240 enter("primaryExpression");
243 exit("primaryExpression");
245 : (IDENTIFIER) => IDENTIFIER
246 { debug_print("IDENTIFIER: " + $IDENTIFIER.text); }
247 -> ^(UNARY_EXPRESSION_STRING IDENTIFIER)
248 | (ctfKeyword) => ctfKeyword -> ^(UNARY_EXPRESSION_STRING ctfKeyword)
249 | (STRING_LITERAL) => STRING_LITERAL
250 { debug_print("STRING_LITERAL: " + $STRING_LITERAL.text); }
251 -> ^(UNARY_EXPRESSION_STRING_QUOTES STRING_LITERAL)
252 /*| (LPAREN unaryExpression RPAREN)*/ // Not supported yet
261 debug_print($reference.text);
264 : (ref=DOT | ref=ARROW) IDENTIFIER -> ^($ref ^(UNARY_EXPRESSION_STRING IDENTIFIER))
267 postfixExpressionSuffix
269 enter("postfixExpressionSuffix");
272 exit("postfixExpressionSuffix");
274 : (OPENBRAC unaryExpression CLOSEBRAC!)
280 enter("postfixExpression");
283 exit("postfixExpression");
285 : (primaryExpression) (postfixExpressionSuffix)*
286 | ((ctfSpecifierHead) (postfixExpressionSuffix)+) // added for ctf-v1.8
291 enter("unaryExpression");
294 exit("unaryExpression");
297 /* | ((SIGN postfixExpression[true]) | postfixExpression[false]) */
302 enter("enumConstant");
305 debug_print($enumConstant.text);
306 exit("enumConstant");
308 : STRING_LITERAL -> ^(UNARY_EXPRESSION_STRING_QUOTES STRING_LITERAL)
309 | IDENTIFIER -> ^(UNARY_EXPRESSION_STRING IDENTIFIER)
310 | ctfKeyword -> ^(UNARY_EXPRESSION_STRING ctfKeyword)
316 enter("declaration");
324 : (declarationSpecifiers declaratorList? TERM)
325 // When the declaration is completely parsed and was a typedef,
326 // we add the declarators to the symbol table.
327 -> {inTypedef()}? ^(DECLARATION ^(TYPEDEF declaratorList declarationSpecifiers))
328 -> ^(DECLARATION declarationSpecifiers declaratorList?)
329 | (ctfSpecifier TERM!)
332 declarationSpecifiers
334 enter("declarationSpecifiers");
337 debug_print($declarationSpecifiers.text);
338 exit("declarationSpecifiers");
341 // We don't want to keep the typedef keyword in the specifier list.
342 // Instead, we keep track that we encountered a typedef in the declaration.
343 storageClassSpecifier
346 )+ -> ^(TYPE_SPECIFIER_LIST typeQualifier* typeSpecifier*)
351 enter("declaratorList");
354 exit("declaratorList");
356 : declarator (SEPARATOR declarator)* -> ^(TYPE_DECLARATOR_LIST declarator+)
359 abstractDeclaratorList
361 enter("abstractDeclaratorList");
364 exit("abstractDeclaratorList");
366 : abstractDeclarator (SEPARATOR abstractDeclarator)*
367 -> ^(TYPE_DECLARATOR_LIST abstractDeclarator+)
370 storageClassSpecifier
371 : TYPEDEFTOK { typedefOn(); }
376 enter("typeSpecifier");
379 debug_print($typeSpecifier.text);
380 exit("typeSpecifier");
398 | { inTypealiasAlias() || isTypeName(input.LT(1).getText()) }? => typedefName
403 enter("typeQualifier");
406 debug_print($typeQualifier.text);
407 exit("typeQualifier");
413 : ALIGNTOK LPAREN unaryExpression RPAREN -> ^(ALIGN unaryExpression)
416 // you can have an empty struct but not an empty variant
421 debug_print("Scope push " + Symbols_stack.size());
422 $Symbols::types = new HashSet<String>();
425 debug_print("Scope pop " + Symbols_stack.size());
428 : LCURL structOrVariantDeclarationList? RCURL
429 -> ^(STRUCT_BODY structOrVariantDeclarationList?)
434 enter("structSpecifier");
437 exit("structSpecifier");
441 // We have an IDENTIFIER after 'struct'
449 ( /* structBody can return an empty tree, so we need those ? */
460 // We have a body after 'struct'
469 ) -> ^(STRUCT structName? structBody? alignAttribute?)
477 debug_print($structName.text);
480 : IDENTIFIER -> ^(STRUCT_NAME IDENTIFIER)
483 structOrVariantDeclarationList
485 enter("structOrVariantDeclarationList");
488 exit("structOrVariantDeclarationList");
490 : structOrVariantDeclaration+
493 structOrVariantDeclaration
495 enter("structOrVariantDeclaration");
498 exit("structOrVariantDeclaration");
503 declarationSpecifiers
505 /* If we met a "typedef" */
506 {inTypedef()}? => declaratorList {typedefOff();}
507 -> ^(TYPEDEF declaratorList declarationSpecifiers)
508 | structOrVariantDeclaratorList
509 -> ^(SV_DECLARATION declarationSpecifiers structOrVariantDeclaratorList)
514 typealiasDecl -> typealiasDecl
519 specifierQualifierList
521 enter("specifierQualifierList");
524 exit("specifierQualifierList");
526 : (typeQualifier | typeSpecifier)+
527 -> ^(TYPE_SPECIFIER_LIST typeQualifier* typeSpecifier*)
530 structOrVariantDeclaratorList
532 enter("structOrVariantDeclaratorList");
535 exit("structOrVariantDeclaratorList");
537 : structOrVariantDeclarator (SEPARATOR structOrVariantDeclarator)*
538 -> ^(TYPE_DECLARATOR_LIST structOrVariantDeclarator+)
541 structOrVariantDeclarator
543 enter("structOrVariantDeclarator");
546 exit("structOrVariantDeclarator");
549 /* Bitfields not supported yet */
550 (declarator (COLON numberLiteral)?) -> declarator
551 /*| (COLON numberLiteral)*/
556 enter("variantSpecifier");
559 exit("variantSpecifier");
580 (variantTag variantBody)
583 ) -> ^(VARIANT variantName? variantTag? variantBody?)
588 enter("variantName");
591 debug_print($variantName.text);
594 : IDENTIFIER -> ^(VARIANT_NAME IDENTIFIER)
600 enter("variantBody");
601 debug_print("Scope push " + Symbols_stack.size());
602 $Symbols::types = new HashSet<String>();
605 debug_print("Scope pop " + Symbols_stack.size());
608 : LCURL structOrVariantDeclarationList RCURL
609 -> ^(VARIANT_BODY structOrVariantDeclarationList)
617 debug_print($variantTag.text);
620 : LT IDENTIFIER GT -> ^(VARIANT_TAG IDENTIFIER)
625 enter("enumSpecifier");
628 exit("enumSpecifier");
633 // Lines 1 to 5, when we have "ENUMTOK IDENTIFIER".
637 enumContainerType enumBody
641 // no enumDeclarator or enumBodym
645 // Lines 1, 2, 4, 5, when we have no IDENTIFIER.
647 enumContainerType enumBody
651 ) -> ^(ENUM enumName? enumContainerType? enumBody?)
659 debug_print($enumName.text);
663 IDENTIFIER -> ^(ENUM_NAME IDENTIFIER)
673 : LCURL enumeratorList (SEPARATOR RCURL | RCURL) -> ^(ENUM_BODY enumeratorList)
678 enter("enumContainerType");
681 exit("enumContainerType");
683 : COLON declarationSpecifiers -> ^(ENUM_CONTAINER_TYPE declarationSpecifiers)
688 enter("enumeratorList");
691 exit("enumeratorList");
693 : enumerator (SEPARATOR enumerator)* -> (^(ENUM_ENUMERATOR enumerator))+
703 : enumConstant enumeratorValue?
708 enter("enumeratorValue");
711 exit("enumeratorValue");
713 : ASSIGNMENT e1=unaryExpression
716 | ELIPSES e2=unaryExpression -> ^(ENUM_VALUE_RANGE $e1 $e2)
728 : pointer* directDeclarator -> ^(TYPE_DECLARATOR pointer* directDeclarator)
733 enter("directDeclarator");
736 exit("directDeclarator");
740 { if (inTypedef()) addTypeName($IDENTIFIER.text); }
741 { debug_print($IDENTIFIER.text); }
742 /*| LPAREN declarator RPAREN*/ /* Not supported yet */
744 directDeclaratorSuffix*
747 directDeclaratorSuffix
748 : OPENBRAC directDeclaratorLength CLOSEBRAC -> ^(LENGTH directDeclaratorLength)
751 directDeclaratorLength
757 enter("abstractDeclarator");
760 exit("abstractDeclarator");
762 : (pointer+ directAbstractDeclarator?)
763 -> ^(TYPE_DECLARATOR pointer+ directAbstractDeclarator?)
764 | directAbstractDeclarator
765 -> ^(TYPE_DECLARATOR directAbstractDeclarator)
769 In the CTF grammar, direct-abstract-declarator can be empty (because of identifier-opt).
770 We take care of that by appending a '?' to each use of "abstractDeclaratorList".
772 directAbstractDeclarator
774 enter("directAbstractDeclarator");
777 debug_print($directAbstractDeclarator.text);
778 exit("directAbstractDeclarator");
782 | (LPAREN abstractDeclarator RPAREN)
784 OPENBRAC unaryExpression? CLOSEBRAC
793 debug_print($pointer.text);
796 : POINTER typeQualifierList? -> ^(POINTER typeQualifierList?)
805 enter("typedefName");
808 debug_print("typedefName: " + $typedefName.text);
812 {inTypealiasAlias() || isTypeName(input.LT(1).getText())}? IDENTIFIER { if ((inTypedef() || inTypealiasAlias()) && !isTypeName($IDENTIFIER.text)) { addTypeName($IDENTIFIER.text); } }
816 * What goes in the target part of a typealias.
818 * For example, the integer part in:
819 * typealias integer {...} := my_new_integer;
823 enter("typealiasTarget");
826 exit("typealiasTarget");
828 : declarationSpecifiers abstractDeclaratorList?
832 * What goes in the alias part of a typealias.
834 * For example, the my_new_integer part in:
835 * typealias integer {...} := my_new_integer;
839 enter("typealiasAlias");
843 exit("typealiasAlias");
846 : ( abstractDeclaratorList
847 | (declarationSpecifiers abstractDeclaratorList?)
853 enter("typealiasDecl");
856 exit("typealiasDecl");
858 : TYPEALIASTOK typealiasTarget TYPE_ASSIGNMENT typealiasAlias
859 -> ^(TYPEALIAS ^(TYPEALIAS_TARGET typealiasTarget) ^(TYPEALIAS_ALIAS typealiasAlias))
864 // TODO: Ajouter ceux qui manquent
870 debug_print($ctfKeyword.text);
881 enter("ctfSpecifier");
884 exit("ctfSpecifier");
886 // event {...}, stream {...}, trace {...}
887 : ctfSpecifierHead ctfBody -> ^(ctfSpecifierHead ctfBody)
889 | typealiasDecl -> ^(DECLARATION typealiasDecl)
894 enter("ctfSpecifierHead");
897 debug_print($ctfSpecifierHead.text);
898 exit("ctfSpecifierHead");
901 | STREAMTOK -> STREAM
905 | CALLSITETOK -> CALLSITE
910 enter("ctfTypeSpecifier");
913 exit("ctfTypeSpecifier");
915 /* ctfBody can return an empty tree if the body is empty */
916 : FLOATINGPOINTTOK ctfBody -> ^(FLOATING_POINT ctfBody?)
917 | INTEGERTOK ctfBody -> ^(INTEGER ctfBody?)
918 | STRINGTOK ctfBody? -> ^(STRING ctfBody?)
925 debug_print("Scope push " + + Symbols_stack.size());
926 $Symbols::types = new HashSet<String>();
929 debug_print("Scope pop " + + Symbols_stack.size());
932 : LCURL ctfAssignmentExpressionList? RCURL -> ctfAssignmentExpressionList?
935 ctfAssignmentExpressionList
936 : (ctfAssignmentExpression TERM!)+
939 ctfAssignmentExpression
941 enter("ctfAssignmentExpression");
947 exit("ctfAssignmentExpression");
953 (assignment=ASSIGNMENT right1=unaryExpression) -> ^(CTF_EXPRESSION_VAL ^(CTF_LEFT $left) ^(CTF_RIGHT $right1))
954 | (type_assignment=TYPE_ASSIGNMENT right2=typeSpecifier) -> ^(CTF_EXPRESSION_TYPE ^(CTF_LEFT $left) ^(CTF_RIGHT ^(TYPE_SPECIFIER_LIST $right2)))
960 (declarationSpecifiers {inTypedef()}? declaratorList)
961 -> ^(TYPEDEF declaratorList declarationSpecifiers)