Exemple #1
0
        public opCode Parse(string str)
        {
            if (str == null)
            {
                str = string.Empty;
            }
            mTokenizer = new tokenizer(this, str);
            mTokenizer.NextToken();
            opCode res = ParseExpr(null /* TODO Change to default(_) if this is not a reference type */, ePriority.none);

            if (mTokenizer.type == eTokenType.end_of_formula)
            {
                if (res == null)
                {
                    res = new opCodeImmediate(EvalType.String, string.Empty);
                }
                return(res);
            }
            else
            {
                mTokenizer.RaiseUnexpectedToken();
            }

            return(res);
        }
Exemple #2
0
        private opCode ParseExpr(opCode Acc, ePriority priority)
        {
            opCode ValueLeft = null, valueRight = null;

            do
            {
                switch (mTokenizer.type)
                {
                case eTokenType.operator_minus:
                {
                    // unary minus operator
                    mTokenizer.NextToken();
                    ValueLeft = ParseExpr(null /* TODO Change to default(_) if this is not a reference type */, ePriority.unaryminus);
                    ValueLeft = new opCodeUnary(eTokenType.operator_minus, ValueLeft);
                    goto Foo;
                    break;
                }

                case eTokenType.operator_plus:
                {
                    // unary minus operator
                    mTokenizer.NextToken();
                    break;
                }

                case eTokenType.operator_not:
                {
                    mTokenizer.NextToken();
                    ValueLeft = ParseExpr(null /* TODO Change to default(_) if this is not a reference type */, ePriority.not);
                    ValueLeft = new opCodeUnary(eTokenType.operator_not, ValueLeft);
                    goto Foo;
                    break;
                }

                case eTokenType.value_identifier:
                {
                    ParseIdentifier(ref ValueLeft);
                    goto Foo;
                    break;
                }

                case eTokenType.value_true:
                {
                    ValueLeft = new opCodeImmediate(EvalType.Boolean, true);
                    mTokenizer.NextToken();
                    goto Foo;
                    break;
                }

                case eTokenType.value_false:
                {
                    ValueLeft = new opCodeImmediate(EvalType.Boolean, false);
                    mTokenizer.NextToken();
                    goto Foo;
                    break;
                }

                case eTokenType.value_string:
                {
                    ValueLeft = new opCodeImmediate(EvalType.String, mTokenizer.value.ToString());
                    mTokenizer.NextToken();
                    goto Foo;
                    break;
                }

                case eTokenType.value_number:
                {
                    try
                    {
                        ValueLeft = new opCodeImmediate(EvalType.Number, double.Parse(mTokenizer.value.ToString(), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture));
                    }
                    catch (Exception ex)
                    {
                        mTokenizer.RaiseError(string.Format("Invalid number {0}", mTokenizer.value.ToString()));
                    }

                    mTokenizer.NextToken();
                    goto Foo;
                    break;
                }

                case eTokenType.value_date:
                {
                    try
                    {
                        ValueLeft = new opCodeImmediate(EvalType.Date, mTokenizer.value.ToString());
                    }
                    catch (Exception ex)
                    {
                        mTokenizer.RaiseError(string.Format("Invalid date {0}, it should be #DD/MM/YYYY hh:mm:ss#", mTokenizer.value.ToString()));
                    }

                    mTokenizer.NextToken();
                    goto Foo;
                    break;
                }

                case eTokenType.open_parenthesis:
                {
                    mTokenizer.NextToken();
                    ValueLeft = ParseExpr(null /* TODO Change to default(_) if this is not a reference type */, ePriority.none);
                    if (mTokenizer.type == eTokenType.close_parenthesis)
                    {
                        // good we eat the end parenthesis and continue ...
                        mTokenizer.NextToken();
                        goto Foo;
                    }
                    else
                    {
                        mTokenizer.RaiseUnexpectedToken("End parenthesis not found");
                    }
                    break;
                }

                case eTokenType.operator_if:
                {
                    // first check functions
                    IList <iEvalTypedValue> parameters = new List <iEvalTypedValue>();
                    mTokenizer.NextToken();
                    bool p = false;
                    parameters = ParseParameters(ref p);
                    goto Foo;
                    break;
                }

                default:
                {
                    goto Foo;
                    break;
                }
                }
            }while (true)// parameters...
            ;
Foo:

            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
                    {
                        goto Foo1;
                    }
                    break;
                }

                case eTokenType.operator_minus:
                {
                    if (priority < ePriority.plusminus)
                    {
                        mTokenizer.NextToken();
                        valueRight = ParseExpr(ValueLeft, ePriority.plusminus);
                        ValueLeft  = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight);
                    }
                    else
                    {
                        goto Foo1;
                    }
                    break;
                }

                case eTokenType.operator_concat:
                {
                    if (priority < ePriority.concat)
                    {
                        mTokenizer.NextToken();
                        valueRight = ParseExpr(ValueLeft, ePriority.concat);
                        ValueLeft  = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight);
                    }
                    else
                    {
                        goto Foo1;
                    }
                    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
                    {
                        goto Foo1;
                    }
                    break;
                }

                case eTokenType.operator_percent:
                {
                    if (priority < ePriority.percent)
                    {
                        mTokenizer.NextToken();
                        ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, Acc);
                    }
                    else
                    {
                        goto Foo1;
                    }
                    break;
                }

                case eTokenType.operator_or:
                {
                    if (priority < ePriority.or)
                    {
                        mTokenizer.NextToken();
                        valueRight = ParseExpr(ValueLeft, ePriority.or);
                        ValueLeft  = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight);
                    }
                    else
                    {
                        goto Foo1;
                    }
                    break;
                }

                case eTokenType.operator_and:
                {
                    if (priority < ePriority.and)
                    {
                        mTokenizer.NextToken();
                        valueRight = ParseExpr(ValueLeft, ePriority.and);
                        ValueLeft  = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight);
                    }
                    else
                    {
                        goto Foo1;
                    }
                    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
                    {
                        goto Foo1;
                    }
                    break;
                }

                default:
                {
                    goto Foo1;
                    break;
                }
                }
            }while (true);
Foo1:
            return(ValueLeft);
        }