Changeset 381


Ignore:
Timestamp:
Jul 1, 2008, 9:05:38 PM (17 years ago)
Author:
cinc
Message:

Some restructuring to better fit the grammar.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/nomc/parser_c/class_parser.c

    r380 r381  
    6363  return pInterface;
    6464}
     65
     66
    6567
    6668static void registerInterface(void)
     
    124126
    125127/*
    126   Function to parse the body of an interface declaration.
     128  Function to parse the body of a class.
    127129  Current token is '{'.
    128130
    129   IB:= CV                                             // NOMCLASSVERSION()
    130      | IV                                             // NOMINSTANCEVAR()
    131      |  M                                             // Method
    132      | OV                                             // Overriden method
     131  CBODY:=
     132 
    133133 */
    134 static void parseIBody(void)
     134static void parseCBody(void)
    135135{
    136136  /* Current token is '{' */
     
    141141    PSYMBOL pCurSymbol;
    142142    GTokenValue value;
    143    
    144     //g_printf("%d: ", g_scanner_cur_line(gScanner)+pParseInfo->uiLineCorrection);
    145    
     143       
    146144    //pParseInfo->fPrintToken=TRUE;
    147145    //printToken(gScanner->token);
    148     //getNextToken();
    149146   
    150147    /* Method implementations must start with "impl" which is registered as a symbol. Here we check if
     
    186183      cleanupAndExit(1);
    187184    }
    188 
    189     //printToken(gScanner->token);
    190 
    191 //    parseMethodImplementation();
    192    // g_message("Method parsed...");
    193  //   cleanupAndExit(1);
    194 #if 0
    195     /* Typespec check must be first */
    196     if(matchNextKind(KIND_TYPESPEC)) /* Be aware that we don't compare types here */
     185  }while(g_scanner_peek_next_token(gScanner)!= G_TOKEN_EOF && g_scanner_peek_next_token(gScanner)!='}');
     186
     187}
     188
     189
     190
     191
     192/*
     193  Current token is CLASSIDENT.
     194
     195  CLASSBODY:=  '{' CBODY '}'
     196             | '{' CBODY '}' ';'
     197
     198*/
     199static void parseClassBody(void)
     200{
     201 
     202  exitIfNotMatchNext('{',  "No opening brace for class body.");
     203   
     204  parseCBody();
     205
     206  exitIfNotMatchNext('}',  "No closing of 'interface' section.");
     207   
     208  /* Remove a terminating ';' from the input if present. */
     209  matchNext(';');
     210}
     211
     212
     213/*
     214 Parse the class name. If we already encountered this class the name is registered as a
     215 symbol. IF this is the first time the name is an identifier.
     216 
     217 Note that the current token is the 'class' keyword.
     218 
     219 CLASSIDENT:=  G_TOKEN_IDENTIFIER
     220             | IDL_SYMBOL_INTERFACE
     221 */
     222static gchar* parseClassIdent(void)
     223{
     224  PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data;
     225 
     226  if(matchNext(G_TOKEN_IDENTIFIER))
     227  {
     228    /* Save interface info */
     229    GTokenValue value=gScanner->value;
     230
     231    return g_strdup(value.v_identifier);
     232  } 
     233  else
     234  {
     235    if(matchNext(G_TOKEN_SYMBOL))
     236    {
     237      /* If the interface name is a symbol, it means the interface was
     238       already registered before. Maybe because of a forward statement.
     239       We will check that in the function which called us. */
     240     
     241      /* Check if it's one of our interface symbols */
     242      PSYMBOL pCurSymbol;
     243      GTokenValue value;
     244     
     245      value=gScanner->value;
     246      pCurSymbol=value.v_symbol;
     247      if(IDL_SYMBOL_REGINTERFACE!=pCurSymbol->uiSymbolToken)
    197248      {
    198         parseMethod();
    199       }
    200     else if(matchNext(G_TOKEN_IDENTIFIER))
    201       {
    202         /* This may be an override statement */
    203         parseOverrideMethodFromIdentifier();
    204       }
    205     else if(matchNext(G_TOKEN_SYMBOL))
    206       {
    207         value=gScanner->value;
    208         pCurSymbol=value.v_symbol;
    209         switch(pCurSymbol->uiSymbolToken)
    210           {
    211           case IDL_SYMBOL_INSTANCEVAR:
    212             parseInstanceVar();
    213             break;
    214           case IDL_SYMBOL_FILESTEM:
    215             parseFileStem();
    216             break;
    217           default:
    218             {
    219               g_scanner_unexp_token(gScanner,
    220                                     G_TOKEN_SYMBOL,
    221                                     NULL,
    222                                     NULL,
    223                                     NULL,
    224                                     "Trying to parse interface body.",
    225                                     TRUE); /* is_error */
    226               cleanupAndExit(1);
    227             }
    228           }/* switch */
    229       }
    230     else
    231       {
    232         getNextToken();
     249        /* No, some other symbol */
    233250        g_scanner_unexp_token(gScanner,
    234                               G_TOKEN_IDENTIFIER,
    235                               NULL,
    236                               NULL,
    237                               NULL,
    238                               "Trying to parse interface body.",
     251                              G_TOKEN_SYMBOL,
     252                              NULL, NULL, NULL,
     253                              "Keyword 'class' is not followed by a valid identifier.",
    239254                              TRUE); /* is_error */
    240255        cleanupAndExit(1);
    241256      }
    242 #endif
    243   }while(g_scanner_peek_next_token(gScanner)!='}');
    244 
    245 }
    246 
    247 
    248 /*
    249   Parse the class name. If we already encountered this class the name is registered as a
    250   symbol. IF this is the first time the name is an identifier.
    251  
    252   Note that the current token is the 'class' keyword.
    253 
    254   CLASSIDENT:=  G_TOKEN_IDENTIFIER
    255               | IDL_SYMBOL_INTERFACE
    256  */
    257 static void parseClassIdent(GTokenType token)
    258 {
    259   PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data;
    260  
    261   if(matchNext(G_TOKEN_IDENTIFIER))
    262     {
    263       /* Save interface info */
    264       GTokenValue value=gScanner->value;
    265       pParseInfo->pCurInterface->chrName=g_strdup(value.v_identifier);
    266     }
     257
     258      /* Save interface name */
     259      return g_strdup(pCurSymbol->chrSymbolName);
     260    }
     261    else
     262    {
     263      g_scanner_unexp_token(gScanner,
     264                            G_TOKEN_IDENTIFIER,
     265                            NULL, NULL, NULL,
     266                            "Keyword 'class' must be followed by an identifier",
     267                            TRUE); /* is_error */
     268      cleanupAndExit(1);
     269    }
     270  }
     271}
     272
     273
     274static gchar* parseParentClassIdent(void)
     275{
     276  g_message("Line %d: Error in class declaration",  g_scanner_cur_line(gScanner));
     277  cleanupAndExit(0);
     278 
     279  return NULL;
     280}
     281
     282
     283static void doForwardClassDeclaration(void)
     284{
     285  PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data;
     286  PINTERFACE pif;
     287 
     288  /* Check if we already have a (maybe forward) declaration */
     289  pif=findInterfaceFromName(pParseInfo->pCurInterface->chrName);
     290  if(pif)
     291  {
     292    /* One forward declaration is enough... */
     293    g_free(pParseInfo->pCurInterface->chrName);
     294    g_free(pParseInfo->pCurInterface);
     295  }
    267296  else
    268     {
    269       if(matchNext(G_TOKEN_SYMBOL))
    270         {
    271           /* If the interface name is a symbol, it means the interface was
    272              already registered before. Maybe because of a forward statement.
    273              We will check that in the function which called us. */
    274          
    275           /* Check if it's one of our interface symbols */
    276           PSYMBOL pCurSymbol;
    277           GTokenValue value;
    278 
    279           value=gScanner->value;
    280           pCurSymbol=value.v_symbol;
    281           if(IDL_SYMBOL_REGINTERFACE!=pCurSymbol->uiSymbolToken)
    282             {
    283               //g_message("%s %d", pCurSymbol->chrSymbolName, pCurSymbol->uiKind);
    284               g_scanner_unexp_token(gScanner,
    285                                     G_TOKEN_SYMBOL,
    286                                     NULL, NULL, NULL,
    287                                     "Keyword 'interface' is not followed by a valid identifier.",
    288                                     TRUE); /* is_error */
    289               cleanupAndExit(1);
    290             }
    291           /* Save interface name */
    292           pParseInfo->pCurInterface->chrName=g_strdup(pCurSymbol->chrSymbolName);
    293         }
    294       else{
    295         g_scanner_unexp_token(gScanner,
    296                               G_TOKEN_IDENTIFIER,
    297                               NULL, NULL, NULL,
    298                               "Keyword 'interface' must be followed by an identifier",
    299                               TRUE); /* is_error */
    300         cleanupAndExit(1);
    301       }
    302     }
    303 }
    304 
    305 
    306 /*
    307   Current token is '{'.
    308 
    309   IB2:= '{' IB '}'
    310       | '{' IB '}' ';'
    311 
    312 */
    313 static void parseIFaceBody(void)
    314 {
    315  
    316   parseIBody();
    317 
    318   exitIfNotMatchNext(G_TOKEN_SYMBOL,  "No closing of 'interface' section.");
    319    
    320   /* Remove a terminating ';' from the input if present. */
    321   matchNext(';');
    322 }
    323 
     297  {
     298    pParseInfo->pCurInterface->chrSourceFileName=g_strdup(pParseInfo->chrCurrentSourceFile);
     299    pParseInfo->pCurInterface->fIsForwardDeclaration=TRUE;
     300    /* It's save to register the interface right here even if the struct is almost empty.
     301     If anything goes wrong later we will exit anyway. */
     302    registerInterface(); 
     303  }
     304}
     305
     306
     307static void doClassDeclaration(void)
     308{
     309  PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data;
     310 
     311  PINTERFACE pif;
     312  gchar *chrTemp=pParseInfo->pCurInterface->chrName;
     313 
     314  /* Check if we already have a (maybe forward) declaration */
     315  pif=findInterfaceFromName(pParseInfo->pCurInterface->chrName);
     316  if(pif)
     317  {
     318    if(pif->fIsForwardDeclaration)
     319    {
     320      /* Remove the forward declaration and insert the real thing afterwards. */
     321      deRegisterInterface(pif);
     322    }
     323    else
     324    {
     325      /* It˚s the declaration from the *.h file. Save a pointer to this information. */
     326      pParseInfo->pClassDefinition=pif;
     327      deRegisterInterface(pif);
     328    }
     329  }
     330 
     331  pParseInfo->pCurInterface->chrName=chrTemp;
     332  pParseInfo->pCurInterface->chrSourceFileName=g_strdup(pParseInfo->chrCurrentSourceFile);
     333 
     334  /* It's save to register the interface right here even if the struct is almost empty.
     335   If anything goes wrong later we will exit anyway. */
     336  registerInterface(); 
     337 
     338  /* The class definition in *.nom files does not contain all the stuff an interface may define. We use the found
     339   interface to fill the gaps. If we don˚t have an interface something went wrong and we quit. */
     340  if(!pParseInfo->pClassDefinition)
     341  {
     342    g_message("Line %d: Error during class parsing. No class definition found. MAke sure you included the *.ih file.",  g_scanner_cur_line(gScanner));
     343    cleanupAndExit(0);
     344  }
     345 
     346  pParseInfo->pCurInterface->chrParent=g_strdup(pParseInfo->pClassDefinition->chrParent);
     347 
     348  /* Note: We don˚t support subclasses yet. */
     349  if(matchNext(':'))
     350  {
     351    parseParentClassIdent();
     352  } 
     353    parseClassBody();
     354}
    324355
    325356/*
    326357  Parse a class declaration. The current token is the 'class' keyword.
    327358
    328   class:=  CLASSIDENT ';'                         // Forward declaration
    329          | CLASSIDENT ':' SUBCLASSIDENT CLASSBODY // Subclass (not used yet!)
     359  class:=  CLASSIDENT ';'                            // Forward declaration
     360         | CLASSIDENT ':' PARENTCLASSIDENT CLASSBODY // Subclass (not used yet!)
    330361         | CLASSIDENT CLASSBODY
    331362 
     
    336367  pParseInfo->pCurInterface=createInterfaceStruct();
    337368
    338   /* Get the interface name */
    339   parseClassIdent(token);
     369  /* Get the class name. */
     370  pParseInfo->pCurInterface->chrName=parseClassIdent();
    340371 
    341372   /* Check for forward declaration */
    342373  if(matchNext(';'))
    343374    {
    344       PINTERFACE pif;
    345 
    346       /* Check if we already have a (maybe forward) declaration */
    347       pif=findInterfaceFromName(pParseInfo->pCurInterface->chrName);
    348       if(pif)
    349         {
    350           g_free(pParseInfo->pCurInterface);
    351         }
    352       else
    353       {
    354         pParseInfo->pCurInterface->chrSourceFileName=g_strdup(pParseInfo->chrCurrentSourceFile);
    355         pParseInfo->pCurInterface->fIsForwardDeclaration=TRUE;
    356         /* It's save to register the interface right here even if the struct is almost empty.
    357          If anything goes wrong later we will exit anyway. */
    358         registerInterface(); 
    359       }
     375      doForwardClassDeclaration();
    360376    }
    361377  else
    362378    {
    363       PINTERFACE pif;
    364       gchar *chrTemp=pParseInfo->pCurInterface->chrName;
    365 
    366       /* Check if we already have a (maybe forward) declaration */
    367       pif=findInterfaceFromName(pParseInfo->pCurInterface->chrName);
    368       if(pif)
    369         {
    370           if(pif->fIsForwardDeclaration)
    371             {
    372               /* Remove the forward declaration and insert the real thing afterwards. */
    373               deRegisterInterface(pif);
    374             }
    375           else
    376             {
    377               pParseInfo-> pClassDefinition=pif;
    378 #if 0             
    379               /* Oops, we already have an interface declaration */
    380               g_scanner_unexp_token(gScanner, G_TOKEN_SYMBOL,
    381                                     NULL, NULL, NULL,
    382                                     "An interface with this name was already declared.",
    383                                     TRUE); /* is_error */
    384               cleanupAndExit(1);
    385 #endif             
    386             }
    387         }
    388       pParseInfo->pCurInterface->chrName=chrTemp;
    389       pParseInfo->pCurInterface->chrSourceFileName=g_strdup(pParseInfo->chrCurrentSourceFile);
    390 
    391       /* It's save to register the interface right here even if the struct is almost empty.
    392          If anything goes wrong later we will exit anyway. */
    393       //registerInterface(); 
    394 
    395       /* The class definition in *.nom files does not contain all the stuff an interface may define. We use the found
    396        interface to fill the gaps. If we don˚t have an interface something went wrong and we quit. */
    397       if(!pParseInfo->pClassDefinition)
    398       {
    399         g_message("Line %d: Error during class parsing. No class definition found. MAke sure you included the *.ih file.",  g_scanner_cur_line(gScanner));
    400         cleanupAndExit(0);
    401       }
    402       pParseInfo->pCurInterface->chrParent=g_strdup(pParseInfo->pClassDefinition->chrParent);
    403      
    404       if(matchNext(':'))
    405         {
    406           //parseSubclassedIFace();
    407           g_message("Line %d: Error in class declaration",  g_scanner_cur_line(gScanner));
    408           cleanupAndExit(0);
    409         }
    410       else if(matchNext('{'))
    411         {         
    412           parseIFaceBody();
    413         }
    414       else
    415         {
    416           g_message("Line %d: Error in class declaration",  g_scanner_cur_line(gScanner));
    417           cleanupAndExit(0);
    418         }
    419     }
     379      /* This is the real thing. */
     380      doClassDeclaration();
     381    }/* not forward declaration */
    420382 
    421383#if 0
    422   g_printf("\n");
    423   g_printf("\n");
     384  g_printf("\n\n");
    424385  /* In printdata.c */ 
    425386  printAllInterfaces();
    426   g_printf("\n");
    427   g_printf("\n");
    428  
     387  g_printf("\n\n");
    429388  printInterface(pParseInfo->pCurInterface);
    430389#endif
Note: See TracChangeset for help on using the changeset viewer.