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

📄 parse.c

📁 一个很好的分子动力学程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*                                                                        *//*                                                                        *//*   FORMULA PARSER                                                       *//*                                                                        *//*      USER CALLABLE ROUTINES                                            *//*                                                                        *//*        (1) double evalform  (char **f, char *err)                      *//*                                                                        *//*            returns value of expression.                                *//*                                                                        *//*            *f     ASCII string containing formula.  Returns            *//*                   pointer to end of string if formula is ok,           *//*                   otherwise points to location of error.               *//*            *err   Returns 0 if OK, >0 for error.  Use value to         *//*                   call *parsemessage for error message                 *//*                                                                        *//*        (2) char   *parsemsg (char err)                                 *//*                                                                        *//*            returns pointer to error message                            *//*                                                                        *//*            err  error value returned by evalfrom                       *//*                                                                        *//*                                                                        *//*                                                                        *//*        FORMULA SYNTAX                                                  *//*                                                                        *//*          evalform can recognize the following items                    *//*                                                                        *//*          (1) number constants                                          *//*          (2) constants "e" and "pi"                                    *//*          (3) operators + - * / ^ ( ) =                                 *//*              (unlimited number of parenthesis)                         *//*          (4) variables (up to MAXNUMBERVAR of them)                    *//*          (5) single argument functions                                 *//*              ( SIN COS TAN EXP LOG LOG10 ACOS ASIN ATAN ABS SQRT RAND) *//*                                                                        *//*        VARIABLES                                                       *//*                                                                        *//*           () names can be any length - case is irrelevant              *//*           () up to MAXNUMBERVAR variables                              *//*           () set variables with =                                      *//*                string "a = 5^2" sets variable A to 25.                 *//*           () variables used in right hand side of equation             *//*              are taken to be zero if not initialized.                  *//*           () can set multiple variables on one line.                   *//*                string "a0 = a1 = a2 = sqrt(2)" sets all three          *//*                variables to sqrt(2).                                   *//*                                                                        *//*                                                                        *//*                                                                        *//*************************************************************************Include Files*************************************************************************/#include <stdlib.h>#include <math.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include "parse.h"#include "cdhouse.h"/*************************************************************************Defines*************************************************************************/#define MAXNUMBERVAR  128#define MAXTOKENLENGTH 32#define FALSE 0#define TRUE  1#define NOTFOUND -1#define NOROOM   -2#define NOHEAP   -3#define BOOLEAN int#define DEFAULT_RETURN 0.0#ifndef M_E#define M_E        2.7182818284590452354E0#endif#ifndef M_PI#define M_PI       3.1415926535897931160E0#endif/*************************************************************************Type Definitions*************************************************************************//*  OPERATORS (IN ORDER FROM LOWEST TO HIGHEST PRECEDENCE)  */typedef enum   {   OP_EndLine,   OP_BeginLine,   OP_CloseParenthesis,   OP_OpenParenthesis,   OP_Assignment,   OP_Add,   OP_Subtract,   OP_Multiply,   OP_Divide,   OP_RaisePower   } operator_t;typedef enum   {   FUNC_err,   FUNC_sin,   FUNC_cos,   FUNC_tan,   FUNC_exp,   FUNC_log,   FUNC_log10,   FUNC_fabs,   FUNC_acos,   FUNC_asin,   FUNC_atan,   FUNC_sqrt,   FUNC_int,   FUNC_rand,   FUNC_nrand   }  function_t;typedef enum   {   ERROR_none,   ERROR_operand,   ERROR_openparen,   ERROR_closeparen,   ERROR_operator,   ERROR_division,   ERROR_function,   ERROR_variable_expected,   ERROR_variable_full,   ERROR_variable_long,   ERROR_heap_full,	ERROR_parameter   } errorcode_t;/*************************************************************************Glogal Variables*************************************************************************/extern int Debug_g;/*************************************************************************Module-Wide Variables*************************************************************************/static  char         *VariableNames_m  [MAXNUMBERVAR];static  double        VariableValues_m [MAXNUMBERVAR];static  char         *FormulaString_m;static  char         TokenString_m[MAXTOKENLENGTH];static  double       DivisorValue_m;static  int          ParenthesisLevel_m;static  errorcode_t  ErrorCode_m;static  int          NumberOfVariables_m = 0;/*************************************************************************Local Function Prototypes*************************************************************************/char       *_strhed (char **);int        GetVariableID (char *TestName);int        AssignVariable ( char *NewName, double NewValue);function_t LookupFunction (char *FunctionName);double     EvaluateFunction (function_t InputFunction, double x);static void       SkipWhiteSpace (char **f);int        GetNextTokenLength ( char *cptr );void       CopyUppercaseString            ( char *TargetString, char *SourceString, int Size );double     ParseFormula (operator_t *PendingOperator);/*************************************************************************Local Subroutines*************************************************************************//*  RETURN Variable Index CORRESPONDING TO VARIABLE NAME  */int GetVariableID (char *TestName)   {   int VariableID = NumberOfVariables_m-1;   /*  SEARCH STORED VARIABLE NAMES  */   for (VariableID=0; VariableID<NumberOfVariables_m; VariableID++)      {      if (strcmpi( VariableNames_m [ VariableID ], TestName) == 0)         /* RETURN CURRENT INDEX  */         return VariableID;      }   /*  VARIABLE NAME NOT FOUND  */   return NOTFOUND;   }function_t LookupFunction (char *FunctionName)   {   if (!strcmp(FunctionName, "SIN"  ))   return( FUNC_sin);   if (!strcmp(FunctionName, "COS"  ))   return( FUNC_cos);   if (!strcmp(FunctionName, "TAN"  ))   return( FUNC_tan);   if (!strcmp(FunctionName, "EXP"  ))   return( FUNC_exp);   if (!strcmp(FunctionName, "LOG"  ))   return( FUNC_log);   if (!strcmp(FunctionName, "LOG10"))   return( FUNC_log10);   if (!strcmp(FunctionName, "ACOS" ))   return( FUNC_acos);   if (!strcmp(FunctionName, "ASIN" ))   return( FUNC_asin);   if (!strcmp(FunctionName, "ATAN" ))   return( FUNC_atan);   if (!strcmp(FunctionName, "ABS"  ))   return( FUNC_fabs);   if (!strcmp(FunctionName, "SQRT" ))   return( FUNC_sqrt);   if (!strcmp(FunctionName, "INT"  ))   return( FUNC_int );   if (!strcmp(FunctionName, "RAND" ))   return( FUNC_rand );   if (!strcmp(FunctionName, "NRAND"))   return( FUNC_nrand);   return(FUNC_err);   }double EvaluateFunction (function_t InputFunction, double x)   {	BOOLEAN Ok;	/*  Check argument ranges  */	Ok = TRUE;	switch (InputFunction)		{		case FUNC_log:		case FUNC_log10:		case FUNC_sqrt:			if (x<=0.0)				{				Ok = FALSE; 				}			break;		case FUNC_acos:		case FUNC_asin:			if (x<-1.0 || x>=1.0)				{				Ok = FALSE;				}		}	/*  If arguments not ok, then return 0  */	if (!Ok)		{		ErrorCode_m = ERROR_parameter;		return DEFAULT_RETURN;		}	/*  Evaluate function  */   switch (InputFunction)      {      case FUNC_sin   : return sin(x);      case FUNC_cos   : return cos(x);      case FUNC_tan   : return tan(x);      case FUNC_exp   : return exp(x);      case FUNC_log   : return log(x);      case FUNC_log10 : return log10(x);      case FUNC_fabs  : return fabs(x);      case FUNC_acos  : return acos(x);      case FUNC_asin  : return asin(x);      case FUNC_atan  : return atan(x);      case FUNC_sqrt  : return sqrt(x);		case FUNC_rand  : return (x/RAND_MAX)*rand();		case FUNC_nrand : return x*nrand();      case FUNC_int   :         /* INSURES INT(-1.2) = -1, NOT -2 */         if (x<0)            return ceil(x);         else            return floor(x);      default:         printf("\nINTERNAL ERROR: unknown function sent to EvaluateFunction %i\n\n",                  InputFunction);            exit(1);            /*  DUMMY RETURN TO PREVENT COMPILER WARNING  */            return 0.0;      }   }static void SkipWhiteSpace (char **f)   {   while (**f==' ' || **f==9 || **f==10 || **f==13)      (*f)++;   }int GetNextTokenLength ( char *cptr )   {   int TokenLength;   /* FIRST CHARACTER MUST BE LETTER  */   if (        ! (  ( *cptr >= 'A' && *cptr <= 'Z' ) ||             ( *cptr >= 'a' && *cptr <= 'z' )     )      )      return 0;   /*  REMAINING CHARACTERS CAN BE LETTERS, NUMBERS OR UNDERSCORES  */   TokenLength = 1;   cptr++;   while ( isalnum(*cptr) || *cptr=='_' )      {      cptr++;      TokenLength++;      }   return TokenLength;   }void CopyUppercaseString ( char *TargetString, char *SourceString, int Size )   {   int ichar;   for (ichar=0;ichar<Size;ichar++)      TargetString[ichar] = toupper(SourceString[ichar]);   /*  ADD STRING TERMINATOR  */   TargetString[Size] = 0;   }double ParseFormula (operator_t *PendingOperator)   {   operator_t CurrentOperator;   function_t CurrentFunction;   double     CurrentValue;   BOOLEAN    MinusSignPresent;   BOOLEAN    ApplyOperator;   int        VariableID;   int        TokenLength;                              /*  PARSE VALUE  */   /*      Values can take one of 5 forms         - Parenthetical Expression         - Numeric Constant         - Function         - Variable         - Special Constant (ie e or pi )   */   /*  INITIALIZE VARIABLE ID TO NONE  */   VariableID = NOTFOUND;   /*  REMOVE OPENING WHITE SPACE   */   SkipWhiteSpace (&FormulaString_m);   /*  CHECK FOR MINUS SIGN   */   MinusSignPresent = FALSE;   if (*FormulaString_m=='-')      {      MinusSignPresent = TRUE;      FormulaString_m++;      }   /*  .. OR PLUS SIGN  */   else if (*FormulaString_m=='+')      FormulaString_m++;   /*  GET VALUE -- PARENTHETICAL EXPRESSION .. */   if ( *FormulaString_m=='(' )      {      FormulaString_m++;      ParenthesisLevel_m++;      CurrentOperator = OP_OpenParenthesis;      /*  OPERATOR SHOULD RETURN AS OP_CloseParenthesis ')'  */      CurrentValue = ParseFormula (&CurrentOperator);      if ( ErrorCode_m != ERROR_none )         return DEFAULT_RETURN;      if (CurrentOperator!=OP_CloseParenthesis)         {         ErrorCode_m = ERROR_openparen;         return DEFAULT_RETURN;         }      }   /* .. GET VALUE -- CONSTANT  */   else if   (   (FormulaString_m[0] >= '0' && FormulaString_m[0] <= '9') ||   FormulaString_m[0]=='.'   )      {#ifdef TEST      char *TempString;      TempString = _strhed (&FormulaString_m);      CurrentValue = atof (TempString);#endif      CurrentValue = strtod (FormulaString_m, &FormulaString_m);      }   /* .. GET VALUE -- NAME (EITHER FUNCTION, VARIABLE, SPECIAL CONSTANT)   */   else      {      /*  SCAN NAME TOKEN IN FORMULA  */      TokenLength = GetNextTokenLength ( FormulaString_m );

⌨️ 快捷键说明

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