📄 parse.c
字号:
/* .. ERROR - NO NAME TOKEN FOUND */ if (TokenLength == 0) { ErrorCode_m = ERROR_operand; return DEFAULT_RETURN; } /* .. ERROR - NAME TOKEN TOO LONG */ if (TokenLength >= MAXTOKENLENGTH ) { ErrorCode_m = ERROR_variable_long; return DEFAULT_RETURN; } /* REMOVE LEADING NAME TOKEN FROM FORMULA */ CopyUppercaseString (TokenString_m, FormulaString_m, TokenLength); FormulaString_m += TokenLength; /* COMPARE TOKEN TO SPECIAL CONSTANTS */ if (!strcmp(TokenString_m,"E")) CurrentValue = M_E; else if (!strcmp(TokenString_m,"PI")) CurrentValue = M_PI; /* INTERPRET FUNCTIONS */ else if ((CurrentFunction=LookupFunction (TokenString_m)) != FUNC_err ) { /* SKIP WHITE SPACE */ SkipWhiteSpace (&FormulaString_m); /* GET VALUE -- PARENTHETICAL EXPRESSION .. */ if (*FormulaString_m=='(') { FormulaString_m++; ParenthesisLevel_m++; CurrentOperator = OP_OpenParenthesis; /* PARSE FUNCTION ARGUEMENT */ CurrentValue = ParseFormula (&CurrentOperator); /* PASS ANY ERROR BACK UP TO CALLING ROUTINE */ if ( ErrorCode_m != ERROR_none ) return DEFAULT_RETURN; /* IF NO CLOSE PARENTHESIS - RETURN ERROR */ if (CurrentOperator!=OP_CloseParenthesis) { ErrorCode_m = ERROR_openparen; return DEFAULT_RETURN; } } /* MISSING OPERAND AFTER FUNCTION NAME */ else { ErrorCode_m = ERROR_operand; return DEFAULT_RETURN; } /* EVALUATE FUNCTION */ CurrentValue = EvaluateFunction (CurrentFunction, CurrentValue); /* Test for error */ if (ErrorCode_m != ERROR_none) { return DEFAULT_RETURN; } } /* GET VALUE ... VARIABLE */ else { VariableID = GetVariableID(TokenString_m); if (VariableID==NOTFOUND) { /* CREATE VARIABLE - INITIALIZE TO ZERO */ VariableID = AssignVariable (TokenString_m, 0.0); if (VariableID == NOROOM) /* VARIABLE LIST FILLED */ { ErrorCode_m = ERROR_variable_full; return DEFAULT_RETURN; } else if (VariableID == NOHEAP ) /* HEAP FILLED */ { ErrorCode_m = ERROR_heap_full; return DEFAULT_RETURN; } } CurrentValue = VariableValues_m[VariableID]; } } /* APPLY UNARY OPERATOR TO NUMBER */ if (MinusSignPresent) CurrentValue = -CurrentValue; /* PARSE OPERATOR */ /* REMOVE LEADING WHITESPACE */ SkipWhiteSpace (&FormulaString_m); /* GET OPERATOR */ switch (*FormulaString_m) { case '+' : CurrentOperator = OP_Add; break; case '-' : CurrentOperator = OP_Subtract; break; case '*' : CurrentOperator = OP_Multiply; break; case '/' : CurrentOperator = OP_Divide; break; case '^' : CurrentOperator = OP_RaisePower; break; case ')' : CurrentOperator = OP_CloseParenthesis; break; case '=' : CurrentOperator = OP_Assignment; break; case '\0': CurrentOperator = OP_EndLine; break; default : ErrorCode_m = ERROR_operator; return DEFAULT_RETURN; } ++FormulaString_m; /* increment pointer beyond operator */ /* APPLY OPERATOR IF NO HIGHER PENDING OPERATORS */ ApplyOperator = TRUE; while (ApplyOperator) { /* CRITERIA FOR APPLYING OPERATOR */ if ( ErrorCode_m == ERROR_none ) { /* EVALUATE REPEATING ASSIGNMENT OPERATORS RIGHT TO LEFT */ if (CurrentOperator==OP_Assignment) ApplyOperator = ( CurrentOperator >= *PendingOperator ); /* ... OTHERWISE EVALUATE FROM LEFT TO RIGHT */ else ApplyOperator = ( CurrentOperator > *PendingOperator ); } else ApplyOperator = FALSE; if (ApplyOperator) { switch (CurrentOperator) { case OP_Add: CurrentValue += ParseFormula (&CurrentOperator); break; case OP_Subtract: CurrentValue -= ParseFormula (&CurrentOperator); break; case OP_Multiply : CurrentValue *= ParseFormula (&CurrentOperator); break; case OP_Divide : DivisorValue_m = ParseFormula(&CurrentOperator); if ( DivisorValue_m == 0 ) { ErrorCode_m = ERROR_division; CurrentValue = 0.0; } else CurrentValue /= DivisorValue_m; break; case OP_RaisePower: CurrentValue = pow (CurrentValue, ParseFormula (&CurrentOperator)); break; case OP_CloseParenthesis : ParenthesisLevel_m--; if ( ParenthesisLevel_m<0 ) ErrorCode_m = ERROR_closeparen; break; case OP_Assignment: if (VariableID == NOTFOUND) { /* VARIABLE EXPECTED */ ErrorCode_m = ERROR_variable_expected; return DEFAULT_RETURN; } VariableValues_m[ VariableID ] = CurrentValue = ParseFormula ( &CurrentOperator); break; } } } *PendingOperator = CurrentOperator; return (CurrentValue); }/* PULLS AND RETURNS POINTER TO FIRST TOKEN */char *_strhed (char **tadd){ char *head, *sep, *tail; tail = (*tadd); /* FIND FIRST NONBLANK CHARACTER */ while ( (*tail) && ( (*tail)==' ' || (*tail)=='\t' || (*tail)=='\n' ) ) tail++; /* FIND NEXT WHITE SPACE CHARCTER */ head = (sep = tail); while ((*sep) && (*sep)!=' ' && (*sep)!='\n' && (*sep)!='\t') sep++; /* INSERT NULL CHARACTER */ tail = sep; if (*sep) { (*sep) = 0; tail++; } /* RETURN FIRST TOKEN */ SkipWhiteSpace (&tail); *tadd = tail; return(head);}/*************************************************************************Exported Subroutines*************************************************************************/char *listvar (int VariableID, double *val) { if (VariableID>=NumberOfVariables_m) return (NULL); else { *val = VariableValues_m[VariableID]; return (VariableNames_m[VariableID]); } }char *parsemsg (int InputErrorCode) { char *msg; switch ( (errorcode_t) InputErrorCode ) { case ERROR_none: msg = ""; break; case ERROR_operand: msg = "error: invalid operand."; break; case ERROR_openparen: msg = "error: unmatched left parenthesis."; break; case ERROR_closeparen: msg = "error: unmatched right parenthesis."; break; case ERROR_operator: msg = "error: invalid operator."; break; case ERROR_division: msg = "error: division by zero."; break; case ERROR_function: msg = "error: unknown function."; break; case ERROR_variable_expected: msg = "error: variable expected."; break; case ERROR_variable_full: msg = "error: variable space full."; break; case ERROR_variable_long: msg = "error: variable name too long."; break; case ERROR_heap_full: msg = "error: heap space full."; break; case ERROR_parameter: msg = "error: function parameter is out of range."; break; default: msg = "internal error: Unknown error code."; break; } return(msg);}double evalform (char **f, int *ErrorResult) { double ValueResult; operator_t CurrentOperator; /* SET GLOBAL VARIABLES */ ErrorCode_m = ERROR_none; ParenthesisLevel_m = 0; FormulaString_m = *f; /* SET INPUT OPERATOR */ CurrentOperator = OP_BeginLine; /* CALL PARSEING ROUTINE */ ValueResult = ParseFormula (&CurrentOperator); /* SET PARAMETER OUTPUT VARIALBES */ *ErrorResult = (int ) ErrorCode_m; *f = FormulaString_m; return(ValueResult); }/* PULLS LEADING TOKEN: EVALUATES AS EXPRESSION AND RETURNS DOUBLE */double dblstrf (char **tadd) { char *f; int err; f = _strhed(tadd); return (evalform(&f, &err));}/* PULLS LEADING TOKEN: EVALUATES AS EXPRESSION AND RETURNS INT */int intstrf ( char **tadd) { return ( dblstrf (tadd) );}/* PULLS LEADING TOKEN: EVALUATES AS EXPRESSION AND RETURNS LONG */long lngstrf ( char **tadd) { return ( dblstrf (tadd) );}/* ASSIGN VALUE TO STORED VARIABLE NAME or CREATE NEW VARIABLE RETURN VARIABLE ID or ERROR CODE NOROOM IF NO LIST SPACE AVAILABLE or ERROR CODE NOHEAP IF NO HEAP SPACE AVAILABLE*/int AssignVariable ( char *NewName, double NewValue) { int VariableID; VariableID = GetVariableID (NewName); /* CREATE NEW VARIABLE */ if (VariableID == NOTFOUND) { /* IS THERE ROOM IN LIST FOR NEW VARIABLE */ if (NumberOfVariables_m >= MAXNUMBERVAR ) return (NOROOM); /* IS THERE ROOM IN HEAP FOR NEW VARIABLE NAME */ ALLOCATE(VariableNames_m[NumberOfVariables_m],char,strlen(NewName)+1)#if 0 VariableNames_m [ NumberOfVariables_m ] = (char *) calloc ( strlen(NewName)+1, sizeof(char) ); if ( VariableNames_m [ NumberOfVariables_m ] == NULL) return (NOHEAP);#endif /* STORE VARIABLE */ strcpy ( VariableNames_m [ NumberOfVariables_m ], NewName ); VariableValues_m [ NumberOfVariables_m ] = NewValue; NumberOfVariables_m++; return ( NumberOfVariables_m-1 ); } /* STORE VALUE IN EXISTING VARIABLE */ else { VariableValues_m [ VariableID ] = NewValue; return VariableID; } }BOOLEAN DoesVariableExist (char *VarName) { return GetVariableID(VarName) != NOTFOUND; }double GetVariableValue (char *VarName) { int index; return (index = GetVariableID(VarName))==NOTFOUND ? 0 : VariableValues_m[index]; }/*test*/char *ParseDebug(void) { return VariableNames_m[0]; }/*end test*/double nrand(void) { static BOOLEAN IsStored = FALSE; static double StoredValue; double FacHalfRandMax; double Factor; double RadiusSqr; double x; double y; /* Return stored value if present */ if (IsStored) { IsStored = FALSE; return StoredValue; } do { FacHalfRandMax = 1.0/(RAND_MAX >> 1); x = FacHalfRandMax*rand() - 1.0; y = FacHalfRandMax*rand() - 1.0; RadiusSqr = x*x + y*y; } while (RadiusSqr >= 1.0 || RadiusSqr == 0.0); Factor = sqrt( -2.0*log(RadiusSqr)/RadiusSqr); IsStored = TRUE; StoredValue = Factor * x; return Factor * y; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -