home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
ML
/
PARSE2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-16
|
6KB
|
305 lines
/*
* 関数の管理
*
* 1994.5.22 T.Koabayashi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "parse.h"
#include "err.h"
#include "inlib.h"
static void ParseArray( void );
/* 構文解析処理 */
void ParseFunction( ident )
int ident ;
{
int args ;
GetToken();
if ( Input.token == SYM_OPEN1 )
{
GetToken();
args = 0 ;
if ( Input.token != SYM_CLOSE1 )
{
args = 1 ;
ParseExpression();
while( Input.token != SYM_CLOSE1 )
{
if ( Input.token != SYM_COMMA )
{
ParseError( " , または ) が必要です。" );
break ;
}
args ++ ;
GetToken();
ParseExpression();
}
}
GetToken();
CodeSetInt( args );
CodeSetIdent( IDENT_FUNC, ident );
}
else
{
DataStruct data ;
data.type = TYPE_FUNC ;
data.funcd.ident = ident ;
CodeSetConst( &data );
}
}
/* 関数定義の構文解析 */
void ParseDefineFunction( code )
CodeSentense *code ;
{
int args, ident ;
CodeConst *vars ;
FuncBuffer *func ;
code->stype = SENT_DEF_FUNC ;
/* 関数名の設定 */
GetToken();
if ( Input.token == SYM_PRIVATE ) {
GetToken();
ident = IdentSearch( IdentFunction, Input.str );
if (ident < 0) {
ident = IdentAppend( IdentFunction, Input.str, IDENT_PRIVATE|IDENT_FUNC );
ClassList[0].func[ident].type = FUNC_NO;
}
} else {
ident = IdentSearch( IdentFunction, Input.str );
if (ident < 0) {
ident = IdentAppend( IdentFunction, Input.str, IDENT_FUNC );
ClassList[0].func[ident].type = FUNC_NO;
}
}
func = ClassList[0].func + ident ;
GetToken();
if ( Input.token == SYM_SEMCLN ) {
return;
}
if (func->type != FUNC_NO) {
ParseError( "関数 %s が二重定義されています。", IdentFunction->name[ident] );
}
func->type = FUNC_USR ;
func->name = IdentFunction->name[ident] ;
func->ptr = CodeNextPtr();
/* ローカル変数の初期化 */
IdentLocalVar = IdentAlloc( MAX_LOCAL_VAR, 0 );
if ( Input.token != SYM_OPEN1 )
ParseError( " ( が必要です。" );
GetToken();
if ( Input.token != SYM_CLOSE1 )
{
args = 1 ;
IdentAppend( IdentLocalVar, Input.str, IDENT_LOCAL );
GetToken();
while( Input.token != SYM_CLOSE1 )
{
if ( Input.token != SYM_COMMA )
{
ParseError( " , または ) が必要です。" );
break ;
}
args ++ ;
GetToken();
IdentAppend( IdentLocalVar, Input.str, IDENT_LOCAL );
GetToken();
}
}
else
args = 0 ;
CodeSetInt( args );
vars = CodeSetInt( 0 );
/* 関数本体の解析 */
GetToken();
ParseSentense();
/* ローカル変数の解放 */
vars->data.id.i = IdentLocalVar->count ;
IdentFree( IdentLocalVar );
IdentLocalVar = NULL ;
}
/*
* return 文の構文解析
*/
void ParseReturn( code )
CodeSentense *code ;
{
code->stype = SENT_RETURN ;
GetToken();
if ( Input.token == SYM_SEMCLN )
{
DataStruct c ;
c.type = TYPE_NOASN ;
CodeSetConst( &c );
}
else
{
ParseExpression();
}
CodeSetOperator( OPE_EXP_END );
if ( Input.token != SYM_SEMCLN )
ParseError( " ; が必要です。" );
else
GetToken();
}
/*
* 変数宣言文の解析
*/
void ParseVar( code, sw )
CodeSentense *code ;
int sw ; /* 1:global 0:local */
{
int ident ;
char name[IDENT_CHARS] ;
int flag ;
flag = ( sw ) ? IDENT_GLOBAL : IDENT_LOCAL ;
code->stype = SENT_VAR ;
do
{
GetToken();
while ( Input.token == SYM_PRIVATE || Input.token == SYM_CONST )
{
if ( Input.token == SYM_PRIVATE )
flag |= IDENT_PRIVATE ;
else
flag |= IDENT_CONST ;
GetToken();
}
if ( Input.token == SYM_IDENT )
{
strcpy( name, Input.str );
GetToken();
if ( sw )
{
ident = IdentAppend( IdentGlobalVar, name, flag );
}
else
{
ident = IdentAppend( IdentLocalVar, name, flag );
}
if ( Input.token == SYM_OPEN3 )
{
flag |= IDENT_ARY ;
CodeSetIdent( flag, ident );
ParseArray();
}
else if ( Input.token == SYM_ASSIGN )
{
CodeSetIdent( flag, ident );
GetToken();
ParseExpression();
CodeSetOperator( OPE_EXP_END );
}
}
else
{
ParseError( "識別子が必要です" );
break ;
}
}
while( Input.token == SYM_COMMA );
if ( Input.token != SYM_SEMCLN )
ParseError( ";が必要です" );
else
GetToken();
CodeSetOperator( OPE_EXP_END );
}
/* 配列変数の解析 */
static void ParseArray()
{
int n ;
n = 0 ;
while( Input.token == SYM_OPEN3 )
{
GetToken();
ParseExpression();
if ( Input.token != SYM_CLOSE3 )
{
ParseError( " ] が必要です" );
break ;
}
n ++ ;
GetToken();
}
CodeSetInt( n ); /* 次数 */
CodeSetOperator( OPE_EXP_END );
return ;
}
void ParseGlobalVar( ident )
int ident ;
{
CodeIdent *code ;
code = CodeSetIdent( IDENT_GLOBAL, ident );
GetToken();
if ( Input.token == SYM_OPEN3 )
{
code->itype |= IDENT_ARY ;
ParseArray();
}
}
void ParseLocalVar( ident )
int ident ;
{
CodeIdent *code ;
code = CodeSetIdent( IDENT_LOCAL, ident );
GetToken();
if ( Input.token == SYM_OPEN3 )
{
code->itype |= IDENT_ARY ;
ParseArray();
}
}
/*
* 代入文の解析
*/
void ParseAssign( code )
CodeSentense *code ;
{
if ( Input.token < SYM_ASSIGN || SYM_ASN_DEC < Input.token )
ParseError( "代入演算子が必要です" );
code->stype = Input.token - ( SYM_ASSIGN - SENT_ASSIGN ) ;
if ( Input.token < SYM_ASN_INC )
{
GetToken();
ParseExpression();
}
else
GetToken();
if ( Input.token != SYM_SEMCLN && Input.token != SYM_CLOSE1 )
ParseError( " ; が必要です" );
GetToken();
CodeSetOperator( OPE_EXP_END );
}