home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / ML / PARSE1.C < prev    next >
C/C++ Source or Header  |  1996-02-15  |  6KB  |  335 lines

  1. /*
  2.  *    構文解析
  3.  *
  4.  *        1994.5.12    Copyright T.Kobayashi
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <assert.h>
  11.  
  12. #include "strclass.h"
  13. #include "parse.h"
  14. #include "err.h"
  15. #include "inlib.h"
  16.  
  17. int            ParseDebug ;
  18. int            TopLevel;
  19. int            MaxCodeSize = 64 * 1024 ;
  20. int            MaxGlobals = 256 ;
  21. int            MaxFunctions = 256 ;
  22.  
  23. static    void    ParseIf( CodeSentense* );
  24. static    void    ParseWhile( CodeSentense* );
  25. static    void    ParseDoWhile( CodeSentense* );
  26. static    void    ParseFor( CodeSentense* );
  27. static    void    ParseComplex( CodeSentense* );
  28. static    void    ParseBreak( CodeSentense* );
  29. static    void    ParseContinue( CodeSentense* );
  30. static    void    ParseSentenseExp( void );
  31.  
  32. /*    文の構文解析    */
  33. int        ParseSentense()
  34. {
  35.     int        ident, flag ;
  36.     CodeSentense    *code ;
  37.  
  38. #if    PDEBUG
  39.     if ( ParseDebug )
  40.     {
  41.         if ( Input.token == SYM_EOF )
  42.             printf( "EOF\n" );
  43.         else
  44.             printf( "PARSE [%s:%4d][%d:%d] %s\n",
  45.                 InputFile, InputLine,
  46.                 Input.token >> 16, Input.token & 0xFFFF, Input.str );
  47.     }
  48. #endif
  49.  
  50.     /*    ファイル終了処理    */
  51.     if ( Input.token == SYM_EOF )
  52.     {
  53. /*
  54.         FileClose();
  55.         IdentPrivate( IdentGlobalVar );
  56.         IdentPrivate( IdentFunction );
  57. */
  58.         return FALSE ;
  59.     }
  60.  
  61.     code = CodeSetSentense( InputFile, InputLine );
  62.  
  63.     switch( Input.token )
  64.     {
  65.         /*    宣言文    */
  66.         case SYM_VAR:
  67.             ParseVar( code, TopLevel );
  68.             break ;
  69.         case SYM_FUNCTION:
  70.             if ( TopLevel == FALSE )
  71.                 ParseError( "関数宣言の位置が不正です" );
  72.             TopLevel = FALSE ;
  73.             ParseDefineFunction( code );
  74.             TopLevel = TRUE ;
  75.             break ;
  76.  
  77.         /*    実行文    */
  78.         case SYM_IF:
  79.             ParseIf( code );
  80.             break ;
  81.         case SYM_WHILE:
  82.             ParseWhile( code );
  83.             break ;
  84.         case SYM_DO:
  85.             ParseDoWhile( code );
  86.             break ;
  87.         case SYM_FOR:
  88.             ParseFor( code );
  89.             break ;
  90.         case SYM_BREAK:
  91.             ParseBreak( code );
  92.             break ;
  93.         case SYM_CONTINUE:
  94.             ParseContinue( code );
  95.             break ;
  96.         case SYM_RETURN:
  97.             ParseReturn( code );
  98.             break ;
  99.         case SYM_OPEN2:        /*    複文    */
  100.             ParseComplex( code );
  101.             break ;
  102.         case SYM_IDENT:        /*    代入または式    */
  103.             if ( ( ident = IdentSearch( IdentLocalVar, Input.str ) ) >= 0 )
  104.             {
  105.                 ParseLocalVar( ident );
  106.                 flag = IdentFlag( IdentLocalVar, ident );
  107.                 if ( flag & IDENT_CONST )
  108.                     ParseError( "局所定数 %s に代入しようとしました。", IdentLocalVar->name[ident] );
  109.                 ParseAssign( code );
  110.             }
  111.             else if ( ( ident = IdentSearch( IdentGlobalVar, Input.str ) ) >= 0 )
  112.             {
  113.                 ParseGlobalVar( ident );
  114.                 flag = IdentFlag( IdentGlobalVar, ident );
  115.                 if ( flag & IDENT_CONST )
  116.                     ParseError( "大域定数 %s に代入しようとしました。", IdentGlobalVar->name[ident] );
  117.                 ParseAssign( code );
  118.             }
  119.             else
  120.             {
  121.                 code->stype = SENT_EXPRESS ;
  122.                 ParseSentenseExp();
  123.                 break ;
  124.             }
  125.             if ( flag & IDENT_CONST )
  126.                 ParseError( "定数に代入しようとしました。");
  127.             break ;
  128.         case SYM_SEMCLN:    /*    空文    */
  129.             code->stype = SENT_NULL ;
  130.             GetToken();
  131.             break ;
  132.  
  133.         default:
  134.             code->stype = SENT_EXPRESS ;
  135.             ParseSentenseExp();
  136.     }
  137.     code->next = CodeNextPtr();
  138.     return TRUE ;
  139. }
  140.  
  141. /*
  142.  *        if 文の構文解析
  143.  */
  144. static    void    ParseIf( code )
  145. CodeSentense    *code ;
  146. {
  147.     GetToken();
  148.     if ( Input.token != SYM_OPEN1 )
  149.         ParseError( " ( が必要です。" );
  150.     else
  151.         GetToken();
  152.  
  153.     /*    条件式    */
  154.     ParseExpression();
  155.     CodeSetOperator( OPE_EXP_END );
  156.     if ( Input.token != SYM_CLOSE1 )
  157.         ParseError( " ) が必要です。" );
  158.     else
  159.         GetToken();
  160.  
  161.     /*    文    */
  162.     ParseSentense();
  163.  
  164.     /*    else    */
  165.     if ( Input.token == SYM_ELSE )
  166.     {
  167.         code->stype = SENT_IF_ELSE ;
  168.         GetToken();
  169.         ParseSentense();
  170.     }
  171.     else
  172.         code->stype = SENT_IF ;
  173. }
  174.  
  175. /*
  176.  *        while 文の構文解析
  177.  */
  178. static    void    ParseWhile( code )
  179. CodeSentense    *code ;
  180. {
  181.     code->stype = SENT_WHILE ;
  182.  
  183.     GetToken();
  184.     if ( Input.token != SYM_OPEN1 )
  185.         ParseError( " ( が必要です。" );
  186.     GetToken();
  187.  
  188.     /*    条件式    */
  189.     ParseExpression();
  190.     CodeSetOperator( OPE_EXP_END );
  191.     if ( Input.token != SYM_CLOSE1 )
  192.         ParseError( " ) が必要です。" );
  193.     GetToken();
  194.  
  195.     /*    文    */
  196.     ParseSentense();
  197. }
  198.  
  199. /*
  200.  *        do-while 文の構文解析
  201.  */
  202. static    void    ParseDoWhile( code )
  203. CodeSentense    *code ;
  204. {
  205.     CodeConst    *adr ;
  206.  
  207.     code->stype = SENT_DO ;
  208.     GetToken();
  209.  
  210.     /*    終了アドレス    */
  211.     adr = CodeSetInt( 0 );
  212.  
  213.     /*    文    */
  214.     ParseSentense();
  215.  
  216.     if ( Input.token != SYM_WHILE )
  217.         ParseError( "while が必要です。" );
  218.     GetToken();
  219.     if ( Input.token != SYM_OPEN1 )
  220.         ParseError( " ( が必要です。" );
  221.     GetToken();
  222.  
  223.     /*    条件式    */
  224.     ParseExpression();
  225.     CodeSetOperator( OPE_EXP_END );
  226.     if ( Input.token != SYM_CLOSE1 )
  227.         ParseError( " ) が必要です。" );
  228.     GetToken();
  229.     if ( Input.token != SYM_SEMCLN )
  230.         ParseError( " ; が必要です。" );
  231.     GetToken();
  232.  
  233.     adr->data.id.i = (int)CodeNextPtr();
  234. }
  235.  
  236. /*
  237.  *        for 文の構文解析
  238.  */
  239. static    void    ParseFor( code )
  240. CodeSentense    *code ;
  241. {
  242.     code->stype = SENT_FOR ;
  243.  
  244.     GetToken();
  245.     if ( Input.token != SYM_OPEN1 )
  246.         ParseError( " ( が必要です。" );
  247.     else
  248.         GetToken();
  249.  
  250.     /*    初期化文    */
  251.     ParseSentense();
  252.  
  253.     /*    条件式    */
  254.     ParseExpression();
  255.     CodeSetOperator( OPE_EXP_END );
  256.     if ( Input.token != SYM_SEMCLN )
  257.         ParseError( " ; が必要です。" );
  258.     else
  259.         GetToken();
  260.  
  261.     /*    文    */
  262.     ParseSentense();
  263.  
  264.     /*    本体    */
  265.     ParseSentense();
  266. }
  267.  
  268. /*
  269.  *        複文の構文解析
  270.  */
  271. static    void    ParseComplex( code )
  272. CodeSentense    *code ;
  273. {
  274.     CodeConst    *adr ;
  275.  
  276. #if    PDEBUG
  277.     if ( ParseDebug )
  278.         printf( "   Complex\n" );
  279. #endif
  280.  
  281.     code->stype = SENT_COMPLEX ;
  282.     GetToken();
  283.  
  284.     /*    終了アドレス    */
  285.     adr = CodeSetInt( 0 );
  286.  
  287.     while( Input.token != SYM_CLOSE2 )
  288.     {
  289.         if ( ParseSentense() == FALSE )
  290.             ParseFatal( "複文中でファイルエンドになりました" );
  291.     }
  292.     GetToken();
  293.  
  294.     adr->data.id.i = (int)CodeNextPtr();
  295. }
  296.  
  297. /*
  298.  *        break 文の構文解析
  299.  */
  300. static    void    ParseBreak( code )
  301. CodeSentense    *code ;
  302. {
  303.     code->stype = SENT_BREAK ;
  304.     GetToken();
  305.     if ( Input.token != SYM_SEMCLN )
  306.         ParseError( " ; が必要です。" );
  307.     else
  308.         GetToken();
  309. }
  310.  
  311. /*
  312.  *        continue 文の構文解析
  313.  */
  314. static    void    ParseContinue( code )
  315. CodeSentense    *code ;
  316. {
  317.     code->stype = SENT_CONTINUE ;
  318.     GetToken();
  319.     if ( Input.token != SYM_SEMCLN )
  320.         ParseError( " ; が必要です。" );
  321.     else
  322.         GetToken();
  323. }
  324.  
  325. /*    式を文に登録    */
  326. static    void    ParseSentenseExp()
  327. {
  328.     ParseExpression();
  329.     CodeSetOperator( OPE_EXP_END );
  330.     if ( Input.token != SYM_SEMCLN )
  331.         ParseError( ";が必要です。" );
  332.     GetToken();
  333. }
  334.  
  335.