grammar CPPparser; options { language = C; backtrack = true; } @header { #include "pd.h" } decl_specifier @init { bzero(&data_type, sizeof(data_type)); data_type.data_type = DATA_TYPE_TYPE_DESC; } @after { print_data (&data_type); } : storage_class_specifier* WS? type_specifier? function_specifier? FRIEND? TYPEDEF? CONSTEXPR? /* | alignment_specifier */ ; storage_class_specifier : REGISTER { if (type_desc.storage_class == STORAGE_CLASS_NONE) type_desc.storage_class = STORAGE_CLASS_REGISTER; else fprintf (stderr, "Storage class already set.\n"); } | STATIC { if (type_desc.storage_class == STORAGE_CLASS_NONE) type_desc.storage_class = STORAGE_CLASS_STATIC; else fprintf (stderr, "Storage class already set.\n"); } | THREAD_LOCAL | EXTERN { if (type_desc.storage_class == STORAGE_CLASS_NONE) type_desc.storage_class = STORAGE_CLASS_EXTERN; else fprintf (stderr, "Storage class already set.\n"); } | MUTABLE ; type_specifier @init { type_desc.type = TYPE_CODE_UNSET; type_desc.size = -1; type_desc.nr_longs = 0; type_desc.nosign_bit = 1; type_desc.signed_bit = 0; } : ( ({!is_cpp}? simple_type_specifier | {is_cpp}? simple_type_specifier_cpp) WS?)+ | class_specifier /* | enum_specifier */ /* | elaborated_type_specifier */ /* | typename_specifier */ | cv_qualifier* ; simple_type_specifier : /* nested_name_specifier? type_name */ /* | nested_name_specifier TEMPLATE type_name */ CHAR { type_desc.type = TYPE_CODE_INT; type_desc.size = sizeof(char); } | WCHAR_T { type_desc.type = TYPE_CODE_INT; type_desc.size = sizeof(wchar_t); } /* | BOOL { type_desc.type = TYPE_CODE_INT; type_desc.size = sizeof(bool); } */ | SHORT { type_desc.type = TYPE_CODE_INT; type_desc.size = sizeof(short); } | INT { type_desc.type = TYPE_CODE_INT; switch (type_desc.nr_longs) { case 0: type_desc.size = sizeof(int); break; case 1: type_desc.size = sizeof(long int); break; case 2: type_desc.size = sizeof(long long int); break; } } | LONG { if (type_desc.type == TYPE_CODE_UNSET) type_desc.type = TYPE_CODE_INT; if (type_desc.nr_longs < 2) type_desc.nr_longs++; switch (type_desc.nr_longs) { case 0: type_desc.size = sizeof(int); break; case 1: type_desc.size = sizeof(long int); break; case 2: type_desc.size = sizeof(long long int); break; } } | SIGNED { type_desc.nosign_bit = 0; type_desc.signed_bit = 1; } | UNSIGNED { type_desc.nosign_bit = 0; type_desc.signed_bit = 0; } | FLOAT { type_desc.type = TYPE_CODE_FLT; type_desc.size = sizeof(float); } | DOUBLE { type_desc.type = TYPE_CODE_FLT; type_desc.size = (type_desc.nr_longs > 0) ? sizeof(long double) : sizeof(double); } | VOID { type_desc.type = TYPE_CODE_VOID; } | AUTO { } /* | decltype ( expression) */ ; simple_type_specifier_cpp : /* nested_name_specifier? type_name */ /* | nested_name_specifier TEMPLATE type_name */ Char { type_desc.type = TYPE_CODE_INT; type_desc.size = sizeof(char); } | Wchar_t { type_desc.type = TYPE_CODE_INT; type_desc.size = sizeof(wchar_t); } /* | Bool { type_desc.type = TYPE_CODE_INT; type_desc.size = sizeof(bool); } */ | Short { type_desc.type = TYPE_CODE_INT; type_desc.size = sizeof(short); } | Int { type_desc.type = TYPE_CODE_INT; switch (type_desc.nr_longs) { case 0: type_desc.size = sizeof(int); break; case 1: type_desc.size = sizeof(long int); break; case 2: type_desc.size = sizeof(long long int); break; } } | Long { if (type_desc.type == TYPE_CODE_UNSET) type_desc.type = TYPE_CODE_INT; if (type_desc.nr_longs < 2) type_desc.nr_longs++; switch (type_desc.nr_longs) { case 0: type_desc.size = sizeof(int); break; case 1: type_desc.size = sizeof(long int); break; case 2: type_desc.size = sizeof(long long int); break; } } | Signed { type_desc.nosign_bit = 0; type_desc.signed_bit = 1; } | Unsigned { type_desc.nosign_bit = 0; type_desc.signed_bit = 0; } | Float { type_desc.type = TYPE_CODE_FLT; type_desc.size = sizeof(float); } | Double { type_desc.type = TYPE_CODE_FLT; type_desc.size = (type_desc.nr_longs > 0) ? sizeof(long double) : sizeof(double); } | Void { type_desc.type = TYPE_CODE_VOID; } | Auto { } /* | decltype ( expression) */ ; class_specifier : class_head '{' member_specification* '}' ; class_head : class_key identifier? /* | nested_name_specifier identifier base_clause? */ /* | nested_name_specifier? simple_template_id base_clause? */ ; member_specification: type_specifier identifier initialiser? ';' | scope_specifier ':' ; class_key : CLASS | STRUCT | UNION ; scope_specifier : PRIVATE | PUBLIC | PROTECTED ; initialiser : '=' numeric /* | string */ /* | array */ ; numeric : FIXED | FLOATING | EXPO ; identifier : ALPHAI ALPHAC ; /* type_name: class_name enum_name typedef_name ; */ cv_qualifier : CONST | VOLATILE ; function_specifier : INLINE | VIRTUAL | EXPLICIT ; /* Literals for decl_specifier. */ FRIEND : 'friend' ; TYPEDEF : 'typedef' ; CONSTEXPR : 'constexpr' ; /* Literals for storage_specifier. */ REGISTER : 'register' ; STATIC : 'static' ; THREAD_LOCAL : 'thread_local' ; EXTERN : 'extern' ; MUTABLE : 'mutable' ; /* Literals for function_specifier. */ INLINE : 'inline' ; VIRTUAL : 'virtual' ; EXPLICIT : 'explicit' ; /* Literals for simple_type_specifier. */ CHAR : 'char' ; WCHAR_T : 'wchar_t' ; BOOL : 'bool' ; SHORT : 'short' ; INT : 'int' ; LONG : 'long' ; SIGNED : 'signed' ; UNSIGNED : 'unsigned' ; FLOAT : 'float' ; DOUBLE : 'double' ; VOID : 'void' ; AUTO : 'auto' ; /* Literals for simple_type_specifier_cpp. */ Char : 'Char' ; Wchar_t : 'Wchar_t' ; Bool : 'Bool' ; Short : 'Short' ; Int : 'Int' ; Long : 'Long' ; Signed : 'Signed' ; Unsigned : 'Unsigned' ; Float : 'Float' ; Double : 'Double' ; Void : 'Void' ; Auto : 'Auto' ; /* Literals for cv_qualifier. */ CONST : 'const' ; VOLATILE : 'volatile' ; /* Literals for class_key. */ CLASS : 'class' ; STRUCT : 'struct' ; UNION : 'union' ; /* Literals for scope_specifier. */ PRIVATE : 'private' ; PUBLIC : 'public' ; PROTECTED : 'protected' ; SIGN : ('+' | '-') ; INTEGER : ('0'..'9') ; FIXED : INTEGER+ ; FLOATING : INTEGER '.' INTEGER* ; EXPO : INTEGER ('.' INTEGER*)? ('e' | 'E') SIGN? INTEGER ; ALPHAI : ('a'..'z' | 'A'..'Z' | '_') ; ALPHAC : (ALPHAI | INTEGER)* ; NEWLINE : '\r' ? '\n' ; WS : (' ' |'\t' |'\n' |'\r' )* /*{ SKIP(); }*/ ;