compiler/libec: Parser improvements
[sdk] / compiler / libec / src / grammar.y
index c72e52d..a5a3ab1 100644 (file)
@@ -52,6 +52,9 @@ default:
    External external;
    Context context;
    AsmField asmField;
+   Attrib attrib;
+   ExtDecl extDecl;
+   Attribute attribute;
 
    Instantiation instance;
    MembersInit membersInit;
@@ -112,7 +115,7 @@ default:
              new_specifiers renew_specifiers asm_field_list
              property_watch_list watch_property_list
              dbindex_item_list dbfield_definition_list
-             template_arguments_list template_parameters_list
+             template_arguments_list template_parameters_list attribs_list
 
 %type <asmField> asm_field
 %type <specifier> storage_class_specifier enum_specifier_compound enum_specifier_nocompound type_qualifier type_specifier class_specifier class_specifier_error
@@ -123,8 +126,10 @@ default:
 %type <enumerator> enumerator
 %type <declarator> declarator direct_declarator direct_abstract_declarator abstract_declarator
                    direct_abstract_declarator_noarray abstract_declarator_noarray
-                   struct_declarator direct_declarator_function direct_declarator_function_start declarator_function_error direct_declarator_function_error declarator_function direct_declarator_nofunction
-                   declarator_nofunction
+                   struct_declarator direct_declarator_function direct_declarator_function_start declarator_function_error direct_declarator_function_error declarator_function direct_declarator_nofunction // declarator_nofunction
+                   direct_declarator_function_type_ok declarator_nofunction_type_ok direct_declarator_nofunction_type_ok declarator_function_type_ok direct_declarator_function_error_type_ok
+                   direct_declarator_function_start_type_ok direct_declarator_type_ok declarator_type_ok declarator_function_error_type_ok
+                   // tricky_declarator
 %type <pointer> pointer
 %type <initializer> initializer initializer_error initializer_condition initializer_condition_error
 %type <initDeclarator> init_declarator init_declarator_error
@@ -147,7 +152,10 @@ default:
 %type <classFunction> instance_class_function_definition instance_class_function_definition_error instance_class_function_definition_start instance_class_function_definition_start_error 
 %type <_class> class class_error class_head
 %type <classDef> struct_declaration struct_declaration_error
-%type <string> ext_decl string_literal ext_attrib base_strict_type_name
+%type <string> string_literal base_strict_type_name attribute_word
+%type <extDecl> ext_decl
+%type <attrib> attrib
+%type <attribute> attribute
 %type <prop> property property_start property_body class_property class_property_start class_property_body
 %type <propertyWatch> property_watch self_watch_definition
 
@@ -175,13 +183,14 @@ default:
 %nonassoc IFX
 %nonassoc ELSE
 %token CLASS THISCLASS CLASS_NAME
-%token PROPERTY SETPROP GETPROP NEWOP RENEW DELETE EXT_DECL EXT_STORAGE IMPORT DEFINE VIRTUAL EXT_ATTRIB
+%token PROPERTY SETPROP GETPROP NEWOP RENEW DELETE EXT_DECL EXT_STORAGE IMPORT DEFINE VIRTUAL ATTRIB
 %token PUBLIC PRIVATE
 %token TYPED_OBJECT ANY_OBJECT _INCREF EXTENSION ASM TYPEOF
 %token WATCH STOPWATCHING FIREWATCHERS WATCHABLE CLASS_DESIGNER CLASS_NO_EXPANSION CLASS_FIXED ISPROPSET
 %token CLASS_DEFAULT_PROPERTY PROPERTY_CATEGORY CLASS_DATA CLASS_PROPERTY SUBCLASS NAMESPACE
 %token NEW0OP RENEW0 VAARG
 %token DBTABLE DBFIELD DBINDEX DATABASE_OPEN
+%token ALIGNOF ATTRIB_DEP __ATTRIB
 
 %destructor { FreeIdentifier($$); } identifier 
 %destructor { FreePointer($$); } pointer
@@ -205,7 +214,7 @@ default:
 %destructor { FreeDeclarator($$); } declarator direct_declarator direct_abstract_declarator abstract_declarator
                                     direct_abstract_declarator_noarray abstract_declarator_noarray
                                     struct_declarator direct_declarator_function direct_declarator_function_start declarator_function_error direct_declarator_function_error declarator_function direct_declarator_nofunction
-                                    declarator_nofunction
+                                    //declarator_nofunction
 
 %destructor { FreeInitializer($$); } initializer initializer_error initializer_condition initializer_condition_error
 %destructor { FreeInitDeclarator($$); } init_declarator init_declarator_error
@@ -230,7 +239,7 @@ default:
 %destructor { Context ctx = curContext; PopContext(ctx); FreeContext(ctx); delete ctx; } class_decl
 %destructor { FreeClass($$); } class class_error class_head
 %destructor { FreeClassDef($$); } struct_declaration struct_declaration_error
-%destructor { delete $$; } ext_decl string_literal
+%destructor { delete $$; } string_literal attribute_word base_strict_type_name
 %destructor { FreeProperty($$); } property
 
 %destructor { FreeList($$, FreeExpression); }  argument_expression_list expression expression_error argument_expression_list_error 
