home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / devtools / gik2 / ewyio2eu.d2x / EWYBAPA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-04  |  15.1 KB  |  499 lines

  1. /*
  2. GIK/2 1.0.1 EWYBAPA.C 5621-432 (C) COPYRIGHT IBM CORP 1993.  ALL RIGHTS RESERVED.  LICENSED MATERIALS - PROPERTY OF IBM.
  3. */
  4. /**********************************************************************/
  5. /*                                                                    */
  6. /*                         MODULE PROLOGUE                            */
  7. /*                                                                    */
  8. /* COMPONENT NAME:   C++ CLASS BROWSER EXAMPLE                        */
  9. /*                                                                    */
  10. /* MODULE NAME:      EWYBAPA.C                                        */
  11. /*                                                                    */
  12. /* DESCRIPTIVE NAME: C++ Parser                                       */
  13. /*                                                                    */
  14. /* PURPOSE:                                                           */
  15. /*                                                                    */
  16. /*   This module contains a small parser for c++ header files         */
  17. /*                                                                    */
  18. /*   The parser should work for most c++ header files, even if not    */
  19. /*   syntactically correct.                                           */
  20. /*                                                                    */
  21. /* COPYRIGHT:        (C) 1993 IBM Corporation                         */
  22. /*                                                                    */
  23. /* DISCLAIMER OF WARRANTIES.  The following [enclosed] code is        */
  24. /* sample code created by IBM Corporation. This sample code is not    */
  25. /* part of any standard or IBM product and is provided to you solely  */
  26. /* for the purpose of assisting you in the development of your        */
  27. /* applications.  The code is provided "AS IS", without               */
  28. /* warranty of any kind.  IBM shall not be liable for any damages     */
  29. /* arising out of your use of the sample code, even if they have been */
  30. /* advised of the possibility of such damages.                        */
  31. /**********************************************************************/
  32.  
  33. #define  INCL_DOS                      /* OS/2 definitions            */
  34. #define  INCL_PM                       /* PM definitions              */
  35.  
  36. /*--------------------------------------------------------------------*/
  37. /* HEADER FILES                                                       */
  38. /*--------------------------------------------------------------------*/
  39.  
  40. #include <os2.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <ctype.h>
  45. #include <malloc.h>
  46. #include <ewyga.h>
  47. #include "ewybapa.h"
  48. #include "ewybacc.h"
  49.  
  50. /*--------------------------------------------------------------------*/
  51. /* CONSTANTS                                                          */
  52. /*--------------------------------------------------------------------*/
  53.  
  54. #define  MAX_IDENT_LEN           33
  55. #define  MAX_PARENTS             32
  56. #define  TOKEN_EOF               0
  57. #define  TOKEN_BLANK             1
  58. #define  TOKEN_CLASS             2
  59. #define  TOKEN_IDENT             3
  60. #define  TOKEN_LEFT_PARENTHESIS  4
  61. #define  TOKEN_RIGHT_PARENTHESIS 5
  62. #define  TOKEN_LEFT_BRACE        6
  63. #define  TOKEN_RIGHT_BRACE       7
  64. #define  TOKEN_SEMICOLON         8
  65. #define  TOKEN_OTHER             9
  66.  
  67. /*--------------------------------------------------------------------*/
  68. /* LOCAL VARIABLES                                                    */
  69. /*--------------------------------------------------------------------*/
  70.  
  71. static int M_nLineNumber = 1;
  72. static int       M_nNestParentheses = 0;
  73. static int       M_nNestBraces = 0;
  74. static char      M_szIdentifier[MAX_IDENT_LEN] = "";
  75. static char      M_szClassName[MAX_IDENT_LEN] = "";
  76. static char      M_szParentName[MAX_PARENTS][MAX_IDENT_LEN];
  77.  
  78. /*--------------------------------------------------------------------*/
  79. /* LOCAL FUNCTIONS                                                    */
  80. /*--------------------------------------------------------------------*/
  81.  
  82. static void ProcessFile(DHND hDiag,FILE *hFile);
  83. static void FillBuffer(char *pszBuffer,FILE *hFile,int nLen);
  84. static int GetToken(FILE *hFile);
  85. static void ReadString(int c,FILE *hFile);
  86. static void ReadBlockComment(FILE *hFile);
  87. static void ReadLineComment(FILE *hFile);
  88. static void ReadIdentifier(int c,FILE *hFile);
  89. static void ReadPreprocessor(FILE *hFile);
  90. static int IsIdentifierLetter(int c);
  91. static int IsKeyword(char *pszString);
  92.  
  93. /*--------------------------------------------------------------------*/
  94. /* CODE                                                               */
  95. /*--------------------------------------------------------------------*/
  96. /**********************************************************************/
  97. /*** parse the c++ header file                                   **   */
  98. /**********************************************************************/
  99.  
  100. void ParseFile(DHND hDiag,char *pszFile)
  101. {
  102.   FILE             *hFile;
  103.  
  104.   hFile = fopen(pszFile, "r");
  105.   if (hFile == NULL)
  106.     return ;
  107.   setvbuf(hFile, NULL, _IOFBF, 32000);
  108.   ProcessFile(hDiag, hFile);
  109.   fclose(hFile);
  110.   return ;
  111. }
  112.  
  113. /**********************************************************************/
  114. /*** read the c++ header file                                    **   */
  115. /**********************************************************************/
  116.  
  117. static void ProcessFile(DHND hDiag,FILE *hFile)
  118. {
  119.   char             *pszBuffer = NULL;
  120.   char             *pszClassParents[MAX_PARENTS];
  121.   int              nToken;
  122.   int              nNestBracesOld;
  123.   int              nParentCount;
  124.   int              p1,p2,pt,l;
  125.   int              i;
  126.   int              fSkip;
  127.  
  128.   nToken = GetToken(hFile);
  129.   while (nToken != TOKEN_EOF)
  130.   {
  131.  
  132.     /******************************************************************/
  133.     /* ** continue until we have a class **                           */
  134.     /******************************************************************/
  135.  
  136.     if (nToken != TOKEN_CLASS)
  137.       nToken = GetToken(hFile);
  138.     else
  139.     {
  140.       while (TOKEN_IDENT != (nToken = GetToken(hFile)))
  141.       {
  142.         continue;
  143.       }
  144.       strcpy(M_szClassName, M_szIdentifier);
  145.       nNestBracesOld = M_nNestBraces;
  146.       for (i = 0; i < MAX_PARENTS; i++)
  147.         pszClassParents[i] = NULL;
  148.       nParentCount = 0;
  149.       fSkip = 1;
  150.       do
  151.       {
  152.         nToken = GetToken(hFile);
  153.         if (nToken == TOKEN_IDENT)
  154.         {
  155.           strcpy(M_szParentName[nParentCount], M_szIdentifier);
  156.           pszClassParents[nParentCount] = M_szParentName[nParentCount];
  157.           nParentCount++;
  158.         }
  159.         if (nToken == TOKEN_SEMICOLON)
  160.         {
  161.           fSkip = 0;
  162.           break;
  163.         }
  164.       }  while (nToken != TOKEN_LEFT_BRACE);
  165.       p1 = ftell(hFile);
  166.       if (fSkip)
  167.       {
  168.  
  169.         /**************************************************************/
  170.         /* ** skip to } **                                            */
  171.         /**************************************************************/
  172.  
  173.         while (M_nNestBraces > nNestBracesOld)
  174.         {
  175.           while (TOKEN_RIGHT_BRACE != (nToken = GetToken(hFile)))
  176.           {
  177.             continue;
  178.           }
  179.         }
  180.         p2 = ftell(hFile)-2;
  181.         l = p2-p1+1;
  182.         pszBuffer = malloc(l+1);
  183.         memset(pszBuffer, 0, l+1);
  184.         pt = ftell(hFile);
  185.         fseek(hFile, p1, SEEK_SET);
  186.         FillBuffer(pszBuffer, hFile, l-1);
  187.         fseek(hFile, pt, SEEK_SET);
  188.       }
  189.  
  190.       /****************************************************************/
  191.       /* ** all info ready, insert class now **                       */
  192.       /****************************************************************/
  193.  
  194.       InsertClass(hDiag, M_szClassName, pszClassParents, pszBuffer);
  195.     }
  196.   }
  197. }
  198.  
  199. /**********************************************************************/
  200. /*** fill textbuffer from file                                   **   */
  201. /**********************************************************************/
  202.  
  203. static void FillBuffer(char *pszBuffer,FILE *hFile,int nLen)
  204. {
  205.   char             c;
  206.   int              i = 0;
  207.  
  208.   while (nLen > 0)
  209.   {
  210.     c = fgetc(hFile);
  211.     pszBuffer[i] = c;
  212.     if (c == '\n')
  213.       nLen = nLen-2;
  214.     else
  215.       nLen = nLen-1;
  216.     i++;
  217.   }
  218.   pszBuffer[i] = '\0';
  219.   return ;
  220. }
  221.  
  222. /**********************************************************************/
  223. /*** tokenizer                                                   **   */
  224. /**********************************************************************/
  225.  
  226. static int GetToken(FILE *hFile)
  227. {
  228.   int              c;
  229.  
  230.   c = fgetc(hFile);
  231.   while ((c == ' ') || (c == '\t'))
  232.     c = fgetc(hFile);
  233.   switch (c)
  234.   {
  235.     case '{' :
  236.       M_nNestBraces++;
  237.       return (TOKEN_LEFT_BRACE);
  238.     case '}' :
  239.       M_nNestBraces--;
  240.       return (TOKEN_RIGHT_BRACE);
  241.     case '(' :
  242.       M_nNestParentheses++;
  243.       return (TOKEN_LEFT_PARENTHESIS);
  244.     case ')' :
  245.       M_nNestParentheses--;
  246.       return (TOKEN_RIGHT_PARENTHESIS);
  247.     case ';' :
  248.       return (TOKEN_SEMICOLON);
  249.     case  EOF :
  250.       return (TOKEN_EOF);
  251.     case '\n' :
  252.       M_nLineNumber++;
  253.       return (TOKEN_BLANK);
  254.     case '#' :
  255.       ReadPreprocessor(hFile);
  256.       return (TOKEN_BLANK);
  257.     case '\'' :
  258.     case '"' :
  259.       ReadString(c, hFile);
  260.       return (TOKEN_OTHER);
  261.     case '/' :
  262.       c = fgetc(hFile);
  263.       if (c == '*')
  264.       {
  265.         ReadBlockComment(hFile);
  266.         return (TOKEN_BLANK);
  267.       }
  268.       if (c == '/')
  269.       {
  270.         ReadLineComment(hFile);
  271.         return (TOKEN_BLANK);
  272.       }
  273.       ungetc(c, hFile);
  274.       return (TOKEN_OTHER);
  275.     default  :
  276.       if (IsIdentifierLetter(c))
  277.       {
  278.         ReadIdentifier(c, hFile);
  279.         if (!strcmp(M_szIdentifier, "class"))
  280.           return (TOKEN_CLASS);
  281.         if (IsKeyword(M_szIdentifier))
  282.           return (TOKEN_OTHER);
  283.         return (TOKEN_IDENT);
  284.       }
  285.       return (TOKEN_OTHER);
  286.   }
  287.   return (TOKEN_OTHER);
  288. }
  289.  
  290. /**********************************************************************/
  291. /*** read a string                                               **   */
  292. /**********************************************************************/
  293.  
  294. static void ReadString(int c,FILE *hFile)
  295. {
  296.   int              cStop;
  297.  
  298.   cStop = c;
  299.   while (cStop != (c = fgetc(hFile)))
  300.   {
  301.     if (c == '\\')
  302.       fgetc(hFile);
  303.     if (c == EOF)
  304.       break;
  305.   }
  306.   return ;
  307. }
  308.  
  309. /**********************************************************************/
  310. /*** read a C comment                                            **   */
  311. /**********************************************************************/
  312.  
  313. static void ReadBlockComment(FILE *hFile)
  314. {
  315.   int              c;
  316.  
  317.   c = fgetc(hFile);
  318.   while (c != EOF)
  319.   {
  320.     if (c == '*')
  321.     {
  322.       c = fgetc(hFile);
  323.       if (c == '/')
  324.         return ;
  325.     }
  326.     else
  327.     {
  328.       if (c == '\n')
  329.         M_nLineNumber++;
  330.       c = fgetc(hFile);
  331.     }
  332.   }
  333.   return ;
  334. }
  335.  
  336. /**********************************************************************/
  337. /*** read a C++ comment                                          **   */
  338. /**********************************************************************/
  339.  
  340. static void ReadLineComment(FILE *hFile)
  341. {
  342.   int              c;
  343.  
  344.   c = fgetc(hFile);
  345.   while (c != EOF)
  346.   {
  347.     if (c == '\n')
  348.     {
  349.       M_nLineNumber++;
  350.       return ;
  351.     }
  352.     c = fgetc(hFile);
  353.   }
  354.   return ;
  355. }
  356.  
  357. /**********************************************************************/
  358. /*** read an identifier                                          **   */
  359. /**********************************************************************/
  360.  
  361. static void ReadIdentifier(int c,FILE *hFile)
  362. {
  363.   int              nLen = 0;
  364.  
  365.   M_szIdentifier[nLen++] = (char)c;
  366.   while (IsIdentifierLetter(c = fgetc(hFile)))
  367.   {
  368.     if (nLen > MAX_IDENT_LEN)
  369.       break;
  370.     M_szIdentifier[nLen++] = (char)c;
  371.   }
  372.   M_szIdentifier[nLen] = '\0';
  373.   ungetc(c, hFile);
  374. }
  375.  
  376. /**********************************************************************/
  377. /*** read a preprocessor statement                               **   */
  378. /**********************************************************************/
  379.  
  380. static void ReadPreprocessor(FILE *hFile)
  381. {
  382.   int              c;
  383.  
  384.   c = fgetc(hFile);
  385.   while (c != EOF)
  386.   {
  387.     if (c == '\\')
  388.     {
  389.       c = fgetc(hFile);
  390.       if (c != '\n')
  391.         continue;
  392.       M_nLineNumber++;
  393.       c = fgetc(hFile);
  394.       continue;
  395.     }
  396.     else
  397.     if (c == '\n')
  398.     {
  399.       M_nLineNumber++;
  400.       return ;
  401.     }
  402.     else
  403.     {
  404.       c = fgetc(hFile);
  405.     }
  406.   }
  407.   return ;
  408. }
  409.  
  410. /**********************************************************************/
  411. /*** check, if valid char in identifier                          **   */
  412. /**********************************************************************/
  413.  
  414. static int IsIdentifierLetter(int c)
  415. {
  416.   return (isalnum(c) || (c == '_'));
  417. }
  418.  
  419. /**********************************************************************/
  420. /*** check, if valid keyword                                     **   */
  421. /**********************************************************************/
  422.  
  423. static int IsKeyword(char *pszString)
  424. {
  425.   if (strcmp(pszString, "auto") == 0)
  426.     return 1;
  427.   if (strcmp(pszString, "char") == 0)
  428.     return 1;
  429.   if (strcmp(pszString, "class") == 0)
  430.     return 1;
  431.   if (strcmp(pszString, "const") == 0)
  432.     return 1;
  433.   if (strcmp(pszString, "double") == 0)
  434.     return 1;
  435.   if (strcmp(pszString, "enum") == 0)
  436.     return 1;
  437.   if (strcmp(pszString, "extern") == 0)
  438.     return 1;
  439.   if (strcmp(pszString, "float") == 0)
  440.     return 1;
  441.   if (strcmp(pszString, "int") == 0)
  442.     return 1;
  443.   if (strcmp(pszString, "long") == 0)
  444.     return 1;
  445.   if (strcmp(pszString, "register") == 0)
  446.     return 1;
  447.   if (strcmp(pszString, "short") == 0)
  448.     return 1;
  449.   if (strcmp(pszString, "signed") == 0)
  450.     return 1;
  451.   if (strcmp(pszString, "static") == 0)
  452.     return 1;
  453.   if (strcmp(pszString, "struct") == 0)
  454.     return 1;
  455.   if (strcmp(pszString, "union") == 0)
  456.     return 1;
  457.   if (strcmp(pszString, "unsigned") == 0)
  458.     return 1;
  459.   if (strcmp(pszString, "void") == 0)
  460.     return 1;
  461.   if (strcmp(pszString, "volatile") == 0)
  462.     return 1;
  463.   if (strcmp(pszString, "break") == 0)
  464.     return 1;
  465.   if (strcmp(pszString, "case") == 0)
  466.     return 1;
  467.   if (strcmp(pszString, "continue") == 0)
  468.     return 1;
  469.   if (strcmp(pszString, "default") == 0)
  470.     return 1;
  471.   if (strcmp(pszString, "do") == 0)
  472.     return 1;
  473.   if (strcmp(pszString, "else") == 0)
  474.     return 1;
  475.   if (strcmp(pszString, "for") == 0)
  476.     return 1;
  477.   if (strcmp(pszString, "goto") == 0)
  478.     return 1;
  479.   if (strcmp(pszString, "if") == 0)
  480.     return 1;
  481.   if (strcmp(pszString, "private") == 0)
  482.     return 1;
  483.   if (strcmp(pszString, "protected") == 0)
  484.     return 1;
  485.   if (strcmp(pszString, "public") == 0)
  486.     return 1;
  487.   if (strcmp(pszString, "return") == 0)
  488.     return 1;
  489.   if (strcmp(pszString, "sizeof") == 0)
  490.     return 1;
  491.   if (strcmp(pszString, "switch") == 0)
  492.     return 1;
  493.   if (strcmp(pszString, "typedef") == 0)
  494.     return 1;
  495.   if (strcmp(pszString, "while") == 0)
  496.     return 1;
  497.   return 0;
  498. }
  499.