home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
ML
/
PARSE3.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-18
|
4KB
|
189 lines
/*
* 式処理ルーチン
*
* T.Kobayashi 1993.8.6
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "parse.h"
#include "err.h"
int OrSym[] = { SYM_OR, SYM_XOR, 0 };
int AndSym[] = { SYM_AND, 0 };
int CompareSym[] = { SYM_NOTEQ, SYM_EQ, SYM_LSS, SYM_GTR, SYM_LSSEQ, SYM_GTREQ, 0 };
int ShiftSym[] = { SYM_LSFT, SYM_RSFT, 0 };
int AdderSym[] = { SYM_PLUS, SYM_MINUS, 0 };
int MultiSym[] = { SYM_MULT, SYM_DIVIDE, SYM_MOD, 0 };
int RefSym[] = { SYM_DOT, SYM_REFER, 0 };
int *Symbols[] = { OrSym, AndSym, CompareSym, ShiftSym, AdderSym, MultiSym, RefSym, NULL };
int OrOpe[] = { OPE_OR, OPE_XOR, 0 };
int AndOpe[] = { OPE_AND, 0 };
int CompareOpe[] = { OPE_NOTEQ, OPE_EQ, OPE_LSS, OPE_GTR, OPE_LSSEQ, OPE_GTREQ, 0 };
int ShiftOpe[] = { OPE_LSFT, OPE_RSFT, 0 };
int AdderOpe[] = { OPE_PLUS, OPE_MINUS, 0 };
int MultiOpe[] = { OPE_MULT, OPE_DIVIDE, OPE_MOD, 0 };
int RefOpe[] = { OPE_DOT, OPE_REFER, 0 };
int *Operators[] = { OrOpe, AndOpe, CompareOpe, ShiftOpe, AdderOpe, MultiOpe, RefOpe, NULL };
#define SYMBOLS (sizeof(Symbols)/sizeof(Symbols[0])-1)
int SymbolLevel[SYM_UNKNOWN - SYM_SPL_CHAR+1];
int OperatorTable[SYM_UNKNOWN - SYM_SPL_CHAR+1];
#define SYM_LEVEL_BEGIN SYM_SPL_CHAR
#define SYM_LEVEL_END SYM_UNKNOWN+1 /*ENDは含まない*/
static void _ParseExpression( int );
static void ParseFactor( void );
void Parse3Init(void)
{
int i, l;
for (i = 0; i < sizeof(SymbolLevel)/sizeof(SymbolLevel[0]); ++i) {
SymbolLevel[i] = -1;
OperatorTable[i] = -1;
}
for (l = 0; Symbols[l] != NULL; l++) {
for( i = 0 ; Symbols[l][i] != 0 ; i++ )
{
/*printf("level=%d, i=%d -> Symbol=%08x, Operator=%d\n", l, i, Symbols[l][i], Operators[l][i]);*/
assert(SYM_LEVEL_BEGIN <= Symbols[l][i] && Symbols[l][i] < SYM_LEVEL_END);
assert(Operators[l] != NULL);
assert(Operators[l][i] != 0);
SymbolLevel[Symbols[l][i] - SYM_LEVEL_BEGIN] = l;
OperatorTable[Symbols[l][i] - SYM_LEVEL_BEGIN] = Operators[l][i];
}
}
}
void ParseExpression()
{
_ParseExpression( 0 );
}
static void _ParseExpression( level )
int level ;
{
int i, ope ;
#if 0
if ( Symbols[level] == NULL )
{
ParseFactor();
}
#else
if ( level >= SYMBOLS)
{
ParseFactor();
}
#endif
else
{
_ParseExpression( level + 1 );
for(;;)
{
#if 0
for( i = 0 ; Symbols[level][i] != 0 ; i++ )
{
if ( Input.token == Symbols[level][i] )
{
ope = Operators[level][i] ;
break ;
}
}
if ( Symbols[level][i] == 0 )
return ;
#else
if ((Input.token & SYM_SPL_CHAR) == 0
|| SymbolLevel[Input.token - SYM_LEVEL_BEGIN] != level) {
return;
}
ope = OperatorTable[Input.token - SYM_LEVEL_BEGIN];
#endif
GetToken();
_ParseExpression( level + 1 );
CodeSetOperator( ope );
}
}
}
static void ParseFactor()
{
int ope, size ;
/* 単項演算子 */
switch( Input.token )
{
case SYM_MINUS :
ope = OPE_MINUS1 ;
break ;
case SYM_NOT:
ope = OPE_NOT ;
break ;
default :
ope = 0 ;
}
if ( ope != 0 )
{
GetToken();
ParseFactor();
CodeSetOperator( ope );
}
else if ( Input.token == SYM_CONSTDATA )
{
/* 定数 */
CodeSetConst( &(Input.data) );
GetToken();
}
else if ( Input.token == SYM_OPEN1 )
{
/* かっこ */
GetToken();
ParseExpression();
if ( Input.token == SYM_CLOSE1 )
GetToken();
else
ParseError( " ) が必要です" );
}
else if ( Input.token == SYM_OPEN2 )
{
/* 配列 */
size = 0 ;
do
{
size++ ;
GetToken();
ParseExpression();
if ( Input.token != SYM_COMMA && Input.token != SYM_CLOSE2 )
ParseError( ",または}が必要です" );
}
while( Input.token != SYM_CLOSE2 );
GetToken();
CodeSetArray( size );
}
else if ( Input.token == SYM_IDENT )
{
/* 変数、関数の処理 */
int ident ;
ident = IdentSearch( IdentLocalVar, Input.str );
if ( ( ident = IdentSearch( IdentLocalVar, Input.str ) ) >= 0 )
ParseLocalVar( ident );
else if ( ( ident = IdentSearch( IdentGlobalVar, Input.str ) ) >= 0 )
{
ParseGlobalVar( ident );
}
else if ( ( ident = IdentSearch( IdentFunction, Input.str ) ) >= 0 )
{
ParseFunction( ident );
}
else
ParseError( "識別子 %s は定義されていません", Input.str );
}
}