@@ -254,6 +263,10 @@ default:
 %destructor { FreeList($$, FreeTemplateParameter); } template_parameters_list
 %destructor { FreeList($$, FreeTemplateArgument); } template_arguments_list
 %destructor { } declaration_mode
+%destructor { FreeAttrib($$); } attrib
+%destructor { FreeExtDecl($$); } ext_decl
+%destructor { FreeAttribute($$); } attribute
+%destructor { FreeList($$, FreeAttribute); }  attribs_list
 
 %start thefile
 
@@ -507,7 +520,7 @@ strict_type:
    ;
 
 class_function_definition_start:
-   guess_declaration_specifiers declarator_function
+   guess_declaration_specifiers declarator_function_type_ok
       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
    | declarator_function
       { $$ = MkClassFunction(null, null, $1, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
@@ -524,21 +537,21 @@ destructor_function_definition_start:
    ;
 
 virtual_class_function_definition_start:
-     VIRTUAL guess_declaration_specifiers declarator_function
+     VIRTUAL guess_declaration_specifiers declarator_function_type_ok
       { $$ = MkClassFunction($2, null, $3, null); $$.isVirtual = true; $$.loc = @$; $$.id = ++globalContext.nextID; }
    | VIRTUAL declarator_function
       { $$ = MkClassFunction(null, null, $2, null); $$.isVirtual = true; $$.loc = @$; $$.id = ++globalContext.nextID; }
       ;
 
 class_function_definition_start_error:
-     guess_declaration_specifiers declarator_function_error
+     guess_declaration_specifiers declarator_function_error_type_ok
       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
    | declarator_function_error
       { $$ = MkClassFunction(null, null, $1, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
    ;
 
 virtual_class_function_definition_start_error:
-     VIRTUAL guess_declaration_specifiers declarator_function_error
+     VIRTUAL guess_declaration_specifiers declarator_function_error_type_ok
       { $$ = MkClassFunction($2, null, $3, null); $$.isVirtual = true; $$.loc = @$; $$.id = ++globalContext.nextID; }
    | VIRTUAL declarator_function_error
       { $$ = MkClassFunction(null, null, $2, null); $$.isVirtual = true; $$.loc = @$; $$.id = ++globalContext.nextID; }
@@ -576,14 +589,14 @@ class_function_definition_error:
 
 // In Instances, return type is required to distinguish from calling the function
 instance_class_function_definition_start:
-   declaration_specifiers declarator_function
+   declaration_specifiers declarator_function_type_ok
       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
-   |  declaration_specifiers declarator_nofunction
+   |  declaration_specifiers declarator_nofunction_type_ok
       { $$ = MkClassFunction($1, null, MkDeclaratorFunction($2, null), null); $$.loc = @$; $$.id = ++globalContext.nextID; }
       ; 
 
 instance_class_function_definition_start_error:
-   declaration_specifiers declarator_function_error
+   declaration_specifiers declarator_function_error_type_ok
       { $$ = MkClassFunction($1, null, $2, null); $$.loc = @$; $$.id = ++globalContext.nextID; }
       ;
 
@@ -1527,6 +1540,10 @@ common_unary_expression:
    | SIZEOF '(' guess_type_name ')'          { $$ = MkExpTypeSize($3); $$.loc = @$; }
    | SIZEOF '(' CLASS type ')'          { $$ = MkExpClassSize($4); $$.loc = @$; }
    | SIZEOF '(' CLASS guess_type ')'          { $$ = MkExpClassSize($4); $$.loc = @$; }
+
+       | ALIGNOF '(' unary_expression ')'         { $$ = MkExpOp(null, ALIGNOF, $3); $$.loc = @$; }
+   | ALIGNOF simple_unary_expression           { $$ = MkExpOp(null, ALIGNOF, $2); $$.loc = @$; }
+   | ALIGNOF '(' guess_type_name ')'          { $$ = MkExpTypeAlign($3); $$.loc = @$; }
        ;
 
 unary_expression:
@@ -1775,6 +1792,9 @@ common_unary_expression_error:
         | SIZEOF '(' guess_type_name ')' error          { $$ = MkExpTypeSize($3); $$.loc = @$; }
     | SIZEOF '(' CLASS type ')' error   { $$ = MkExpClassSize($4); $$.loc = @$; }
     | SIZEOF '(' CLASS guess_type ')' error   { $$ = MkExpClassSize($4); $$.loc = @$; }
+    | ALIGNOF '(' unary_expression_error           { $$ = MkExpOp(null, ALIGNOF, $3); $$.loc = @$; }
+        | ALIGNOF simple_unary_expression_error           { $$ = MkExpOp(null, ALIGNOF, $2); $$.loc = @$; }
+        | ALIGNOF '(' guess_type_name ')' error          { $$ = MkExpTypeAlign($3); $$.loc = @$; }
        ;
 
 unary_expression_error:
@@ -2147,8 +2167,8 @@ class_specifier_error:
    ;
 
 ext_storage:
-     EXT_STORAGE  { $$ = MkSpecifierExtended(yytext); }
-   | ext_decl   { $$ = MkSpecifierExtended($1); delete $1; }
+     EXT_STORAGE  { $$ = MkSpecifierExtended(MkExtDeclString(CopyString(yytext))); }
+   | ext_decl   { $$ = MkSpecifierExtended($1); }
    ;
 
 type_qualifier:
@@ -2214,25 +2234,25 @@ strict_type_specifier:
 // TESTING declarator_nofunction here... For function declarations
 
 struct_declarator:
-         declarator_nofunction
+         declarator_nofunction_type_ok
       { $$ = MkStructDeclarator($1, null); $$.loc = @$; }
-       | declarator_nofunction ext_attrib
+       | declarator_nofunction_type_ok attrib
       { $$ = MkStructDeclarator($1, null); $$.structDecl.attrib = $2; $$.loc = @$; }  
        | ':' constant_expression
       { $$ = MkStructDeclarator(null, $2);  $$.loc = @$; }
-       | declarator_nofunction ':' constant_expression
+       | declarator_nofunction_type_ok ':' constant_expression
       { $$ = MkStructDeclarator($1, $3);  $$.loc = @$; }
-   | declarator_nofunction ':' constant_expression ':' constant_expression
+   | declarator_nofunction_type_ok ':' constant_expression ':' constant_expression
       { $$ = MkStructDeclarator($1, $3); $$.structDecl.posExp = $5; $$.loc = @$; }
        | ':' constant_expression_error
       { $$ = MkStructDeclarator(null, $2);  $$.loc = @$; }
-       | declarator_nofunction ':' constant_expression_error
+       | declarator_nofunction_type_ok ':' constant_expression_error
       { $$ = MkStructDeclarator($1, $3);  $$.loc = @$; }
-   | declarator_nofunction ':' constant_expression ':' constant_expression_error
+   | declarator_nofunction_type_ok ':' constant_expression ':' constant_expression_error
       { $$ = MkStructDeclarator($1, $3); $$.structDecl.posExp = $5; $$.loc = @$; }
-   | declarator_nofunction ':' constant_expression_error ':' constant_expression_error
+   | declarator_nofunction_type_ok ':' constant_expression_error ':' constant_expression_error
       { $$ = MkStructDeclarator($1, $3); $$.structDecl.posExp = $5; $$.loc = @$; }
-   | declarator_nofunction ':' constant_expression_error ':' constant_expression
+   | declarator_nofunction_type_ok ':' constant_expression_error ':' constant_expression
       { $$ = MkStructDeclarator($1, $3); $$.structDecl.posExp = $5; $$.loc = @$; }
    ;
 
@@ -2254,12 +2274,27 @@ struct_entry:
          $$.ctx = PushContext();
          FreeSpecifier($2);
       }
+   | struct_or_union ext_decl identifier 
+      {
+         $$ = MkStructOrUnion($1, $3, null);
+         $$.extDeclStruct = $2;
+         $$.addNameSpace = true;
+         $$.ctx = PushContext();
+      }
+   | struct_or_union ext_decl base_strict_type
+      {
+         $$ = MkStructOrUnion($1, MkIdentifier($3.name), null);
+         $$.extDeclStruct = $2;
+         $$.ctx = PushContext();
+         FreeSpecifier($3);
+      }
    ;
 
 struct_or_union_specifier_compound:
      struct_or_union_specifier_compound_error '}' { $$ = $1; $$.loc = @$; }
    | struct_entry '{' '}'                 { $$ = $1; $$.loc = @$; POP_DEFAULT_ACCESS PopContext(curContext); }
    | struct_or_union '{' '}'              { $$ = MkStructOrUnion($1, null, null); $$.loc = @$; POP_DEFAULT_ACCESS }
+   | struct_or_union ext_decl '{' '}'              { $$ = MkStructOrUnion($1, null, null); $$.extDeclStruct = $2; $$.loc = @$; POP_DEFAULT_ACCESS }
        ;
 
 struct_or_union_specifier_compound_error:
@@ -2270,6 +2305,10 @@ struct_or_union_specifier_compound_error:
        | struct_or_union '{' struct_declaration_list               { $$ = MkStructOrUnion($1, null, $3); POP_DEFAULT_ACCESS }
    | struct_or_union '{' struct_declaration_list_error               { $$ = MkStructOrUnion($1, null, $3); POP_DEFAULT_ACCESS }
    | struct_or_union '{' error              { $$ = MkStructOrUnion($1, null, null); POP_DEFAULT_ACCESS }
+
+       | struct_or_union ext_decl '{' struct_declaration_list               { $$ = MkStructOrUnion($1, null, $4); $$.extDeclStruct = $2; POP_DEFAULT_ACCESS }
+   | struct_or_union ext_decl '{' struct_declaration_list_error               { $$ = MkStructOrUnion($1, null, $4); $$.extDeclStruct = $2; POP_DEFAULT_ACCESS }
+   | struct_or_union ext_decl '{' error              { $$ = MkStructOrUnion($1, null, null); $$.extDeclStruct = $2; POP_DEFAULT_ACCESS }
        ;
 
 struct_or_union_specifier_nocompound:
@@ -2644,9 +2683,50 @@ identifier_list:
    | parameter_list_error ',' identifier    { $$ = $1; ListAdd($1, MkTypeName(null, MkDeclaratorIdentifier($3))); }
        ;
 
+/*
+tricky_declarator:
+   base_strict_type
+   {
+      $$ = MkDeclaratorIdentifier(MkIdentifier($1.name));
+      FreeSpecifier($1);
+   }
+   ;
+*/
+direct_declarator_nofunction_type_ok:
+     direct_declarator_nofunction
+   | base_strict_type
+   {
+      char * colon = RSearchString($1.name, "::", strlen($1.name), true, false);
+      String s = colon ? colon + 2 : $1.name;
+      FreeSpecifier($1);
+      $$ = MkDeclaratorIdentifier(MkIdentifier(s));
+   }
+   | UINT { $$ = MkDeclaratorIdentifier(MkIdentifier("uint")); }
+       | base_strict_type '[' constant_expression ']'
+      {
+         Declarator decl;
+         char * colon = RSearchString($1.name, "::", strlen($1.name), true, false);
+         String s = colon ? colon + 2 : $1.name;
+         decl = MkDeclaratorIdentifier(MkIdentifier(s));
+         FreeSpecifier($1);
+         $$ = MkDeclaratorArray(decl, $3);
+      }
+   | base_strict_type '[' constant_expression_error ']' { $$ = MkDeclaratorArray($1, $3); }
+       | base_strict_type '[' type ']' { $$ = MkDeclaratorEnumArray($1, $3); }
+       | base_strict_type '[' ']'                     { $$ = MkDeclaratorArray($1, null); }
+
+       | direct_declarator_nofunction_type_ok '[' constant_expression ']' { $$ = MkDeclaratorArray($1, $3); }
+   | direct_declarator_nofunction_type_ok '[' constant_expression_error ']' { $$ = MkDeclaratorArray($1, $3); }
+       | direct_declarator_nofunction_type_ok '[' type ']' { $$ = MkDeclaratorEnumArray($1, $3); }
+       | direct_declarator_nofunction_type_ok '[' ']'                     { $$ = MkDeclaratorArray($1, null); }
+       ;
+
 direct_declarator_nofunction:
          identifier                                                   { $$ = MkDeclaratorIdentifier($1); }
        | '(' declarator ')'                            { $$ = MkDeclaratorBrackets($2); }
+   | '(' ext_decl declarator ')'                            { $$ = MkDeclaratorBrackets(MkDeclaratorExtended($2, $3)); }
+       | '(' declarator_type_ok ')'                            { $$ = MkDeclaratorBrackets($2); }
+   | '(' ext_decl declarator_type_ok ')'                            { $$ = MkDeclaratorBrackets(MkDeclaratorExtended($2, $3)); }
        | direct_declarator_nofunction '[' constant_expression ']' { $$ = MkDeclaratorArray($1, $3); }
    | direct_declarator_nofunction '[' constant_expression_error ']' { $$ = MkDeclaratorArray($1, $3); }
        | direct_declarator_nofunction '[' type ']' { $$ = MkDeclaratorEnumArray($1, $3); }
@@ -2710,12 +2790,79 @@ direct_declarator_function_error:
 direct_declarator:
      direct_declarator_function
    | direct_declarator_nofunction
+/*
    | ext_decl direct_declarator_function
       { $$ = MkDeclaratorExtended($1, $2); }
    | ext_decl direct_declarator_nofunction
       { $$ = MkDeclaratorExtended($1, $2); }
+*/
+   ;
+
+
+direct_declarator_function_start_type_ok:
+     direct_declarator_nofunction_type_ok '('
    ;
 
+direct_declarator_function_type_ok:
+         direct_declarator_function_start_type_ok parameter_type_list ')' { $$ = MkDeclaratorFunction($1, $2); }
+   | direct_declarator_function_start_type_ok parameter_type_list_error ')' { $$ = MkDeclaratorFunction($1, $2); }
+       | direct_declarator_function_start_type_ok identifier_list ')'     { $$ = MkDeclaratorFunction($1, $2); }
+   | direct_declarator_function_start_type_ok identifier_list_error ')'     { $$ = MkDeclaratorFunction($1, $2); }
+       | direct_declarator_function_start_type_ok ')'                     { $$ = MkDeclaratorFunction($1, null); }
+       ;
+
+// Tricky stuff here for overriding...
+direct_declarator_function_error_type_ok:
+   direct_declarator_function_start_type_ok identifier_list_error
+      {
+         $$ = MkDeclaratorFunction($1, $2); 
+         fileInput.Seek(@1.end.pos, start); 
+         yyclearin;
+         resetScannerPos(&@1.end);
+         @$.start = @1.start;
+         @$.end = @1.end;
+      }
+   | direct_declarator_function_start_type_ok error
+      { 
+         $$ = MkDeclaratorFunction($1, null); 
+         fileInput.Seek(@1.end.pos, start); 
+         yyclearin;
+         resetScannerPos(&@1.end);
+         @$.start = @1.start;
+         @$.end = @1.end;
+      }
+   | direct_declarator_function_start_type_ok parameter_list '('
+      { 
+         $$ = MkDeclaratorFunction($1, $2); 
+         fileInput.Seek(@1.end.pos, start); 
+         yyclearin;
+         resetScannerPos(&@1.end);
+         @$.start = @1.start;
+         @$.end = @1.end;
+      }
+   | direct_declarator_function_start_type_ok guess_declaration_specifiers identifier '('
+      { 
+         $$ = MkDeclaratorFunction($1, null); 
+         fileInput.Seek(@1.end.pos, start); 
+         yyclearin;
+         resetScannerPos(&@1.end);
+         @$.start = @1.start;
+         @$.end = @1.end;
+         FreeList($2, FreeSpecifier);
+         FreeIdentifier($3);
+      }
+       ;
+
+direct_declarator_type_ok:
+     direct_declarator_function_type_ok
+   | direct_declarator_nofunction_type_ok
+/*
+   | ext_decl direct_declarator_function_type_ok
+      { $$ = MkDeclaratorExtended($1, $2); }
+   | ext_decl direct_declarator_nofunction_type_ok
+      { $$ = MkDeclaratorExtended($1, $2); }
+*/
+   ;
 /*
 asm_start:
     ASM '(' STRING_LITERAL { $<string>$ = CopyString(yytext); } STRING_LITERAL { $<string>$ = CopyString(yytext); }
@@ -2732,15 +2879,15 @@ asm_start:
    ;  
 
 ext_decl:
-     EXT_DECL { $$ = CopyString(yytext); }
-   | ext_attrib
+     EXT_DECL { $$ = MkExtDeclString(CopyString(yytext)); }
+   | attrib { $$ = MkExtDeclAttrib($1);
    | asm_start ')'
       {
          char temp[1024];
          strcpy(temp, $<string>1);
          strcat(temp, ")");
          delete $<string>1;
-         $$ = CopyString(temp);
+         $$ = MkExtDeclString(CopyString(temp));
       }
    | asm_start STRING_LITERAL { $$ = CopyString(yytext); } ')'
       {
@@ -2751,78 +2898,84 @@ ext_decl:
          strcat(temp, ")");
          delete $<string>1;
          delete $<string>3;
-         $$ = CopyString(temp);
+         $$ = MkExtDeclString(CopyString(temp));
       }
    ;
 */
 
 ext_decl:
-     EXT_DECL { $$ = CopyString(yytext); }
-   | ext_attrib
+     EXT_DECL { $$ = MkExtDeclString(CopyString(yytext)); }
+   | attrib { $$ = MkExtDeclAttrib($1); }
    | ASM '(' string_literal ')'
       {
          char temp[1024];
          strcpy(temp, "__asm__(");
          strcat(temp, $3);
          strcat(temp, ")");
-         $$ = CopyString(temp);
+         $$ = MkExtDeclString(CopyString(temp));
          delete $3;
       }
    ;
 
-ext_attrib:
-   EXT_ATTRIB  { $$ = CopyString(yytext); }
+_attrib:
+   ATTRIB      { $<i>$ = ATTRIB; }
+ | ATTRIB_DEP  { $<i>$ = ATTRIB_DEP; }
+ | __ATTRIB    { $<i>$ = __ATTRIB; }
+ ;
+
+
+attribute_word:
+     IDENTIFIER   { $$  = CopyString(yytext); }
+   | TYPE_NAME    { $$  = CopyString(yytext); }
+   | EXT_STORAGE  { $$  = CopyString(yytext); }
+   | EXT_DECL     { $$  = CopyString(yytext); }
+   | CONST        { $$  = CopyString(yytext); }
+   ;
+
+attribute:
+     attribute_word  { $$ = MkAttribute($1, null); $$.loc = @$; }
+   | attribute_word '(' expression ')'  { $$ = MkAttribute($1, MkExpBrackets($3)); $$.loc = @$; }
+   ;
+
+attribs_list:
+     attribute { $$ = MkListOne($1); }
+   | attribs_list attribute { ListAdd($1, $2); $$ = $1; }
+   | attribs_list ',' attribute { ListAdd($1, $3); $$ = $1; }
+   ;
+
+attrib:
+     _attrib '(' '(' attribs_list ')' ')' { $$ = MkAttrib($<i>1, $4); $$.loc = @$; }
+   | _attrib '(' '('              ')' ')'  { $$ = MkAttrib($<i>1, null); $$.loc = @$; }
    ;
-   
 
 direct_abstract_declarator:
-         '(' abstract_declarator ')'
-                                 { $$ = MkDeclaratorBrackets($2); }
-       | '[' ']'
-                                 { $$ = MkDeclaratorArray(null, null); }
-   | '[' constant_expression ']'
-                                 { $$ = MkDeclaratorArray(null, $2); }
-       | '[' constant_expression_error ']'
-                                 { $$ = MkDeclaratorArray(null, $2); }
-   | '[' type ']'
-                                 { $$ = MkDeclaratorEnumArray(null, $2); }
-       | direct_abstract_declarator '[' ']'
-                                 { $$ = MkDeclaratorArray($1, null); }
-       | direct_abstract_declarator '[' constant_expression ']'
-                                 { $$ = MkDeclaratorArray($1, $3); }
-       | direct_abstract_declarator '[' type']'
-                                 { $$ = MkDeclaratorEnumArray($1, $3); }
-       | direct_abstract_declarator '[' constant_expression_error ']'
-                                 { $$ = MkDeclaratorArray($1, $3); }
-       | '(' ')'
-                                 { $$ = MkDeclaratorFunction(null, null); }
-       | '(' parameter_type_list ')'
-                                 { $$ = MkDeclaratorFunction(null, $2); }
-       | '(' parameter_type_list_error ')'
-                                 { $$ = MkDeclaratorFunction(null, $2); }
-       | direct_abstract_declarator '(' ')'
-                                 { $$ = MkDeclaratorFunction($1, null); }
-       | direct_abstract_declarator '(' parameter_type_list ')'
-                                 { $$ = MkDeclaratorFunction($1, $3); }
-       | direct_abstract_declarator '(' parameter_type_list_error ')'
-                                 { $$ = MkDeclaratorFunction($1, $3); }
+         '(' abstract_declarator ')'               { $$ = MkDeclaratorBrackets($2); }
+       | '(' ext_decl abstract_declarator ')'               { $$ = MkDeclaratorBrackets(MkDeclaratorExtended($2, $3)); }
+       | '[' ']'                                   { $$ = MkDeclaratorArray(null, null); }
+   | '[' constant_expression ']'               { $$ = MkDeclaratorArray(null, $2); }
+       | '[' constant_expression_error ']'         { $$ = MkDeclaratorArray(null, $2); }
+   | '[' type ']'                              { $$ = MkDeclaratorEnumArray(null, $2); }
+       | direct_abstract_declarator '[' ']'        { $$ = MkDeclaratorArray($1, null); }
+       | direct_abstract_declarator '[' constant_expression ']'        { $$ = MkDeclaratorArray($1, $3); }
+       | direct_abstract_declarator '[' type']'                        { $$ = MkDeclaratorEnumArray($1, $3); }
+       | direct_abstract_declarator '[' constant_expression_error ']'  { $$ = MkDeclaratorArray($1, $3); }
+       | '(' ')'                                   { $$ = MkDeclaratorFunction(null, null); }
+       | '(' parameter_type_list ')'               { $$ = MkDeclaratorFunction(null, $2); }
+       | '(' parameter_type_list_error ')'         { $$ = MkDeclaratorFunction(null, $2); }
+       | direct_abstract_declarator '(' ')'        { $$ = MkDeclaratorFunction($1, null); }
+       | direct_abstract_declarator '(' parameter_type_list ')'         { $$ = MkDeclaratorFunction($1, $3); }
+       | direct_abstract_declarator '(' parameter_type_list_error ')'   { $$ = MkDeclaratorFunction($1, $3); }
        ;
 
 direct_abstract_declarator_noarray:
-         '(' abstract_declarator_noarray ')'
-                                 { $$ = MkDeclaratorBrackets($2); }
-       | '(' ')'
-                                 { $$ = MkDeclaratorFunction(null, null); }
-       | '(' parameter_type_list ')'
-                                 { $$ = MkDeclaratorFunction(null, $2); }
-       | '(' parameter_type_list_error ')'
-                                 { $$ = MkDeclaratorFunction(null, $2); }
-       | direct_abstract_declarator_noarray '(' ')'
-                                 { $$ = MkDeclaratorFunction($1, null); }
-       | direct_abstract_declarator_noarray '(' parameter_type_list ')'
-                                 { $$ = MkDeclaratorFunction($1, $3); }
-       | direct_abstract_declarator_noarray '(' parameter_type_list_error ')'
-                                 { $$ = MkDeclaratorFunction($1, $3); }
+         '(' abstract_declarator_noarray ')'          { $$ = MkDeclaratorBrackets($2); }
+       | '(' ext_decl abstract_declarator_noarray ')' { $$ = MkDeclaratorBrackets(MkDeclaratorExtended($2, $3)); }
+       | '(' ')'                                      { $$ = MkDeclaratorFunction(null, null); }
+       | '(' parameter_type_list ')'                  { $$ = MkDeclaratorFunction(null, $2); }
+       | '(' parameter_type_list_error ')'         { $$ = MkDeclaratorFunction(null, $2); }
+       | direct_abstract_declarator_noarray '(' ')'   { $$ = MkDeclaratorFunction($1, null); }
+       | direct_abstract_declarator_noarray '(' parameter_type_list ')'       { $$ = MkDeclaratorFunction($1, $3); }
+       | direct_abstract_declarator_noarray '(' parameter_type_list_error ')' { $$ = MkDeclaratorFunction($1, $3); }
        ;
 
 pointer:
@@ -2837,7 +2990,7 @@ abstract_declarator:
        | direct_abstract_declarator
        | pointer direct_abstract_declarator   { $$ = MkDeclaratorPointer($1, $2); }
    | ext_decl pointer { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, null)); }
-   | ext_decl direct_abstract_declarator { $$ = MkDeclaratorExtended($1, $2); }
+//   | ext_decl direct_abstract_declarator { $$ = MkDeclaratorExtended($1, $2); }
        | ext_decl pointer direct_abstract_declarator { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
        ;
 
@@ -2846,8 +2999,8 @@ abstract_declarator_noarray:
        | direct_abstract_declarator_noarray
        | pointer direct_abstract_declarator_noarray   { $$ = MkDeclaratorPointer($1, $2); }
    | ext_decl pointer { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, null)); }
