00001
00002
00003
00004
00005
00006
00007 #ifndef ONCE_FPARSER_H_
00008 #define ONCE_FPARSER_H_
00009
00010 #pragma interface
00011
00012 #include <string>
00013 #include <vector>
00014
00015 #ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT
00016 #include <iostream>
00017 #endif
00018
00019 #ifdef _MSC_VER
00020
00021
00022 #pragma warning(disable : 4661)
00023 #endif
00024
00025 namespace FPoptimizer_CodeTree { class CodeTree; }
00026
00027 template<typename Value_t>
00028 class FunctionParserBase
00029 {
00030 public:
00031 enum ParseErrorType
00032 {
00033 SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH,
00034 EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS,
00035 ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC,
00036 UNKNOWN_IDENTIFIER,
00037 NO_FUNCTION_PARSED_YET,
00038 FP_NO_ERROR
00039 };
00040
00041 typedef Value_t value_type;
00042
00043
00044 int Parse(const char* Function, const std::string& Vars,
00045 bool useDegrees = false);
00046 int Parse(const std::string& Function, const std::string& Vars,
00047 bool useDegrees = false);
00048
00049 void setDelimiterChar(char);
00050
00051 const char* ErrorMsg() const;
00052 inline ParseErrorType GetParseErrorType() const { return parseErrorType; }
00053
00054 Value_t Eval(const Value_t* Vars);
00055 inline int EvalError() const { return evalErrorType; }
00056
00057 bool AddConstant(const std::string& name, Value_t value);
00058 bool AddUnit(const std::string& name, Value_t value);
00059
00060 typedef Value_t (*FunctionPtr)(const Value_t*);
00061
00062 bool AddFunction(const std::string& name,
00063 FunctionPtr, unsigned paramsAmount);
00064 bool AddFunction(const std::string& name, FunctionParserBase&);
00065
00066 bool RemoveIdentifier(const std::string& name);
00067
00068 void Optimize();
00069
00070
00071 int ParseAndDeduceVariables(const std::string& function,
00072 int* amountOfVariablesFound = 0,
00073 bool useDegrees = false);
00074 int ParseAndDeduceVariables(const std::string& function,
00075 std::string& resultVarString,
00076 int* amountOfVariablesFound = 0,
00077 bool useDegrees = false);
00078 int ParseAndDeduceVariables(const std::string& function,
00079 std::vector<std::string>& resultVars,
00080 bool useDegrees = false);
00081
00082
00083 FunctionParserBase();
00084 ~FunctionParserBase();
00085
00086
00087
00088 FunctionParserBase(const FunctionParserBase&);
00089 FunctionParserBase& operator=(const FunctionParserBase&);
00090
00091
00092 void ForceDeepCopy();
00093
00094
00095 #ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT
00096
00097 void PrintByteCode(std::ostream& dest, bool showExpression = true) const;
00098 #endif
00099
00100
00101
00102
00103 private:
00104
00105
00106
00107
00108 char delimiterChar;
00109 ParseErrorType parseErrorType;
00110 int evalErrorType;
00111
00112 friend class FPoptimizer_CodeTree::CodeTree;
00113
00114 struct Data;
00115 Data* data;
00116
00117 bool useDegreeConversion;
00118 unsigned evalRecursionLevel;
00119 unsigned StackPtr;
00120 const char* errorLocation;
00121
00122
00123
00124
00125 void CopyOnWrite();
00126 bool CheckRecursiveLinking(const FunctionParserBase*) const;
00127 bool NameExists(const char*, unsigned);
00128 bool ParseVariables(const std::string&);
00129 int ParseFunction(const char*, bool);
00130 const char* SetErrorType(ParseErrorType, const char*);
00131
00132 void AddFunctionOpcode(unsigned);
00133 void AddImmedOpcode(Value_t v);
00134 void incStackPtr();
00135 void CompilePowi(int);
00136 bool TryCompilePowi(Value_t);
00137
00138 const char* CompileIf(const char*);
00139 const char* CompileFunctionParams(const char*, unsigned);
00140 const char* CompileElement(const char*);
00141 const char* CompilePossibleUnit(const char*);
00142 const char* CompilePow(const char*);
00143 const char* CompileUnaryMinus(const char*);
00144 const char* CompileMult(const char*);
00145 const char* CompileAddition(const char*);
00146 const char* CompileComparison(const char*);
00147 const char* CompileAnd(const char*);
00148 const char* CompileExpression(const char*);
00149 inline const char* CompileFunction(const char*, unsigned);
00150 inline const char* CompileParenthesis(const char*);
00151 inline const char* CompileLiteral(const char*);
00152 };
00153
00154 class FunctionParser: public FunctionParserBase<double> {};
00155 class FunctionParser_f: public FunctionParserBase<float> {};
00156 class FunctionParser_ld: public FunctionParserBase<long double> {};
00157 class FunctionParser_li: public FunctionParserBase<long> {};
00158
00159 #endif