home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / fed0217s.zip / source / parser.cpp < prev    next >
C/C++ Source or Header  |  2000-12-13  |  5KB  |  271 lines

  1. /*
  2. ** Module   :PARSER.CPP
  3. ** Abstract :Sintax hiliting language-specific parsers
  4. **
  5. ** Copyright (C) Sergey I. Yevtushenko
  6. **
  7. ** Log: Tue  11/03/1997       Created
  8. **      Sat  12/04/1997       Added REXX parser
  9. */
  10.  
  11. #include <string.h>
  12.  
  13. #include <fio.h>
  14. #include <parser.h>
  15. #include <version.h>
  16.  
  17. RegParser<Parser     > reg_NONE("none"  ," ~N~o hiliting ", 0);
  18. RegParser<Parser_CPP > reg_CPP ("C++"   ," ~C~++"         , HI_CPP );
  19. RegParser<Parser_REXX> reg_REXX("REXX"  ," ~R~EXX"        , HI_REXX);
  20. RegParser<Parser_MAKE> reg_MAKE("MAKE"  ," ~M~AKE"        , HI_MAKE);
  21. RegParser<Parser_ASM > reg_ASM ("ASM"   ," ~A~SM"         , HI_ASM );
  22. RegParser<Parser_HTML> reg_HTML("HTML"  ," ~H~TML"        , HI_HTML);
  23. RegParser<Parser_MAIL> reg_MAIL("MAIL"  ," MA~I~L"        , HI_MAIL);
  24. RegParser<Parser_PAS > reg_PAS ("PASCAL"," ~P~ASCAL"      , HI_PAS );
  25. RegParser<Parser_PL  > reg_PL  ("PERL"  ," P~E~RL"        , HI_PL  );
  26.  
  27. //-----------------------------------------
  28. // Class Parser
  29. //-----------------------------------------
  30.  
  31. Dictionary *Parser::pKeywords = 0;
  32. Dictionary *Parser::pParsers  = 0;
  33.  
  34. char Parser::def_tbl[256];
  35. int Parser::tbl_ready = 0;
  36.  
  37. Parser::Parser()
  38. {
  39.     if(!pKeywords)
  40.     {
  41.         pKeywords = new Dictionary(1,0,0);
  42.         for(int i = 0; keywords[i].key; i++)
  43.             pKeywords->Add(&keywords[i]);
  44.     }
  45.  
  46.     reset(0, ST_INITIAL);
  47.     preserve_case = 0;
  48.     mask = 0;
  49.  
  50.     if(!tbl_ready)
  51.     {
  52.         for(int j = 0; j < 256; j++)
  53.             def_tbl[j] = j;
  54.  
  55.         tbl_ready = 1;
  56.     }
  57.  
  58.     cvt_tbl = def_tbl;
  59. }
  60.  
  61. //-----------------------------------------
  62. // Static methods for Parser dictionary
  63. //-----------------------------------------
  64.  
  65. void Parser::RegParser(RegRecord* pReg)
  66. {
  67.     if(!pParsers)
  68.         pParsers = new Dictionary(1, 0, 0);
  69.  
  70.     pParsers->Add(pReg);
  71. }
  72.  
  73. Parser* Parser::GenParser(int key)
  74. {
  75.     if(!pParsers)
  76.         return 0;
  77.  
  78.     for(int i = 0; i < pParsers->Count(); i++)
  79.     {
  80.         RegRecord* pReg = (RegRecord*)pParsers->Get(i);
  81.  
  82.         if(pReg->iType == key)
  83.             return pReg->pGen();
  84.     }
  85.  
  86.     return 0;
  87. }
  88.  
  89. Parser* Parser::GenParser(char* key)
  90. {
  91.     if(!pParsers)
  92.         return 0;
  93.  
  94.     RegRecord* pReg = (RegRecord*)pParsers->IsIn(key, 0);
  95.  
  96.     if(pReg)
  97.         return pReg->pGen();
  98.  
  99.     return 0;
  100. }
  101.  
  102. int Parser::Count()
  103. {
  104.     if(!pParsers)
  105.         return 0;
  106.  
  107.     return pParsers->Count();
  108. }
  109.  
  110. char* Parser::Name(int iNdx, int iHint)
  111. {
  112.     if(!pParsers)
  113.         return 0;
  114.  
  115.     RegRecord* pReg = (RegRecord*)pParsers->Get(iNdx);
  116.  
  117.     if(pReg)
  118.         return (iHint) ? pReg->cHName:pReg->cName;
  119.  
  120.     return 0;
  121. }
  122.  
  123. int Parser::Type(int iNdx)
  124. {
  125.     if(!pParsers)
  126.         return 0;
  127.  
  128.     RegRecord* pReg = (RegRecord*)pParsers->Get(iNdx);
  129.  
  130.     if(pReg)
  131.         return pReg->iType;
  132.  
  133.     return 0;
  134. }
  135.  
  136. char* Parser::NameByKey(int key, int iHint)
  137. {
  138.     if(!pParsers)
  139.         return 0;
  140.  
  141.     for(int i = 0; i < pParsers->Count(); i++)
  142.     {
  143.         RegRecord* pReg = (RegRecord*)pParsers->Get(i);
  144.  
  145.         if(pReg->iType == key)
  146.             return (iHint) ? pReg->cHName:pReg->cName;
  147.     }
  148.  
  149.     return "";
  150. }
  151.  
  152. int Parser::Index(char* key)
  153. {
  154.     if(!pParsers)
  155.         return 0;
  156.  
  157.     RegRecord* pReg = (RegRecord*)pParsers->IsIn(key, 0);
  158.  
  159.     if(pReg)
  160.         return pReg->iType;
  161.  
  162.     return 0;
  163. }
  164.  
  165. int Parser::GuessType(char *name)
  166. {
  167.     char *str;
  168.     char *ptr;
  169.     int mode = 0;
  170.     char mapname[FED_MAXPATH];
  171.  
  172.     for(ptr = str = hi_map; *str;)
  173.     {
  174.         char chr;
  175.  
  176.         while(*str && *str != '\n')
  177.             str++;
  178.  
  179.         chr = *str;
  180.         *str = 0;
  181.  
  182.         //String ready, parse it
  183.         char *dots = strchr(ptr, ':');
  184.  
  185.         if(dots)
  186.         {
  187.             *dots = 0;
  188.  
  189.             while(__issp(*ptr))
  190.                 ptr++;
  191.  
  192.             mode = Index(ptr);
  193.  
  194.             *dots = ':';
  195.  
  196.             if(mode)
  197.             {
  198.                 ptr = dots + 1;
  199.                 while(*ptr)
  200.                 {
  201.                     int i = 0;
  202.  
  203.                     while(__issp(*ptr))
  204.                         ptr++;
  205.  
  206.                     for(; *ptr && *ptr != ';' && i < FED_MAXPATH; i++, ptr++)
  207.                     {
  208.                         mapname[i] = *ptr;
  209.                     }
  210.                     mapname[i] = 0;
  211.  
  212.                     if(match_name(name, mapname))
  213.                     {
  214.                         *str = chr;
  215.                         return mode;
  216.                     }
  217.  
  218.                     if(*ptr)
  219.                         ptr++;
  220.                 }
  221.             }
  222.         }
  223.  
  224.         *str = chr;
  225.  
  226.         if(*str)
  227.             str++;
  228.  
  229.         ptr = str;
  230.         mode = 0;
  231.     }
  232.  
  233.     return mode;
  234. }
  235.  
  236. //-----------------------------------------
  237. // Regular methods
  238. //-----------------------------------------
  239.  
  240. void Parser::reset(char *token, int initial_state)
  241. {
  242.     tok_len = 0;
  243.     color   = 0;
  244.     state   = initial_state;
  245.     tok     = token;
  246.     old_tok = token;
  247. }
  248.  
  249. int Parser::next_token()
  250. {
  251.     old_tok = tok;
  252.     tok_len = 0;
  253.     color = CL_DEFAULT;
  254.     char *tmp = tok;
  255.     while(*tmp)
  256.     {
  257.         tmp++;
  258.         tok_len++;
  259.     }
  260.     return tok_len;
  261. }
  262.  
  263. int Parser::is_kwd()
  264. {
  265.     Pkwd pKwd = (Pkwd) pKeywords->IsIn(tok, tok_len, preserve_case);
  266.     if(pKwd && (pKwd->mask & mask))
  267.         return 1;
  268.     return 0;
  269. }
  270.  
  271.