-   | ext_decl direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, $2); }
-       | ext_decl pointer direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
+//   | ext_decl direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, $2); }
+   | ext_decl pointer direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
        ;
 
 declarator:
@@ -2858,12 +3011,24 @@ declarator:
       { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
    | declarator ext_decl
       { $$ = MkDeclaratorExtendedEnd($2, $1); }  
+   | declarator_nofunction_type_ok ext_decl
+      { $$ = MkDeclaratorExtendedEnd($2, $1); }  
+   ;
+
+declarator_type_ok:
+         direct_declarator_type_ok
+       | pointer direct_declarator_type_ok
+      { $$ = MkDeclaratorPointer($1, $2); }
+  | ext_decl pointer direct_declarator_type_ok
+      { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
+   | declarator_type_ok ext_decl
+      { $$ = MkDeclaratorExtendedEnd($2, $1); }  
    ;
 
 declarator_function:
      direct_declarator_function
        | pointer direct_declarator_function      { $$ = MkDeclaratorPointer($1, $2); }
-   | ext_decl direct_declarator_function { $$ = MkDeclaratorExtended($1, $2); }
+//   | ext_decl direct_declarator_function { $$ = MkDeclaratorExtended($1, $2); }
        | ext_decl pointer direct_declarator_function { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
        | pointer ext_decl direct_declarator_function { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
    ;
@@ -2871,18 +3036,44 @@ declarator_function:
 declarator_function_error:
          direct_declarator_function_error
        | pointer direct_declarator_function_error      { $$ = MkDeclaratorPointer($1, $2); }
-   | ext_decl direct_declarator_function_error { $$ = MkDeclaratorExtended($1, $2); }
+//   | ext_decl direct_declarator_function_error { $$ = MkDeclaratorExtended($1, $2); }
        | ext_decl pointer direct_declarator_function_error { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
        | pointer ext_decl direct_declarator_function_error { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
    ;
 
+/*
 declarator_nofunction:
          direct_declarator_nofunction
        | pointer direct_declarator_nofunction      { $$ = MkDeclaratorPointer($1, $2); }
-   | ext_decl direct_declarator_nofunction { $$ = MkDeclaratorExtended($1, $2); }
+//   | ext_decl direct_declarator_nofunction { $$ = MkDeclaratorExtended($1, $2); }
        | ext_decl pointer direct_declarator_nofunction { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
        | pointer ext_decl direct_declarator_nofunction { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
    ;
+*/
+
+declarator_function_type_ok:
+     direct_declarator_function_type_ok
+       | pointer direct_declarator_function_type_ok      { $$ = MkDeclaratorPointer($1, $2); }
+//   | ext_decl direct_declarator_function_type_ok { $$ = MkDeclaratorExtended($1, $2); }
+       | ext_decl pointer direct_declarator_function_type_ok { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
+       | pointer ext_decl direct_declarator_function_type_ok { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
+   ;
+
+declarator_function_error_type_ok:
+         direct_declarator_function_error_type_ok
+       | pointer direct_declarator_function_error_type_ok      { $$ = MkDeclaratorPointer($1, $2); }
+//   | ext_decl direct_declarator_function_error_type_ok { $$ = MkDeclaratorExtended($1, $2); }
+       | ext_decl pointer direct_declarator_function_error_type_ok { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
+       | pointer ext_decl direct_declarator_function_error_type_ok { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
+   ;
+
+declarator_nofunction_type_ok:
+         direct_declarator_nofunction_type_ok
+       | pointer direct_declarator_nofunction_type_ok      { $$ = MkDeclaratorPointer($1, $2); }
+//   | ext_decl direct_declarator_nofunction_type_ok { $$ = MkDeclaratorExtended($1, $2); }
+       | ext_decl pointer direct_declarator_nofunction_type_ok { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
+       | pointer ext_decl direct_declarator_nofunction_type_ok { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
+   ;
 
 initializer:
          assignment_expression          { $$ = MkInitializerAssignment($1); $$.loc = @$; }
@@ -2958,6 +3149,7 @@ initializer_list:
 
 init_declarator:
          declarator                     { $$ = MkInitDeclarator($1, null); $$.loc = @$; }
+   | declarator_type_ok             { $$ = MkInitDeclarator($1, null); $$.loc = @$; }
        | declarator '=' initializer     { $$ = MkInitDeclarator($1, $3); $$.loc = @$; $$.initializer.loc.start = @2.end; }
        ;
 
@@ -2972,7 +3164,23 @@ init_declarator_error:
 init_declarator_list:
          init_declarator                            { $$ = MkList(); ListAdd($$, $1); }
        | init_declarator_list ',' init_declarator   { $$ = $1; ListAdd($1, $3); }
+       | UINT ',' init_declarator                  { $$ = MkList(); ListAdd($$, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("uint")), null)); ListAdd($$, $3); }
+   | INT64 ',' init_declarator                  { $$ = MkList(); ListAdd($$, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("int64")), null)); ListAdd($$, $3); }
+       | base_strict_type ',' init_declarator
+   {
+      char * colon = RSearchString($1.name, "::", strlen($1.name), true, false);
+      String s = colon ? colon + 2 : $1.name;
+      FreeSpecifier($1);
+      $$ = MkList();
+      ListAdd($$, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(s)), null));
+      ListAdd($$, $3);
+   }
    | init_declarator_list_error ',' init_declarator   { $$ = $1; ListAdd($1, $3); }
+   /*| base_strict_type ',' init_declarator
+      {
+         $$ = MkList();
+         ListAdd($1, $3);
+      }*/
        ;
 
 init_declarator_list_error:
@@ -2994,11 +3202,11 @@ guess_type_name:
 
 /*** PARAMETERS **********************************************************************/
 parameter_declaration:
-     guess_declaration_specifiers declarator          { $$ = MkTypeName($1, $2); }
+     guess_declaration_specifiers declarator_type_ok          { $$ = MkTypeName($1, $2); }
    | guess_declaration_specifiers abstract_declarator { $$ = MkTypeName($1, $2); }
    | guess_declaration_specifiers '&'                 { $$ = MkTypeName($1, MkDeclaratorPointer(MkPointer(null,null), null)); }
-   | guess_declaration_specifiers '&' declarator      { $$ = MkTypeName($1, MkDeclaratorPointer(MkPointer(null,null), $3)); }
-       | guess_declaration_specifiers                     { $$ = MkTypeName($1, null); }
+   | guess_declaration_specifiers '&' declarator_type_ok      { $$ = MkTypeName($1, MkDeclaratorPointer(MkPointer(null,null), $3)); }
+       | guess_declaration_specifiers                     { $$ = MkTypeNameGuessDecl($1, null); }
    | CLASS
       { $$ = MkTypeName(MkListOne(MkSpecifier(CLASS)), null); }
 /*
@@ -3018,7 +3226,7 @@ parameter_declaration:
        ;
 
 parameter_declaration_error:
-         guess_declaration_specifiers declarator error          { $$ = MkTypeName($1, $2); }
+         guess_declaration_specifiers declarator_type_ok error          { $$ = MkTypeName($1, $2); }
        | guess_declaration_specifiers abstract_declarator error { $$ = MkTypeName($1, $2); }
        ;
 
@@ -3066,7 +3274,7 @@ parameter_type_list_error:
 /****** STATEMENTS *******************************************************************/
 statement:
          labeled_statement
-   | EXT_ATTRIB { $$ = MkExpressionStmt(null); }   // Ignoring this for now... ( For __attribute__ ((__unused__)) )
+   | attrib { $$ = MkExpressionStmt(null); FreeAttrib($1); }   // Ignoring this for now... ( For __attribute__ ((__unused__)) )
        | compound_statement
    | ';' { $$ = MkExpressionStmt(null); }
    | ':' { $$ = MkExpressionStmt(null); }
@@ -3338,6 +3546,9 @@ function_definition:
          external_guess_declaration_specifiers declarator_function declaration_list compound_statement      { $$ = MkFunction($1, $2, $3); ProcessFunctionBody($$, $4); $$.loc = @$; }
        | external_guess_declaration_specifiers declarator_function compound_statement                       
        { $$ = MkFunction($1, $2, null); ProcessFunctionBody($$, $3); $$.loc = @$; }
+       | external_guess_declaration_specifiers declarator_function_type_ok declaration_list compound_statement      { $$ = MkFunction($1, $2, $3); ProcessFunctionBody($$, $4); $$.loc = @$; }
+       | external_guess_declaration_specifiers declarator_function_type_ok compound_statement                       
+       { $$ = MkFunction($1, $2, null); ProcessFunctionBody($$, $3); $$.loc = @$; }
 
        | declarator_function declaration_list compound_statement                             { $$ = MkFunction(null, $1, $2); ProcessFunctionBody($$, $3); $$.loc = @$; }
        | declarator_function compound_statement                                              { $$ = MkFunction(null, $1, null); ProcessFunctionBody($$, $2); $$.loc = @$;}
@@ -3345,6 +3556,8 @@ function_definition:
 function_definition_error:
      external_guess_declaration_specifiers declarator_function declaration_list compound_statement_error      { $$ = MkFunction($1, $2, $3); ProcessFunctionBody($$, $4); $$.loc = @$; $$.loc.end = $4.loc.end; }
        | external_guess_declaration_specifiers declarator_function compound_statement_error                       { $$ = MkFunction($1, $2, null); ProcessFunctionBody($$, $3); $$.loc = @$; $$.loc.end = $3.loc.end; }
+   | external_guess_declaration_specifiers declarator_function_type_ok declaration_list compound_statement_error      { $$ = MkFunction($1, $2, $3); ProcessFunctionBody($$, $4); $$.loc = @$; $$.loc.end = $4.loc.end; }
+       | external_guess_declaration_specifiers declarator_function_type_ok compound_statement_error                       { $$ = MkFunction($1, $2, null); ProcessFunctionBody($$, $3); $$.loc = @$; $$.loc.end = $3.loc.end; }
        | declarator_function declaration_list compound_statement_error                             { $$ = MkFunction(null, $1, $2); ProcessFunctionBody($$, $3); $$.loc = @$; $$.loc.end = $3.loc.end; }
        | declarator_function compound_statement_error                                              { $$ = MkFunction(null, $1, null); ProcessFunctionBody($$, $2); $$.loc = @$; $$.loc.end = $2.loc.end; }
    ;