wip II
[sdk] / compiler / libec / src / grammar.y
index 2c34911..1d6902d 100644 (file)
@@ -25,6 +25,8 @@ int defaultMemberAccess = -1;
 
 #define POP_DEFAULT_ACCESS    if(defaultMemberAccess > -1) defaultMemberAccess--;
 
+#define C89_DECL_WARNING   "eC expects all declarations to precede statements in the block (C89 style)\n"
+
 #define uint _uint
 default:
 
@@ -127,7 +129,8 @@ default:
 %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
+                   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
 %type <pointer> pointer
 %type <initializer> initializer initializer_error initializer_condition initializer_condition_error
 %type <initDeclarator> init_declarator init_declarator_error
@@ -212,7 +215,8 @@ 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
+                                    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
 
 %destructor { FreeInitializer($$); } initializer initializer_error initializer_condition initializer_condition_error
 %destructor { FreeInitDeclarator($$); } init_declarator init_declarator_error
@@ -518,7 +522,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; }
@@ -535,21 +539,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; }
@@ -587,14 +591,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; }
       ;
 
@@ -1110,30 +1114,16 @@ firewatchers:
        ;
 
 struct_declaration:
-         guess_declaration_specifiers struct_declarator_list ';'         { $$ = MkClassDefDeclaration(MkStructDeclaration($1, $2, null)); $$.decl.loc = @$; $$.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
-   | guess_declaration_specifiers ';'                                { $$ = MkClassDefDeclaration(MkStructDeclaration($1, null, null)); $$.decl.loc = @$; $$.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
-   | instantiation_unnamed ';'                                       { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = @$; $$.decl.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
-   | guess_instantiation_named ';'                                   { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = @$; $$.decl.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
+     struct_declaration_error ';' { $$ = $1; $$.loc.end = @2.start; }
+   | default_property_list ';'     { $$ = MkClassDefDefaultProperty($1); if($1->last) ((MemberInit)$1->last).loc.end = @2.start; $$.loc = @$; }
    | class_function_definition                                       { $$ = MkClassDefFunction($1); $$.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
    | property                       { $$ = MkClassDefProperty($1); $$.loc = @$; globalContext.nextID++; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
-
-       | member_access guess_declaration_specifiers struct_declarator_list ';'         { $$ = MkClassDefDeclaration(MkStructDeclaration($2, $3, null)); $$.decl.loc = @$; $$.loc = @$; $$.memberAccess = $1; }
-   | member_access guess_declaration_specifiers ';'                                { $$ = MkClassDefDeclaration(MkStructDeclaration($2, null, null)); $$.decl.loc = @$; $$.loc = @$; $$.memberAccess = $1; }
-   | member_access instantiation_unnamed ';'                                       { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = @$; $$.memberAccess = $1; }
-   | member_access guess_instantiation_named ';'                                   { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = @$; $$.memberAccess = $1; }
    | member_access class_function_definition                                       { $$ = MkClassDefFunction($2); $$.loc = @$; $$.memberAccess = $1; }
    | member_access property                       { $$ = MkClassDefProperty($2); $$.loc = @$; globalContext.nextID++; $$.memberAccess = $1; }
-
-   | default_property_list ';'      { $$ = MkClassDefDefaultProperty($1); if($1->last) ((MemberInit)$1->last).loc.end = @2.start; $$.loc = @$; }
-   | CLASS_DATA guess_declaration_specifiers struct_declarator_list ';' { $$ = MkClassDefClassData(MkStructDeclaration($2, $3, null)); $$.decl.loc = @$; $$.loc = @$; }
    | class_property                 { $$ = MkClassDefClassProperty($1); $$.loc = @$; globalContext.nextID++; }
-   | self_watch_definition ';'      { $$ = MkClassDefPropertyWatch($1); $$.loc = @$; globalContext.nextID++; }
    | WATCHABLE { $$ = null; deleteWatchable = true; }
-   | CLASS_DESIGNER identifier ';' { $$ = MkClassDefDesigner($2.string); FreeIdentifier($2); }
-   | CLASS_DESIGNER strict_type ';' { $$ = MkClassDefDesigner($2.name); FreeSpecifier($2); }
    | CLASS_NO_EXPANSION             { $$ = MkClassDefNoExpansion(); }
    | CLASS_FIXED                    { $$ = MkClassDefFixed(); }
-   | CLASS_DEFAULT_PROPERTY identifier ';' { $$ = MkClassDefDesignerDefaultProperty($2); }
    | CLASS_PROPERTY '(' identifier ')' '=' initializer_condition ';' { $$ = MkClassDefClassPropertyValue($3, $6); $$.loc = @$; }
 
    | ';' { $$ = null; }
@@ -1144,16 +1134,33 @@ struct_declaration:
 
 struct_declaration_error:
      class_function_definition_error { $$ = MkClassDefFunction($1); $$.loc = $1.loc;  $$.loc.end.charPos++; $$.loc.end.pos++; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
+
+// Moved all these in here without the ';'
+   | guess_declaration_specifiers                                { $$ = MkClassDefDeclaration(MkStructDeclaration($1, null, null)); $$.decl.loc = @$; $$.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
+       | guess_declaration_specifiers struct_declarator_list          { $$ = MkClassDefDeclaration(MkStructDeclaration($1, $2, null)); $$.decl.loc = @$; $$.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
+       | member_access guess_declaration_specifiers struct_declarator_list         { $$ = MkClassDefDeclaration(MkStructDeclaration($2, $3, null)); $$.decl.loc = @$; $$.loc = @$; $$.memberAccess = $1; }
+   | member_access guess_declaration_specifiers                                { $$ = MkClassDefDeclaration(MkStructDeclaration($2, null, null)); $$.decl.loc = @$; $$.loc = @$; $$.memberAccess = $1; }
+   | member_access instantiation_unnamed                                       { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = @$; $$.memberAccess = $1; }
+   | member_access guess_instantiation_named                                   { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = @$; $$.memberAccess = $1; }
+   | CLASS_DATA guess_declaration_specifiers struct_declarator_list { $$ = MkClassDefClassData(MkStructDeclaration($2, $3, null)); $$.decl.loc = @$; $$.loc = @$; }
+   | self_watch_definition      { $$ = MkClassDefPropertyWatch($1); $$.loc = @$; globalContext.nextID++; }
+   | CLASS_DESIGNER identifier { $$ = MkClassDefDesigner($2.string); FreeIdentifier($2); }
+   | CLASS_DESIGNER strict_type { $$ = MkClassDefDesigner($2.name); FreeSpecifier($2); }
+   | CLASS_DEFAULT_PROPERTY identifier { $$ = MkClassDefDesignerDefaultProperty($2); }
+   | instantiation_unnamed                                       { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = @$; $$.decl.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
+   | guess_instantiation_named                                   { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = @$; $$.decl.loc = @$; $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
+   | default_property_list     { $$ = MkClassDefDefaultProperty($1); if($1->last) ((MemberInit)$1->last).loc.end = @1.end; $$.loc = @$; }
+
    | guess_instantiation_named_error error { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = $1.loc; $$.decl.loc = $$.loc;  $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
    | instantiation_unnamed_error error { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = $1.loc; $$.decl.loc = $$.loc;  $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
-   | guess_instantiation_named { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = $1.loc; $$.decl.loc = $$.loc;  $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
-   | instantiation_unnamed { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = $1.loc; $$.decl.loc = $$.loc;  $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
+//   | guess_instantiation_named { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = $1.loc; $$.decl.loc = $$.loc;  $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
+//   | instantiation_unnamed { $$ = MkClassDefDeclaration(MkDeclarationClassInst($1)); $$.loc = $1.loc; $$.decl.loc = $$.loc;  $$.memberAccess = memberAccessStack[defaultMemberAccess]; }
 
    | member_access class_function_definition_error { $$ = MkClassDefFunction($2); $$.loc = @$;  $$.loc.end.charPos++; $$.loc.end.pos++; $$.memberAccess = $1; }
    | member_access guess_instantiation_named_error error { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = $$.loc; $$.memberAccess = $1; }
    | member_access instantiation_unnamed_error error { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = $$.loc; $$.memberAccess = $1; }
-   | member_access guess_instantiation_named { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = $$.loc; $$.memberAccess = $1; }
-   | member_access instantiation_unnamed { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = $$.loc; $$.memberAccess = $1; }
+//   | member_access guess_instantiation_named { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = $$.loc; $$.memberAccess = $1; }
+//   | member_access instantiation_unnamed { $$ = MkClassDefDeclaration(MkDeclarationClassInst($2)); $$.loc = @$; $$.decl.loc = $$.loc; $$.memberAccess = $1; }
 
    | default_property_list_error { $$ = MkClassDefDefaultProperty($1); $$.loc = @$;  $$.loc.end.charPos++; $$.loc.end.pos++; }
    ;
@@ -1173,13 +1180,21 @@ struct_declaration_list_error:
        ;
 
 template_datatype:
-     declaration_specifiers { $$ = MkTemplateDatatype($1, null); }
-   | declaration_specifiers abstract_declarator { $$ = MkTemplateDatatype($1, $2); }
-   | identifier { $$ = MkTemplateDatatype(MkListOne(MkSpecifierName($1.string)), null); FreeIdentifier($1); }
+     guess_declaration_specifiers { $$ = MkTemplateDatatype($1, null); }
+   | guess_declaration_specifiers abstract_declarator { $$ = MkTemplateDatatype($1, $2); }
+//   | identifier { $$ = MkTemplateDatatype(MkListOne(MkSpecifierName($1.string)), null); FreeIdentifier($1); }
    ;
 
 template_type_argument:
-     template_datatype { $$ = MkTemplateTypeArgument($1); }
+//     template_datatype { $$ = MkTemplateTypeArgument($1); }
+
+//    Explicitly copied the rules here to handle:
+//      ast.ec:  Map<List<Location>> intlStrings { };
+//          vs
+//      LinkList.ec:   class LinkList<bool circ = false>
+
+     guess_declaration_specifiers { $$ = MkTemplateTypeArgument(MkTemplateDatatype($1, null)); }
+   | guess_declaration_specifiers abstract_declarator { $$ = MkTemplateTypeArgument(MkTemplateDatatype($1, $2)); }
    ;
 
 template_type_parameter:
@@ -1203,12 +1218,16 @@ template_identifier_parameter:
    ;
 
 template_expression_argument:
-     constant_expression { $$ = MkTemplateExpressionArgument($1); }
+     shift_expression /*constant_expression*/ { $$ = MkTemplateExpressionArgument($1); }
    ;
 
 template_expression_parameter:
+/*
      template_datatype identifier     { $$ = MkExpressionTemplateParameter($2, $1, null); }
    | template_datatype identifier '=' template_expression_argument    { $$ = MkExpressionTemplateParameter($2, $1, $4); }
+*/
+     guess_declaration_specifiers identifier '=' template_expression_argument    { $$ = MkExpressionTemplateParameter($2, MkTemplateDatatype($1, null), $4); }
+   | guess_declaration_specifiers abstract_declarator identifier '=' template_expression_argument    { $$ = MkExpressionTemplateParameter($3, MkTemplateDatatype($1, $2), $5); }
    ;
 
 template_parameter:
@@ -1229,7 +1248,7 @@ template_argument:
    | identifier '=' template_expression_argument   { $$ = $3; $$.name = $1; $$.loc = @$; }
    | identifier '=' template_identifier_argument   { $$ = $3; $$.name = $1; $$.loc = @$; }
    | identifier '=' template_type_argument         { $$ = $3; $$.name = $1; $$.loc = @$; }
-   | template_datatype '=' template_expression_argument 
+   /*| template_datatype '=' template_expression_argument
    {
       $$ = $3; 
       if($1.specifiers && $1.specifiers->first)
@@ -1264,7 +1283,7 @@ template_argument:
       }
       FreeTemplateDataType($1);
       $$.loc = @$;
-   }
+   }*/
    ;
 
 template_arguments_list:
@@ -1305,6 +1324,7 @@ class_decl:
    }
    | identifier class_entry identifier '<' template_parameters_list '>' { $2; $$ = DeclClassAddNameSpace(globalContext.nextID++, $3.string); $$.templateParams = $5; FreeIdentifier($1); FreeIdentifier($3); $$.nameLoc = @3; $$.isRemote = true; memberAccessStack[++defaultMemberAccess] = privateAccess; }
    | identifier class_entry base_strict_type '<' template_parameters_list '>' { $2; $$ = DeclClass(globalContext.nextID++, $3.name); $$.templateParams = $5; FreeIdentifier($1); $$.nameLoc = @3; $$.isRemote = true; FreeSpecifier($3); memberAccessStack[++defaultMemberAccess] = privateAccess; }
+
    ;
 
 class:
@@ -2165,8 +2185,7 @@ class_specifier_error:
    ;
 
 ext_storage:
-     EXT_STORAGE  { $$ = MkSpecifierExtended(MkExtDeclString(CopyString(yytext))); }
-   | ext_decl   { $$ = MkSpecifierExtended($1); }
+   ext_decl   { $$ = MkSpecifierExtended($1); }
    ;
 
 type_qualifier:
@@ -2232,25 +2251,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 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 = @$; }
    ;
 
@@ -2272,12 +2291,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:
@@ -2288,6 +2322,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:
@@ -2662,9 +2700,65 @@ identifier_list:
    | parameter_list_error ',' identifier    { $$ = $1; ListAdd($1, MkTypeName(null, MkDeclaratorIdentifier($3))); }
        ;
 
+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;
+      $$ = MkDeclaratorIdentifier(MkIdentifier(s));
+      FreeSpecifier($1);
+   }
+   | UINT { $$ = MkDeclaratorIdentifier(MkIdentifier("uint")); }
+   // These rules need to be reviewed in lights of prototypes with types only...
+       | 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 ']'
+      {
+         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 '[' type ']'
+      {
+         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);
+         $$ = MkDeclaratorEnumArray(decl, $3);
+      }
+       | base_strict_type '[' ']'
+      {
+         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);
+         $$ = MkDeclaratorEnumArray(decl, 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); }
@@ -2728,12 +2822,73 @@ direct_declarator_function_error:
 direct_declarator:
      direct_declarator_function
    | direct_declarator_nofunction
-   | ext_decl direct_declarator_function
+   ;
+
+
+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
+   | ext_decl direct_declarator_nofunction_type_ok
       { $$ = MkDeclaratorExtended($1, $2); }
+*/
    ;
-
 /*
 asm_start:
     ASM '(' STRING_LITERAL { $<string>$ = CopyString(yytext); } STRING_LITERAL { $<string>$ = CopyString(yytext); }
@@ -2776,6 +2931,7 @@ ext_decl:
 
 ext_decl:
      EXT_DECL { $$ = MkExtDeclString(CopyString(yytext)); }
+   | EXT_STORAGE  { $$ = MkExtDeclString(CopyString(yytext)); }
    | attrib { $$ = MkExtDeclAttrib($1); }
    | ASM '(' string_literal ')'
       {
@@ -2820,53 +2976,33 @@ attrib:
    ;
 
 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:
@@ -2881,7 +3017,6 @@ 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 pointer direct_abstract_declarator { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
        ;
 
@@ -2890,8 +3025,7 @@ 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 pointer direct_abstract_declarator_noarray { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
        ;
 
 declarator:
@@ -2902,12 +3036,23 @@ 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 pointer direct_declarator_function { $$ = MkDeclaratorExtended($1, MkDeclaratorPointer($2, $3)); }
        | pointer ext_decl direct_declarator_function { $$ = MkDeclaratorPointer($1, MkDeclaratorExtended($2, $3)); }
    ;
@@ -2915,17 +3060,29 @@ 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 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 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 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 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 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:
@@ -3002,6 +3159,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; }
        ;
 
@@ -3016,7 +3174,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;
+      $$ = MkList();
+      ListAdd($$, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(s)), null));
+      ListAdd($$, $3);
+      FreeSpecifier($1);
+   }
    | init_declarator_list_error ',' init_declarator   { $$ = $1; ListAdd($1, $3); }
+   /*| base_strict_type ',' init_declarator
+      {
+         $$ = MkList();
+         ListAdd($1, $3);
+      }*/
        ;
 
 init_declarator_list_error:
@@ -3038,11 +3212,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); }
 /*
@@ -3062,7 +3236,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); }
        ;
 
@@ -3246,10 +3420,10 @@ statement_list_error:
      statement_error                   { $$ = MkList(); ListAdd($$, $1); }
    | statement_list statement_error          { $$ = $1; ListAdd($1, $2); }
    | statement_list_error statement_error          { $$ = $1; ListAdd($1, $2); }
-   | statement_list declaration              { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; yyerror(); $$ = $1; ListAdd($1, stmt); /*declMode = defaultDeclMode;*/ }
-   | statement_list_error declaration        { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; yyerror(); $$ = $1; ListAdd($1, stmt); /*declMode = defaultDeclMode;*/ }
-   | statement_list declaration_error        { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; yyerror(); $$ = $1; ListAdd($1, stmt); /*declMode = defaultDeclMode;*/ }
-   | statement_list_error declaration_error  { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; yyerror(); $$ = $1; ListAdd($1, stmt); /*declMode = defaultDeclMode;*/ }
+   | statement_list declaration              { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; Compiler_Warning(C89_DECL_WARNING); $$ = $1; ListAdd($1, stmt); /*declMode = defaultDeclMode;*/ }
+   | statement_list_error declaration        { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; Compiler_Warning(C89_DECL_WARNING); $$ = $1; ListAdd($1, stmt); /*declMode = defaultDeclMode;*/ }
+   | statement_list declaration_error        { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; Compiler_Warning(C89_DECL_WARNING); $$ = $1; ListAdd($1, stmt); /*declMode = defaultDeclMode;*/ }
+   | statement_list_error declaration_error  { Statement stmt = MkBadDeclStmt($2); stmt.loc = @2; Compiler_Warning(C89_DECL_WARNING); $$ = $1; ListAdd($1, stmt); /*declMode = defaultDeclMode;*/ }
    ;
 
 compound_inside:
@@ -3380,7 +3554,10 @@ jump_statement_error:
 
 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                       
+       | 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 = @$; }
@@ -3389,6 +3566,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; }
    ;