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 >
Wrap
C/C++ Source or Header
|
1996-02-15
|
6KB
|
335 lines
/*
* 構文解析
*
* 1994.5.12 Copyright T.Kobayashi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "strclass.h"
#include "parse.h"
#include "err.h"
#include "inlib.h"
int ParseDebug ;
int TopLevel;
int MaxCodeSize = 64 * 1024 ;
int MaxGlobals = 256 ;
int MaxFunctions = 256 ;
static void ParseIf( CodeSentense* );
static void ParseWhile( CodeSentense* );
static void ParseDoWhile( CodeSentense* );
static void ParseFor( CodeSentense* );
static void ParseComplex( CodeSentense* );
static void ParseBreak( CodeSentense* );
static void ParseContinue( CodeSentense* );
static void ParseSentenseExp( void );
/* 文の構文解析 */
int ParseSentense()
{
int ident, flag ;
CodeSentense *code ;
#if PDEBUG
if ( ParseDebug )
{
if ( Input.token == SYM_EOF )
printf( "EOF\n" );
else
printf( "PARSE [%s:%4d][%d:%d] %s\n",
InputFile, InputLine,
Input.token >> 16, Input.token & 0xFFFF, Input.str );
}
#endif
/* ファイル終了処理 */
if ( Input.token == SYM_EOF )
{
/*
FileClose();
IdentPrivate( IdentGlobalVar );
IdentPrivate( IdentFunction );
*/
return FALSE ;
}
code = CodeSetSentense( InputFile, InputLine );
switch( Input.token )
{
/* 宣言文 */
case SYM_VAR:
ParseVar( code, TopLevel );
break ;
case SYM_FUNCTION:
if ( TopLevel == FALSE )
ParseError( "関数宣言の位置が不正です" );
TopLevel = FALSE ;
ParseDefineFunction( code );
TopLevel = TRUE ;
break ;
/* 実行文 */
case SYM_IF:
ParseIf( code );
break ;
case SYM_WHILE:
ParseWhile( code );
break ;
case SYM_DO:
ParseDoWhile( code );
break ;
case SYM_FOR:
ParseFor( code );
break ;
case SYM_BREAK:
ParseBreak( code );
break ;
case SYM_CONTINUE:
ParseContinue( code );
break ;
case SYM_RETURN:
ParseReturn( code );
break ;
case SYM_OPEN2: /* 複文 */
ParseComplex( code );
break ;
case SYM_IDENT: /* 代入または式 */
if ( ( ident = IdentSearch( IdentLocalVar, Input.str ) ) >= 0 )
{
ParseLocalVar( ident );
flag = IdentFlag( IdentLocalVar, ident );
if ( flag & IDENT_CONST )
ParseError( "局所定数 %s に代入しようとしました。", IdentLocalVar->name[ident] );
ParseAssign( code );
}
else if ( ( ident = IdentSearch( IdentGlobalVar, Input.str ) ) >= 0 )
{
ParseGlobalVar( ident );
flag = IdentFlag( IdentGlobalVar, ident );
if ( flag & IDENT_CONST )
ParseError( "大域定数 %s に代入しようとしました。", IdentGlobalVar->name[ident] );
ParseAssign( code );
}
else
{
code->stype = SENT_EXPRESS ;
ParseSentenseExp();
break ;
}
if ( flag & IDENT_CONST )
ParseError( "定数に代入しようとしました。");
break ;
case SYM_SEMCLN: /* 空文 */
code->stype = SENT_NULL ;
GetToken();
break ;
default:
code->stype = SENT_EXPRESS ;
ParseSentenseExp();
}
code->next = CodeNextPtr();
return TRUE ;
}
/*
* if 文の構文解析
*/
static void ParseIf( code )
CodeSentense *code ;
{
GetToken();
if ( Input.token != SYM_OPEN1 )
ParseError( " ( が必要です。" );
else
GetToken();
/* 条件式 */
ParseExpression();
CodeSetOperator( OPE_EXP_END );
if ( Input.token != SYM_CLOSE1 )
ParseError( " ) が必要です。" );
else
GetToken();
/* 文 */
ParseSentense();
/* else */
if ( Input.token == SYM_ELSE )
{
code->stype = SENT_IF_ELSE ;
GetToken();
ParseSentense();
}
else
code->stype = SENT_IF ;
}
/*
* while 文の構文解析
*/
static void ParseWhile( code )
CodeSentense *code ;
{
code->stype = SENT_WHILE ;
GetToken();
if ( Input.token != SYM_OPEN1 )
ParseError( " ( が必要です。" );
GetToken();
/* 条件式 */
ParseExpression();
CodeSetOperator( OPE_EXP_END );
if ( Input.token != SYM_CLOSE1 )
ParseError( " ) が必要です。" );
GetToken();
/* 文 */
ParseSentense();
}
/*
* do-while 文の構文解析
*/
static void ParseDoWhile( code )
CodeSentense *code ;
{
CodeConst *adr ;
code->stype = SENT_DO ;
GetToken();
/* 終了アドレス */
adr = CodeSetInt( 0 );
/* 文 */
ParseSentense();
if ( Input.token != SYM_WHILE )
ParseError( "while が必要です。" );
GetToken();
if ( Input.token != SYM_OPEN1 )
ParseError( " ( が必要です。" );
GetToken();
/* 条件式 */
ParseExpression();
CodeSetOperator( OPE_EXP_END );
if ( Input.token != SYM_CLOSE1 )
ParseError( " ) が必要です。" );
GetToken();
if ( Input.token != SYM_SEMCLN )
ParseError( " ; が必要です。" );
GetToken();
adr->data.id.i = (int)CodeNextPtr();
}
/*
* for 文の構文解析
*/
static void ParseFor( code )
CodeSentense *code ;
{
code->stype = SENT_FOR ;
GetToken();
if ( Input.token != SYM_OPEN1 )
ParseError( " ( が必要です。" );
else
GetToken();
/* 初期化文 */
ParseSentense();
/* 条件式 */
ParseExpression();
CodeSetOperator( OPE_EXP_END );
if ( Input.token != SYM_SEMCLN )
ParseError( " ; が必要です。" );
else
GetToken();
/* 文 */
ParseSentense();
/* 本体 */
ParseSentense();
}
/*
* 複文の構文解析
*/
static void ParseComplex( code )
CodeSentense *code ;
{
CodeConst *adr ;
#if PDEBUG
if ( ParseDebug )
printf( " Complex\n" );
#endif
code->stype = SENT_COMPLEX ;
GetToken();
/* 終了アドレス */
adr = CodeSetInt( 0 );
while( Input.token != SYM_CLOSE2 )
{
if ( ParseSentense() == FALSE )
ParseFatal( "複文中でファイルエンドになりました" );
}
GetToken();
adr->data.id.i = (int)CodeNextPtr();
}
/*
* break 文の構文解析
*/
static void ParseBreak( code )
CodeSentense *code ;
{
code->stype = SENT_BREAK ;
GetToken();
if ( Input.token != SYM_SEMCLN )
ParseError( " ; が必要です。" );
else
GetToken();
}
/*
* continue 文の構文解析
*/
static void ParseContinue( code )
CodeSentense *code ;
{
code->stype = SENT_CONTINUE ;
GetToken();
if ( Input.token != SYM_SEMCLN )
ParseError( " ; が必要です。" );
else
GetToken();
}
/* 式を文に登録 */
static void ParseSentenseExp()
{
ParseExpression();
CodeSetOperator( OPE_EXP_END );
if ( Input.token != SYM_SEMCLN )
ParseError( ";が必要です。" );
GetToken();
}