⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bwb_exp.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 3 页
字号:
***************************************************************/#if ANSI_Cintexp_findop( char *expression )#elseintexp_findop( expression )   char *expression;#endif   {   register int c;                              /* character counter */   int carry_on;                                /* boolean: control while loop */   int rval;                                    /* return value */   char cbuf[ MAXSTRINGSIZE + 1 ];              /* capitalized expression */   char nbuf[ MAXSTRINGSIZE + 1 ];              /* non-capitalized expression */   int position;                                /* position in the expression */   int adv_loop;                                /* control loop to build expression */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_findop(): received <%s>", expression );   bwb_debug( bwb_ebuf );#endif   /* set return value to OP_NULL initially */   rval = OP_NULL;   /* assign local pointer to expression to begin reading */   position = 0;   /* advance to the first significant character */   adv_ws( expression, &position );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_findop(): expression after advance <%s>",      &( expression[ position ] ) );   bwb_debug( bwb_ebuf );#endif   /* we now have the first significant character and can begin parsing */   /* check the first character for an indication of a parenthetical      expression, a string constant, or a numerical constant that begins      with a digit (numerical constants beginning with a plus or minus      sign or hex/octal/binary constants will have to be detected by      exp_isnc() */   carry_on = TRUE;   switch ( expression[ position ] )      {      case '\"':                /* this should indicate a string constant */         rval = CONST_STRING;         break;      case '(':                 /* this will indicate a simple parenthetical expression */         rval = PARENTHESIS;         break;#if MULTISEG_LINES      case ':':                 /* terminate processing */#endif      case ')':			/* end of argument list? */         rval = OP_TERMINATE;         break;      case '0':                 /* these will indicate a numerical constant */      case '1':      case '2':      case '3':      case '4':      case '5':      case '6':      case '7':      case '8':      case '9':      case '.':      case '&':                 /* designator for hex or octal constant */         rval = CONST_NUMERICAL;         break;      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_findop(): rval pos 1 is <%d>", rval );   bwb_debug( bwb_ebuf );#endif   /* String constants, numerical constants, open parentheses, and      the plus and minus operators have been checked at this point;      but if the return value is still OP_NULL, other possibilities      must be checked, namely, other operators, function names, and      variable names.  The function adv_element cannot be used here      because it will stop, e.g., with certain operators and not      include them in the returned element. */   /* get a character string to be interpreted */   adv_loop = TRUE;   cbuf[ 0 ] = '\0';   nbuf[ 0 ] = '\0';   c = 0;   while ( adv_loop == TRUE )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in exp_findop() loop position <%d> char 0x%x",	 c, expression[ position ] );      bwb_debug( bwb_ebuf );#endif      switch( expression[ position ] )	 {	 case ' ':              /* whitespace */	 case '\t':	 case '\r':             /* end of line */	 case '\n':	 case '\0':             /* end of string */	 case '(':              /* parenthesis terminating function name */	    adv_loop = FALSE;	    break;	 default:	    nbuf[ c ] = cbuf[ c ] = expression[ position ];	    ++c;	    nbuf[ c ] = cbuf[ c ] = '\0';	    ++position;	    break;	 }      if ( c >= MAXSTRINGSIZE )	 {	 adv_loop = FALSE;	 }      }   bwb_strtoupper( cbuf );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_findop(): cbuf element is <%s>", cbuf );   bwb_debug( bwb_ebuf );#endif   /* check for numerical constant */   if ( rval == OP_NULL )      {      rval = exp_isnc( cbuf );      }   /* check for other operators */   if ( rval == OP_NULL )      {      rval = exp_isop( cbuf );      }   /* check for user-defined function */   if ( rval == OP_NULL )      {      rval = exp_isufn( nbuf );      }   /* check for function name */   if ( rval == OP_NULL )      {      rval = exp_isfn( nbuf );      }   /* check for a BASIC command, esp. to catch THEN or ELSE */   if ( rval == OP_NULL )      {      rval = exp_iscmd( cbuf );      }   /* last: check for variable name, and assign it if there      is not already one */   if ( rval == OP_NULL )      {      rval = exp_isvn( nbuf );      }   /* return the value assigned (or OP_ERROR if none assigned) */   if ( rval == OP_NULL )      {      return OP_ERROR;      }   else      {      return rval;      }   }/***************************************************************	FUNCTION:       exp_isnc()	DESCRIPTION:    This function reads the expression to find			if a numerical constant is present at this			point.***************************************************************/#if ANSI_Cintexp_isnc( char *expression )#elseintexp_isnc( expression )   char *expression;#endif   {   char tbuf[ MAXVARNAMESIZE + 1 ]; /* JBV */   switch( expression[ 0 ] )      {      case '0':                 /* these will indicate a numerical constant */      case '1':      case '2':      case '3':      case '4':      case '5':      case '6':      case '7':      case '8':      case '9':      case '&':                 /* indicator for hex or octal constant */         return CONST_NUMERICAL;      case '+':      case '-':         /* if the previous stack level was a numerical value or a string,            then this is certainly not one; return OP_NULL here            and let the next function call to exp_isop() determine            the (plus or minus) operator */         if (  ( CURTASK exps[ CURTASK expsc - 1 ].operation == NUMBER )            || ( CURTASK exps[ CURTASK expsc - 1 ].operation == VARIABLE )            || ( CURTASK exps[ CURTASK expsc - 1 ].operation == CONST_STRING ) )            {#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in exp_isnc(): previous function is a number or string" );            bwb_debug( bwb_ebuf );#endif            return OP_NULL;            }         /* similarly, if the previous stack level was a variable            with a numerical value (not a string), then this level            must be an operator, not a numerical constant */         if ( ( CURTASK exps[ CURTASK expsc - 1 ].operation == VARIABLE )            && ( CURTASK exps[ CURTASK expsc - 1 ].type != STRING ))            {            return OP_NULL;            }         /*--------------------------------------------------------*/         /* Check for unary minus sign added by JBV.               */         /* Could be prefixing a parenthetical expression or a     */         /* variable name.                                         */         /* But parentheses won't show up in expression (cbuf), so */         /* just check for expression and variable name lengths.   */         /*--------------------------------------------------------*/         if (expression[0] == '-')         {             if (strlen(expression) == 1) return OP_NEGATION;             exp_getvfname(&expression[1], tbuf);             if (strlen(tbuf) != 0) return OP_NEGATION;         }         /* failing these tests, the argument must be a numerical            constant preceded by a plus or minus sign */         return CONST_NUMERICAL;      default:         return OP_NULL;      }   }/***************************************************************	FUNCTION:       exp_isop()	DESCRIPTION:    This function reads the expression to find			if a logical or mathematical operation is			required at this point.        This function presupposes that a numerical constant with        affixed plus or minus sign has been ruled out.***************************************************************/#if ANSI_Cintexp_isop( char *expression )#elseintexp_isop( expression )   char *expression;#endif   {   register int c;                              /* counter */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_isop(): expression is <%s>", expression );   bwb_debug( bwb_ebuf );#endif   /* compare the initial characters of the string with the table      of operators */   for ( c = 0; c < N_OPERATORS; ++c )      {      if ( strncmp( expression, exp_ops[ c ].symbol,         (size_t) strlen( exp_ops[ c ].symbol ) ) == 0 )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in exp_isop(): match <%s>, number <%d>.",            exp_ops[ c ].symbol, c );         bwb_debug( bwb_ebuf );#endif         return exp_ops[ c ].operation;         }      }   /* search failed; return OP_NULL */   return OP_NULL;   }/***************************************************************	FUNCTION:       exp_iscmd()	DESCRIPTION:    This function reads the expression to find			if a BASIC command name is present; if so,			it returns OP_TERMINATE to terminate expression			parsing.  This is critical, for example, in			parsing a conditional following IF where THEN,			ELSE, and other BASIC commands may follow.***************************************************************/#if ANSI_Cintexp_iscmd( char *expression )#elseintexp_iscmd( expression )   char *expression;#endif   {   register int n;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_iscmd(): expression received <%s>",      expression );   bwb_debug( bwb_ebuf );#endif   /* first check for THEN or ELSE statements */   if ( strcmp( expression, CMD_THEN ) == 0 )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in exp_iscmd(): match found, <%s>",	 expression );      bwb_debug( bwb_ebuf );#endif      return OP_TERMINATE;      }#if STRUCT_CMDS   if ( strcmp( expression, CMD_TO ) == 0 )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in exp_iscmd(): match found, <%s>",	 expression );      bwb_debug( bwb_ebuf );#endif      return OP_TERMINATE;      }#endif   if ( strcmp( expression, CMD_ELSE ) == 0 )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in exp_iscmd(): match found, <%s>",	 expression );      bwb_debug( bwb_ebuf );#endif      return OP_TERMINATE;      }   /* run through the command table and search for a match */   for ( n = 0; n < COMMANDS; ++n )      {      if ( strcmp( expression, bwb_cmdtable[ n ].name ) == 0 )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in exp_iscmd(): match found, <%s>",            expression );         bwb_debug( bwb_ebuf );#endif         return OP_TERMINATE;         }#if INTENSIVE_DEBUG      else         {         sprintf( bwb_ebuf, "in exp_iscmd(): No match, <%s> and <%s>; returns %d",            expression, bwb_cmdtable[ n ].name,            strcmp( expression, bwb_cmdtable[ n ].name ) );         bwb_debug( bwb_ebuf );         }#endif      }   /* search failed, return NULL */   return OP_NULL;   }/***************************************************************        FUNCTION:   	exp_isufn()        DESCRIPTION:  	This function reads the expression to find        		if a user-defined function name is present			at this point.***************************************************************/#if ANSI_Cintexp_isufn( char *expression )#elseintexp_isufn( expression )   char *expression;#endif   {   struct fslte *f;   char tbuf[ MAXVARNAMESIZE + 1 ];   exp_getvfname( expression, tbuf );   for ( f = CURTASK fslt_start.next; f != &CURTASK fslt_end; f = f->next )      {      if ( strcmp( f->name, tbuf ) == 0 )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in exp_isufn(): found user function <%s>",            tbuf );         bwb_debug( bwb_ebuf );#endif         /* a user function name was found: but is it the local variable            name for the user function? If so, return OP_NULL and the            name will be read as a variable */         if ( var_islocal( tbuf ) != NULL )            {            return OP_NULL;            }         else            {#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in exp_isufn(): found function <%s> not a local variable, EXEC level <%d>",               tbuf, CURTASK exsc );            bwb_debug( bwb_ebuf );            getchar();#endif            return OP_USERFNC;            }         }      }   return OP_NULL;   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -