private opCode ParseExpr(opCode Acc, ePriority priority) { opCode ValueLeft = null; opCode valueRight = null; do { switch (mTokenizer.type) { case eTokenType.operator_minus: // unary minus operator mTokenizer.NextToken(); ValueLeft = ParseExpr(null, ePriority.unaryminus); ValueLeft = new opCodeUnary(eTokenType.operator_minus, ValueLeft); break; // TODO: might not be correct. Was : Exit Do case eTokenType.operator_plus: // unary minus operator mTokenizer.NextToken(); break; case eTokenType.operator_not: mTokenizer.NextToken(); ValueLeft = ParseExpr(null, ePriority.not); ValueLeft = new opCodeUnary(eTokenType.operator_not, ValueLeft); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_identifier: ParseIdentifier(ref ValueLeft); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_true: ValueLeft = new opCodeImmediate(EvalType.Boolean, true); mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_false: ValueLeft = new opCodeImmediate(EvalType.Boolean, false); mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_string: ValueLeft = new opCodeImmediate(EvalType.String, mTokenizer.value.ToString()); mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_number: try { ValueLeft = new opCodeImmediate(EvalType.Number, double.Parse(mTokenizer.value.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture)); } catch (Exception) { mTokenizer.RaiseError(string.Format("Invalid number {0}", mTokenizer.value.ToString())); } mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_date: try { ValueLeft = new opCodeImmediate(EvalType.Date, mTokenizer.value.ToString()); } catch (Exception) { mTokenizer.RaiseError(string.Format("Invalid date {0}, it should be #DD/MM/YYYY hh:mm:ss#", mTokenizer.value.ToString())); } mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.open_parenthesis: mTokenizer.NextToken(); ValueLeft = ParseExpr(null, ePriority.none); if (mTokenizer.type == eTokenType.close_parenthesis) { // good we eat the end parenthesis and continue ... mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do } else { mTokenizer.RaiseUnexpectedToken("End parenthesis not found"); } break; case eTokenType.operator_if: // first check functions List<object> parameters = new List<object>(); // parameters... mTokenizer.NextToken(); bool brackets = false; parameters = ParseParameters(ref brackets); break; // TODO: might not be correct. Was : Exit Do default: break; // TODO: might not be correct. Was : Exit Do } } while (true); if (ValueLeft == null) { mTokenizer.RaiseUnexpectedToken("No Expression found"); } ParseDot(ref ValueLeft); do { eTokenType tt; tt = mTokenizer.type; switch (tt) { case eTokenType.end_of_formula: // end of line return ValueLeft; case eTokenType.value_number: mTokenizer.RaiseUnexpectedToken("Unexpected number without previous opterator"); break; case eTokenType.operator_plus: if (priority < ePriority.plusminus) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.plusminus); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_minus: if (priority < ePriority.plusminus) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.plusminus); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_concat: if (priority < ePriority.concat) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.concat); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_mul: case eTokenType.operator_div: if (priority < ePriority.muldiv) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.muldiv); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_percent: if (priority < ePriority.percent) { mTokenizer.NextToken(); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, Acc); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_or: if (priority < ePriority.or) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.or); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_and: if (priority < ePriority.and) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.and); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_ne: case eTokenType.operator_gt: case eTokenType.operator_ge: case eTokenType.operator_eq: case eTokenType.operator_le: case eTokenType.operator_lt: if (priority < ePriority.equality) { tt = mTokenizer.type; mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.equality); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; default: break; // TODO: might not be correct. Was : Exit Do break; } } while (true); return ValueLeft; }
public opCode Parse(string str) { if (str == null) str = string.Empty; mTokenizer = new tokenizer(this, str, eParserSyntax.cSharp); mTokenizer.NextToken(); opCode res = ParseExpr(null, ePriority.none); if (mTokenizer.type == eTokenType.end_of_formula) { if (res == null) res = new opCodeImmediate(EvalType.String, string.Empty); return res; } else { mTokenizer.RaiseUnexpectedToken(""); } }