home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / smc / scan.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  17.8 KB  |  629 lines

  1. /*****************************************************************************/
  2. #ifndef _SCAN_H_
  3. #define _SCAN_H_
  4. /*****************************************************************************/
  5. #ifndef _ALLOC_H_
  6. #include "alloc.h"
  7. #endif
  8. /*****************************************************************************/
  9. #ifndef _TOKENS_H_
  10. #include "tokens.h"
  11. #endif
  12. /*****************************************************************************/
  13. #ifndef _INFILE_H_
  14. #include "infile.h"
  15. #endif
  16. /*****************************************************************************/
  17. #ifndef _HASH_H_
  18. #include "hash.h"
  19. #endif
  20. /*****************************************************************************/
  21.  
  22. const   size_t      scanSaveBuffSize = 4*OS_page_size;
  23.  
  24. /*****************************************************************************
  25.  *
  26.  *  The following describes a pre-processor "macro" entry. We only allow two
  27.  *  types of macros - they must either expand to a simple identifier (or the
  28.  *  empty string as a special case) or an integer constant.
  29.  */
  30.  
  31. DEFMGMT class MacDefRec
  32. {
  33. public:
  34.  
  35.     MacDef          mdNext;
  36.     Ident           mdName;
  37.  
  38.     bool            mdIsId;             // identifier vs. constant?
  39.     bool            mdBuiltin;          // non-recursive definition?
  40.  
  41.     union
  42.     {
  43.         Ident           mdIden;
  44.         int             mdCons;
  45.     }
  46.                     mdDef;
  47. };
  48.  
  49. /*****************************************************************************
  50.  *
  51.  *  The following is used to keep track of conditional compilation state.
  52.  */
  53.  
  54. enum    preprocState
  55. {
  56.     PPS_NONE,
  57.  
  58.     PPS_IF,                             // we're in a true 'if' part
  59.     PPS_ELSE,                           // we're in any  'else' part
  60. };
  61.  
  62. enum    prepDirs
  63. {
  64.     PP_NONE,
  65.  
  66.     PP_IF,
  67.     PP_IFDEF,
  68.     PP_IFNDEF,
  69.     PP_ELSE,
  70.     PP_ENDIF,
  71.     PP_ERROR,
  72.     PP_PRAGMA,
  73.     PP_DEFINE,
  74. };
  75.  
  76. DEFMGMT class PrepListRec
  77. {
  78. public:
  79.  
  80.     PrepList            pplNext;
  81.     preprocState        pplState;
  82.     unsigned            pplLine;
  83. };
  84.  
  85. /*****************************************************************************/
  86.  
  87. DEFMGMT
  88. union Token
  89. {
  90.     tokens      tok;                    // for easy access
  91.  
  92.     // Each version of the token must start with 'tok'
  93.  
  94.     struct
  95.     {
  96.         tokens          tok;
  97.  
  98.         Ident           tokIdent;
  99.     }
  100.                 id;
  101.  
  102.     struct
  103.     {
  104.         tokens          tok;
  105.  
  106.         QualName        tokQualName;
  107.         SymDef          tokQualSym;
  108.         SymDef          tokQualScp;
  109.     }
  110.                 qualid;
  111.  
  112.     struct
  113.     {
  114.         tokens          tok;
  115.  
  116.         SymDef          tokHackSym;
  117.     }
  118.                 hackid;         // HACK!HACK!HACK!HACK!HACK!HACK!
  119.  
  120.     struct
  121.     {
  122.         tokens          tok;
  123.  
  124.         var_types       tokIntTyp;
  125.         __int32         tokIntVal;
  126.     }
  127.                 intCon;
  128.  
  129.     struct
  130.     {
  131.         tokens          tok;
  132.  
  133.         var_types       tokLngTyp;
  134.         __int64         tokLngVal;
  135.     }
  136.                 lngCon;
  137.  
  138.     struct
  139.     {
  140.         tokens          tok;
  141.  
  142.         float           tokFltVal;
  143.     }
  144.                 fltCon;
  145.  
  146.     struct
  147.     {
  148.         tokens          tok;
  149.  
  150.         double          tokDblVal;
  151.     }
  152.                 dblCon;
  153.  
  154.     struct
  155.     {
  156.         tokens          tok;
  157.  
  158.         size_t          tokStrLen   :28;
  159.         size_t          tokStrType  :3; // 0=default,1="A",2="L",3="S"
  160.         size_t          tokStrWide  :1;
  161.         stringBuff      tokStrVal;
  162.     }
  163.                 strCon;
  164.  
  165.     struct
  166.     {
  167.         tokens          tok;
  168.  
  169.         AtComment       tokAtcList;
  170.     }
  171.                 atComm;
  172. };
  173.  
  174. /*****************************************************************************/
  175.  
  176. DEFMGMT
  177. struct  scannerState;
  178.  
  179. /*****************************************************************************/
  180.  
  181. DEFMGMT
  182. class   scanner
  183. {
  184.  
  185. private:
  186.  
  187.     HashTab         scanHashKwd;
  188.     HashTab         scanHashSrc;
  189.  
  190. public:
  191.  
  192.     /*************************************************************************/
  193.     /* Overall startup and shutdown (once per session)                       */
  194.     /*************************************************************************/
  195.  
  196.     bool            scanInit(Compiler comp, HashTab hashKwd);
  197.     void            scanDone(){}
  198.  
  199.     void            scanReset();
  200.  
  201.     void            scanSetp(Parser parser)
  202.     {
  203.         scanParser = parser;
  204.     }
  205.  
  206.     /*************************************************************************/
  207.     /* Start/stop/restart scanning the specified input text                  */
  208.     /*************************************************************************/
  209.  
  210.     void            scanStart  (SymDef            sourceCSym,
  211.                                 const char      * sourceFile,
  212.                                 QueuedFile        sourceBuff,
  213.                                 const char      * sourceText,
  214.                                 HashTab           hashSrc,
  215.                                 norls_allocator * alloc);
  216.  
  217.     void            scanClose  ();
  218.  
  219.     void            scanRestart(SymDef            sourceCSym,
  220.                                 const char      * sourceFile,
  221.                                 scanPosTP         begAddr,
  222. //                              scanPosTP         endAddr,
  223.                                 unsigned          begLine,
  224. //                              unsigned          begCol,
  225.                                 norls_allocator * alloc);
  226.  
  227.     void            scanSetCpos(const char      * sourceFile,
  228.                                 unsigned          begLine)
  229.     {
  230.         scanInputFile.inputSetFileName(sourceFile);
  231.  
  232. //      scanTokColumn = begCol;
  233.         scanTokLineNo = begLine;
  234.     }
  235.  
  236.     void            scanString (const char      * sourceText,
  237.                                 norls_allocator * alloc);
  238.  
  239.     /*************************************************************************/
  240.     /* Look an arbitrary number of tokens ahead and then backtrack           */
  241.     /*************************************************************************/
  242.  
  243. private:
  244.  
  245.     bool            scanTokRecord;          // we're recording tokens for replay
  246.     BYTE    *       scanTokReplay;          // current input stream position
  247.  
  248.     tokens          scanReplayTok();
  249.  
  250. public:
  251.  
  252.     scanPosTP       scanTokMarkPos(OUT Token     REF saveTok,
  253.                                    OUT unsigned  REF saveLno);
  254.     scanPosTP       scanTokMarkPLA(OUT Token     REF saveTok,
  255.                                    OUT unsigned  REF saveLno);
  256.  
  257.     void            scanTokRewind (    scanPosTP     pos,
  258.                                        unsigned      lineNum,
  259.                                        Token *       pushTok = NULL);
  260.  
  261.     /*************************************************************************/
  262.     /* The main entry points for scanning the input                          */
  263.     /*************************************************************************/
  264.  
  265.     Token           scanTok;
  266.  
  267.     tokens          scan();
  268.  
  269.     HashTab         scanGetHash() { return scanHashSrc; }
  270.  
  271.     void            scanSuspend(OUT scannerState REF state);
  272.     void            scanResume (IN  scannerState REF state);
  273.  
  274.     void            scanSetQualID(QualName qual, SymDef sym, SymDef scp = NULL);
  275.  
  276.     /*************************************************************************/
  277.     /* Only the hashtable class uses the following tables                    */
  278.     /*************************************************************************/
  279.  
  280.     static
  281.     unsigned        scanHashValIds[256];
  282.     static
  283.     unsigned        scanHashValAll[256];
  284.  
  285.     /*************************************************************************/
  286.     /* The following buffer must be large enough for the longest identifier  */
  287.     /*************************************************************************/
  288.  
  289.     char            scannerBuff[1030];
  290.  
  291.     /*************************************************************************/
  292.     /* The private state of the scanner - compiler/allocator to use, etc.    */
  293.     /*************************************************************************/
  294.  
  295. private:
  296.  
  297.     norls_allocator*scanAlloc;
  298.  
  299.     Compiler        scanComp;
  300.     Parser          scanParser;
  301.  
  302.     /*************************************************************************/
  303.     /* Input-related members - source file, read next char, etc.             */
  304.     /*************************************************************************/
  305.  
  306.     infile          scanInputFile;
  307.  
  308.     int             readNextChar();
  309.     void            undoNextChar();
  310.     int             peekNextChar();
  311.  
  312.     int             scanNextChar();
  313.  
  314.     void            scanSkipComment();
  315.     void            scanSkipLineCmt();
  316.  
  317.     tokens          scanNumericConstant(int ch);
  318.     tokens          scanIdentifier     (int ch);
  319.  
  320.     unsigned        scanSkipWsp(unsigned ch, bool stopAtEOL = false);
  321.  
  322.     /*************************************************************************/
  323.     /* The following is used for parsing those weird @foo comment things     */
  324.     /*************************************************************************/
  325.  
  326.     ConstStr        scanCollectGUID();
  327.     bool            scanNativeType(CorNativeType *type, size_t *size);
  328.     bool            scanCollectId(bool dotOK = false);
  329.     int             scanCollectNum();
  330.  
  331.     bool            scanDoAtComment();
  332.  
  333.     /*************************************************************************/
  334.     /* The following is used to manage conditional compilation               */
  335.     /*************************************************************************/
  336.  
  337.     PrepList        scanPrepList;
  338.     PrepList        scanPrepFree;
  339.  
  340.     PrepList        scanGetPPdsc();
  341.  
  342.     void            scanPPdscPush(preprocState state);
  343.     void            scanPPdscPop();
  344.  
  345.     prepDirs        scanCheckForPrep();
  346.  
  347.     void            scanCheckEOL();
  348.  
  349.     void            scanSkipToDir(preprocState state);
  350.  
  351.     bool            scanStopAtEOL;
  352.     bool            scanInPPexpr;
  353.     bool            scanNoMacExp;
  354.     bool            scanSkipToPP;
  355.  
  356.     /*************************************************************************/
  357.     /* The following members are used to manage macros                       */
  358.     /*************************************************************************/
  359.  
  360. private:
  361.  
  362.     MacDef          scanMacros;
  363.  
  364.     MacDef          scanFindMac(Ident name);
  365.  
  366.     bool            scanIsMacro(const char *name);
  367.  
  368. #if!MGDDATA
  369.     MacDefRec       scanDefDsc;
  370. #endif
  371.  
  372. public:
  373.  
  374.     MacDef          scanDefMac(const char *name,
  375.                                const char *def, bool builtIn = false,
  376.                                                 bool chkOnly = false);
  377.     bool            scanUndMac(const char *name);
  378.  
  379.     bool            scanChkDefined();
  380.  
  381.     /*************************************************************************/
  382.     /* Members for reporting the source position of tokens                   */
  383.     /*************************************************************************/
  384.  
  385.     unsigned        scanTokLineNo;
  386. //  unsigned        scanTokColumn;
  387.  
  388.     BYTE    *       scanTokSrcPos;
  389.  
  390.     void            scanSaveLinePos();
  391.  
  392.     void            scanSkipToEOL();
  393.     prepDirs        scanNewLine(unsigned ch, bool noPrep = false);
  394.     prepDirs        scanRecordNL(bool noPrep);
  395.     void            saveSrcPos();
  396.  
  397.     SymDef          scanCompUnit;
  398.  
  399. public:
  400.  
  401.     unsigned        scanGetTokenLno()
  402.     {
  403.         if  (scanSaveLastLn != scanTokLineNo)
  404.             scanSaveLinePos();
  405.  
  406.         return  scanTokLineNo;
  407.     }
  408.  
  409.     unsigned        scanGetSourceLno()
  410.     {
  411.         return  scanTokLineNo;
  412.     }
  413.  
  414. //  unsigned        scanGetTokenCol()
  415. //  {
  416. //      return  scanTokColumn;
  417. //  }
  418.  
  419.     scanPosTP       scanGetFilePos()
  420.     {
  421.         if  (scanSaveLastLn != scanTokLineNo)
  422.             scanSaveLinePos();
  423.  
  424.         return  scanTokReplay ? scanTokReplay : scanSaveNext;
  425.     }
  426.  
  427.     scanPosTP       scanGetTokenPos(unsigned *lineNo = NULL)
  428.     {
  429.         if  (scanSaveLastLn != scanTokLineNo)
  430.             scanSaveLinePos();
  431.  
  432.         if  (lineNo)
  433.             *lineNo = scanTokLineNo;
  434.  
  435.         return    scanTokSrcPos;
  436.     }
  437.  
  438.     scanDifTP       scanGetPosDiff(scanPosTP memBpos, scanPosTP memEpos)
  439.     {
  440.         return  memEpos - memBpos;
  441.     }
  442.  
  443.     void            scanSetTokenPos(unsigned  lineNo)
  444.     {
  445.         scanTokLineNo = lineNo;
  446.     }
  447.  
  448.     void            scanSetTokenPos(SymDef    compUnit,
  449.                                     unsigned  lineNo)
  450.     {
  451.         scanCompUnit  = compUnit;
  452.         scanTokLineNo = lineNo;
  453.     }
  454.  
  455.     SymDef          scanGetCompUnit()
  456.     {
  457.         return scanCompUnit;
  458.     }
  459.  
  460. private:
  461.     unsigned        scanNestedGTcnt;
  462. public:
  463.     void            scanNestedGT(int delta)
  464.     {
  465.         scanNestedGTcnt += delta; assert((int)scanNestedGTcnt >= 0);
  466.     }
  467.  
  468.     /*************************************************************************/
  469.     /* Members for token lookahead                                           */
  470.     /*************************************************************************/
  471.  
  472. private:
  473.  
  474.     unsigned        scanLookAheadCount;
  475.     Token           scanLookAheadToken;
  476.     unsigned        scanLookAheadLineNo;
  477. //  unsigned        scanLookAheadColumn;
  478.     BYTE    *       scanSaveSN;
  479.  
  480. public:
  481.  
  482.     tokens          scanLookAhead();
  483.  
  484.     /*************************************************************************/
  485.     /* Members that are used to record token streams                         */
  486.     /*************************************************************************/
  487.  
  488. private:
  489.  
  490.     BYTE    *       scanSaveBase;
  491.     BYTE    *       scanSaveNext;
  492.     BYTE    *       scanSaveEndp;
  493.  
  494.     unsigned        scanSaveLastLn;
  495.  
  496.     void            scanSaveMoreSp(size_t need = 0);
  497.  
  498.     /*************************************************************************/
  499.     /* Members to deal with string and character literals                    */
  500.     /*************************************************************************/
  501.  
  502. private:
  503.  
  504.     unsigned        scanEscapeSeq(bool *newLnFlag);
  505.  
  506.     tokens          scanCharConstant();
  507.     tokens          scanStrgConstant(int prefixChar = 0);
  508.  
  509.     char    *       scanStrLitBuff;
  510.     size_t          scanStrLitBsiz;
  511.  
  512.     /*************************************************************************/
  513.     /* Members to construct error strings                                    */
  514.     /*************************************************************************/
  515.  
  516. private:
  517.  
  518.     char       *    scanErrStrNext;
  519.  
  520. public:
  521.  
  522.     void            scanErrNameBeg();
  523.     void            scanErrNameEnd(){}
  524.  
  525.     stringBuff      scanErrNameStrBeg();
  526.     void            scanErrNameStrAdd(stringBuff str);
  527.     void            scanErrNameStrApp(stringBuff str);
  528. #if MGDDATA
  529.     void            scanErrNameStrAdd(String     str);
  530.     void            scanErrNameStrApp(String     str);
  531. #endif
  532.     void            scanErrNameStrEnd();
  533.  
  534.     /*************************************************************************/
  535.     /* The following is used to 'swallow' definitions of symbols             */
  536.     /*************************************************************************/
  537.  
  538. private:
  539.  
  540.     void            scanSkipInit();
  541.  
  542. public:
  543.  
  544.     void            scanSkipText(tokens LT, tokens RT, tokens ET = tkNone);
  545.  
  546.     /*************************************************************************/
  547.     /* Use these methods to skip over sections of the source stream          */
  548.     /*************************************************************************/
  549.  
  550.     void            scanSkipSect(unsigned tokDist, unsigned linDif = 0)
  551.     {
  552.         scanTokReplay = scanTokSrcPos + tokDist;
  553.         scanTokLineNo = scanSaveLastLn = scanTokLineNo + linDif;
  554.  
  555.         scanReplayTok();
  556.     }
  557.  
  558.     /*************************************************************************/
  559.     /* Members that implement miscellaneous query functionality              */
  560.     /*************************************************************************/
  561.  
  562. public:
  563.  
  564.     Ident           tokenToIdent(tokens tok)
  565.     {
  566.         return  scanHashKwd->tokenToIdent(tok);
  567.     }
  568.  
  569.     bool            tokenIsKwd(tokens tok)
  570.     {
  571.         return  (bool)(tok <= tkKwdLast);
  572.     }
  573.  
  574.     /*************************************************************************/
  575.     /* Debugging functions                                                   */
  576.     /*************************************************************************/
  577.  
  578. #ifdef  DEBUG
  579.     bool            scanDispCurToken(bool lastId, bool brief = false);
  580. #endif
  581.  
  582. };
  583.  
  584. /*****************************************************************************/
  585.  
  586. inline
  587. int                 scanner::readNextChar()
  588. {
  589.     return  scanInputFile.inputStreamRdU1();
  590. }
  591.  
  592. inline
  593. void                scanner::undoNextChar()
  594. {
  595.             scanInputFile.inputStreamUnU1();
  596. }
  597.  
  598. inline
  599. int                 scanner::peekNextChar()
  600. {
  601.     int     ch = scanInputFile.inputStreamRdU1();
  602.                  scanInputFile.inputStreamUnU1();
  603.     return  ch;
  604. }
  605.  
  606. /*****************************************************************************/
  607.  
  608. DEFMGMT
  609. struct scannerState
  610. {
  611.     SymDef          scsvCompUnit;
  612.  
  613.     Token           scsvTok;
  614.  
  615.     unsigned        scsvTokLineNo;
  616. //  unsigned        scsvTokColumn;
  617.  
  618.     unsigned        scsvNestedGTcnt;
  619.  
  620.     scanPosTP       scsvTokSrcPos;
  621.     scanPosTP       scsvTokReplay;
  622.  
  623.     bool            scsvTokRecord;
  624. };
  625.  
  626. /*****************************************************************************/
  627. #endif
  628. /*****************************************************************************/
  629.