예제 #1
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        ///   Method of the Scanfkt: reads a constant_identifier.
        /// </summary>
        public void ScanFkt_ConstantIdentifier()
        {
            string buf  = string.Empty;
            string buf1 = string.Empty;
            ushort i;

            do
            {
                buf  = buf + this.ch;
                buf1 = buf1 + this.ch_;
                this.ScanFkt_GetCh();
            }while (((this.ch >= 'A') && (this.ch <= 'Z')) || (Constants.spezialChars.IndexOf(this.ch) >= 0));

            i = 0;
            while (i < Constants.konstante.Length)
            {
                if ((Constants.konstante[i].bez.ToLower().CompareTo(buf.ToLower()) == 0) &&
                    (!this.noUpCase || (Constants.konstante[i].bez.CompareTo(buf1) == 0)))
                {
                    this.sym        = symTyp.istKonst;
                    this.kVar       = this.ScanFkt_MakeNode(null, symTyp.istKonst, null);
                    this.kVar.Name  = Constants.konstante[i].bez;
                    this.kVar.Nr    = i;
                    this.kVar.Zwert = Constants.konstante[i].wert;
                    return;
                }
                i++;
            }
            // keine Konstantenbezeichnung gefunden
            ScanFkt_Err(7);
        }
예제 #2
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// ScanFkt - scans the function string and builds a function tree when successful.
        /// </summary>
        /// <param name="fx0">
        /// function tree
        /// </param>
        /// <param name="funcStr0">
        /// function string to scan
        /// </param>
        public void ScanFkt(ref FunctionCalcTree fx0, string funcStr0)
        {
            if (funcStr0 != string.Empty)
            {
                this.maxLang  = (byte)funcStr0.Length;
                this.funcStr  = funcStr0;
                this.fx       = fx0;
                this.fFormel  = string.Empty;
                this.chPos    = -1;
                this.oldChPos = -1;
                this.ch       = ' ';
                this.fehler   = false;
                this.errPos   = 0;
                this.errNr    = 0;
                this.ScanFkt_GetSym();
                this.ScanFkt_Expression(ref this.fx);
            }
            else
            {
                this.errNr = 6;
            }

            this.lastErrNr  = (byte)this.errNr;
            this.lastErrPos = this.errPos;
            if (this.errNr == 0)
            {
                fx0 = this.fx;
            }
        }
예제 #3
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// The fkt wert.
        /// </summary>
        /// <param name="fx">
        /// function.
        /// </param>
        /// <param name="nr">
        /// number of variable - in this version unused
        /// </param>
        /// <returns>
        /// value <see cref="double"/> .
        /// </returns>
        public double FktWert(FunctionCalcTree fx, int nr)
        {
            double result;

            if (fx != null)
            {
                this.calcErr      = false;
                this.fktWertError = false;
                result            = this.FktWert_Berechne(fx, nr);
                if (this.fktWertError)
                {
                    if (this.calcErr)
                    {
                        result = Constants.fehlerZahl;
                    }
                    else
                    {
                        result = Constants.leerFeld;
                    }
                }
            }
            else
            {
                result       = Constants.fehlerZahl;
                this.calcErr = true;
            }

            return(result);
        }
예제 #4
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        ///   Method of the Scanfkt: reads an identifier.
        /// </summary>
        public void ScanFkt_Identifier()
        {
            string buf  = string.Empty;
            string buf1 = string.Empty;

            do
            {
                buf  = buf + this.ch;
                buf1 = buf1 + this.ch_;
                this.ScanFkt_GetCh();
            }while ((this.ch >= 'A') && (this.ch <= 'Z'));

            if (buf == "PI")
            {
                this.sym  = symTyp.istZahl;
                this.wert = Math.PI;
                return;
            }

            if (buf == "E")
            {
                if (this.ch == '^')
                {
                    this.sym = symTyp.expf;
                    this.ScanFkt_GetCh();
                    return;
                }
                else
                {
                    this.sym  = symTyp.istZahl;
                    this.wert = Constants.eulerZahl;
                    return;
                }
            }
            // teste auf Funktionsbezeichner
            this.sym = symTyp.sinf;
            while ((this.sym < symTyp.ffmax) && (buf != Constants.fnam[(int)this.sym - 5]))
            {
                this.sym++;
            }

            if (this.sym == symTyp.ffmax)
            {
                if (buf.ToLower().CompareTo(Constants.varName.ToLower()) == 0)
                {
                    this.sym = symTyp.ident;
                    if (this.xVar == null)
                    {
                        this.xVar       = this.ScanFkt_MakeNode(null, symTyp.ident, null);
                        this.xVar.Zwert = 0;
                        this.xVar.Name  = buf1;
                    }
                }
                else
                {
                    ScanFkt_Err(7);
                }
            }
        }
예제 #5
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// Calculates the value of a function for a given number.
        /// </summary>
        /// <param name="fx">
        /// function
        /// </param>
        /// <param name="x">
        /// given number
        /// </param>
        /// <returns>
        /// calculateted value <see cref="double"/> .
        /// </returns>
        public double FreierFktWert(FunctionCalcTree fx, double x)
        {
            double result;

            this.varXwert = x;
            result        = this.FktWert(fx, -1);
            return(result);
        }
예제 #6
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// Makes a node in the function tree.
        /// </summary>
        /// <param name="op1">
        ///  op1 - left tree/operand
        /// </param>
        /// <param name="code">
        ///  code - operator
        /// </param>
        /// <param name="op2">
        /// op2 right tree/operand
        /// </param>
        /// <returns>
        /// The <see cref="CalculatorFunctionTerm"/> .
        /// </returns>
        public FunctionCalcTree ScanFkt_MakeNode(FunctionCalcTree op1, symTyp code, FunctionCalcTree op2)
        {
            FunctionCalcTree result;

            result       = new FunctionCalcTree();
            result.Cwert = code;
            result.Li    = op1;
            result.Re    = op2;
            return(result);
        }
예제 #7
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// clears the function tree
        /// </summary>
        /// <param name="fx">
        /// function tree
        /// </param>
        public void Loesch(ref FunctionCalcTree fx)
        {
            if (fx != null)
            {
                this.Loesch(ref fx.Li);
                this.Loesch(ref fx.Re);

                // fx.free
                fx = null;
            }
        }
        /// <summary>
        /// The textbox1 text changed_1.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void TextBox1TextChanged1(object sender, TextChangedEventArgs e)
        {
            var formelStr = this.textBox1.Text;

            if (usesDecimalkomma)
            {
                formelStr = formelStr.Replace('.', ',');
            }
            else
            {
                formelStr = formelStr.Replace(',', '.');
            }
            string hilfStr   = string.Empty;
            var    aktParser = new Parse();

            this.scannedFkt = null;
            aktParser.ScanFkt(ref this.scannedFkt, formelStr);
            if (aktParser.lastErrNr > 0)
            {
                if (this.art == TRechnerArt.formelRechner)
                {
                    this.buttonFertig.IsEnabled = false;
                }
                else
                {
                    this.textBoxErgebnis.Text = string.Empty;
                }
                aktParser.ErrMsg(aktParser.lastErrNr, ref hilfStr);
                // Fehlerposition anzeigen mit ^
                hilfStr = string.Concat("^ ", hilfStr);
                for (int i = 1; i <= aktParser.lastErrPos; i++)
                {
                    hilfStr = string.Concat(" ", hilfStr);
                }
                this.textBoxErgebnis.Text = hilfStr;
            }
            else
            {
                if (this.art == TRechnerArt.formelRechner)
                {
                    this.buttonFertig.IsEnabled = true;
                    this.textBoxErgebnis.Text   = string.Empty;
                }
                else
                {
                    var wert = aktParser.FktWert_Berechne(this.scannedFkt, -1);
                    this.textBoxErgebnis.Text = wert.ToString(CultureInfo.InvariantCulture);
                }
            }
        }
        /// <summary>
        ///   The get funktion.
        /// </summary>
        /// <returns> The <see cref="CalculatorFunctionTerm" /> . </returns>
        public FunctionCalcTree GetFunktion()
        {
            if (this.scannedFkt != null)
            {
                this.Ergebnis        = this.textBox1.Text;
                this.scannedFkt.Name = this.Ergebnis;
            }
            else
            {
                this.scannedFkt = null;
            }

            return(this.scannedFkt);
        }
예제 #10
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// Method of the Scanfkt: get expression.
        /// expression is a sum of terms or a term
        /// </summary>
        /// <param name="expr">
        /// The expression
        /// </param>
        public void ScanFkt_Expression(ref FunctionCalcTree expr)
        {
            symTyp           addop;
            FunctionCalcTree temp = null;

            if ((this.sym == symTyp.plus) || (this.sym == symTyp.minus))
            {
                addop = this.sym;
                this.ScanFkt_GetSym();
            }
            else
            {
                addop = symTyp.plus;
            }

            this.ScanFkt_Expression_Term(ref expr);
            if (addop == symTyp.minus)
            {
                if ((expr != null) && (expr.Cwert == symTyp.istZahl))
                {
                    expr = this.ScanFkt_Zahl(-expr.Zwert);
                }
                else
                {
                    expr = this.ScanFkt_MakeNode(this.ScanFkt_Zahl(-1), symTyp.mal, expr);
                }
            }

            while ((this.sym == symTyp.plus) || (this.sym == symTyp.minus))
            {
                do
                {
                    addop = this.sym;
                    this.ScanFkt_GetSym();
                    if (this.sym == symTyp.plus)
                    {
                        this.sym = addop;
                    }
                    else if ((this.sym == symTyp.minus) && (addop == symTyp.minus))
                    {
                        this.sym = symTyp.plus;
                    }
                }while (!((this.sym != symTyp.plus) && (this.sym != symTyp.minus)));
                this.ScanFkt_Expression_Term(ref temp);
                if (!this.fehler)
                {
                    expr = this.ScanFkt_MakeNode(expr, addop, temp);
                }
            }
        }
예제 #11
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// Method of the Scanfkt: get functionterm.
        /// a functionterm is function or a factor
        /// </summary>
        /// <param name="fterm">
        /// fterm - the functionterm.
        /// </param>
        public void ScanFkt_Expression_Term_FuncTerm(ref FunctionCalcTree fterm)
        {
            symTyp           fsym;
            FunctionCalcTree temp = null;

            if (this.sym < symTyp.sinf)
            {
                this.ScanFkt_Expression_Term_FuncTerm_Faktor(ref fterm);
            }
            else if (this.sym == symTyp.fstrEnd)
            {
                this.ScanFkt_Err(4);
            }
            else
            {
                fterm = null;
            }

            while ((symTyp.pot <= this.sym) && (this.sym < symTyp.ffmax))
            {
                fsym = this.sym;
                this.ScanFkt_GetSym();
                if (fsym > symTyp.pot)
                {
                    if (this.sym != symTyp.lklammer)
                    {
                        this.ScanFkt_Err(1);
                        return;
                    }
                }

                if (this.sym < symTyp.sinf)
                {
                    this.ScanFkt_Expression_Term_FuncTerm_Faktor(ref temp);
                }
                else
                {
                    this.ScanFkt_Expression_Term_FuncTerm(ref temp);
                }

                if (!this.fehler)
                {
                    fterm = this.ScanFkt_MakeNode(fterm, fsym, temp);
                }
            }
        }
예제 #12
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// Method of the Scanfkt: get term.
        /// a term is a product or functionterm
        /// </summary>
        /// <param name="prod">
        /// prod - the term.
        /// </param>
        public void ScanFkt_Expression_Term(ref FunctionCalcTree prod)
        {
            symTyp           pSym;
            FunctionCalcTree temp = null;

            this.ScanFkt_Expression_Term_FuncTerm(ref prod);
            while ((this.sym == symTyp.mal) || (this.sym == symTyp.durch))
            {
                pSym = this.sym;
                this.ScanFkt_GetSym();
                this.ScanFkt_Expression_Term_FuncTerm(ref temp);
                if (!this.fehler)
                {
                    prod = this.ScanFkt_MakeNode(prod, pSym, temp);
                }
            }
        }
예제 #13
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        ///  Method of the Scanfkt:  get factor.
        ///  a factor is a variable, a constant, a number or an expression
        /// </summary>
        /// <param name="fakt">
        /// fakt - the factor.
        /// </param>
        public void ScanFkt_Expression_Term_FuncTerm_Faktor(ref FunctionCalcTree fakt)
        {
            if (this.fehler)
            {
                return;
            }

            switch (this.sym)
            {
            case symTyp.ident:
                fakt = this.xVar;
                break;

            case symTyp.istKonst:
                fakt = this.kVar;
                break;

            case symTyp.istZahl:
                fakt = this.ScanFkt_Zahl(this.wert);
                break;

            case symTyp.lklammer:
                this.ScanFkt_GetSym();
                this.ScanFkt_Expression(ref fakt);
                if (this.sym != symTyp.rklammer)
                {
                    this.ScanFkt_Err(2);
                    return;
                }

                break;

            default:
                this.ScanFkt_Err(4);
                return;

                // break;
            }

            this.ScanFkt_GetSym();
            if (this.sym < symTyp.lklammer)
            {
                this.ScanFkt_Err(3);
            }
        }
예제 #14
0
파일: Parser.cs 프로젝트: fabianhick/viana
 /// <summary>
 /// Tests, if the function term contains no vars / only numbers and constants.
 /// </summary>
 /// <param name="fx">
 /// fx - the function term to test.
 /// </param>
 /// <returns>
 /// The <see cref="bool"/> .
 /// </returns>
 private bool doesContainNoVar(FunctionCalcTree fx)
 {
     if ((fx == null) || (fx.Cwert <= symTyp.istKonst))
     {
         return(true);
     }
     else
     {
         if (fx.Cwert == symTyp.ident)
         {
             return(false);
         }
         else
         {
             return(this.doesContainNoVar(fx.Li) && this.doesContainNoVar(fx.Re));
         }
     }
 }
예제 #15
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// Tests, if the given function is a linear function.
        /// </summary>
        /// <param name="fx">
        /// fx - the function term to test.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/> .
        /// </returns>
        public bool isLinearFunction(FunctionCalcTree fx)
        {
            if ((fx == null) || (fx.Cwert <= symTyp.istKonst))
            {
                return(true);
            }

            if (fx.Cwert > symTyp.pot)
            {
                return(this.doesContainNoVar(fx.Re));
            }

            switch (fx.Cwert)
            {
            case symTyp.ident:
                return(true);

            case symTyp.pot:
                return(this.doesContainNoVar(fx.Li) && this.doesContainNoVar(fx.Re));

            case symTyp.plus:
                return(this.isLinearFunction(fx.Li) && this.isLinearFunction(fx.Re));

            case symTyp.minus:
                return(this.isLinearFunction(fx.Li) && this.isLinearFunction(fx.Re));

            case symTyp.mal:
                return((this.doesContainNoVar(fx.Li) && this.isLinearFunction(fx.Re)) ||
                       (this.isLinearFunction(fx.Li) && this.doesContainNoVar(fx.Re)));

            case symTyp.durch:
                return(this.isLinearFunction(fx.Li) && this.doesContainNoVar(fx.Re));

            default:
                return(false);
            }
        }
예제 #16
0
파일: Parser.cs 프로젝트: fabianhick/viana
        /// <summary>
        /// Method of FktWert: calculate value.
        /// </summary>
        /// <param name="fx">
        /// function
        /// </param>
        /// <param name="nr">
        /// The nr.
        /// </param>
        /// <returns>
        /// value <see cref="double"/> .
        /// </returns>
        public double FktWert_Berechne(FunctionCalcTree fx, int nr)
        {
            double erg2;

            if (this.fktWertError)
            {
                this.result = Constants.fehlerZahl;
                return(this.result);
            }

            switch (fx.Cwert)
            {
            case symTyp.istZahl:
                this.result = fx.Zwert;
                break;

            case symTyp.istKonst:
                this.result = fx.Zwert;
                break;

            case symTyp.ident:
                this.result = this.varXwert;
                break;

            default:
                erg2 = this.FktWert_Berechne(fx.Re, nr);
                if (this.fktWertError)
                {
                    this.result = erg2;
                    return(this.result);
                }

                if (fx.Cwert <= symTyp.pot)
                {
                    this.erg1 = this.FktWert_Berechne(fx.Li, nr);
                    if (this.fktWertError)
                    {
                        this.result = this.erg1;
                        return(this.result);
                    }

                    switch (fx.Cwert)
                    {
                    case symTyp.plus:
                        this.erg1 = this.erg1 + erg2;
                        break;

                    case symTyp.minus:
                        this.erg1 = this.erg1 - erg2;
                        break;

                    case symTyp.mal:
                        this.erg1 = this.erg1 * erg2;
                        break;

                    case symTyp.durch:
                        if (erg2 != 0)
                        {
                            this.erg1 = this.erg1 / erg2;
                        }
                        else
                        {
                            this.FktWert_Berechne_Fehler();
                        }

                        break;

                    case symTyp.pot:
                        if (Convert.ToInt16(erg2) == erg2)
                        {
                            this.erg1 = this.FktWert_WertIntPot(this.erg1, Convert.ToInt16(erg2));
                        }
                        else if (this.erg1 > 0)
                        {
                            this.erg1 = Math.Exp(erg2 * Math.Log(this.erg1));
                        }
                        else if (this.erg1 < 0)
                        {
                            this.FktWert_Berechne_Fehler();
                        }

                        break;

                    default:
                        this.FktWert_Berechne_Fehler();
                        break;
                    }
                }
                else
                {
                    switch (fx.Cwert)
                    {
                    case symTyp.sinf:
                        this.erg1 = Math.Sin(erg2);
                        break;

                    case symTyp.cosf:
                        this.erg1 = Math.Cos(erg2);
                        break;

                    case symTyp.tanf:
                        this.erg1 = Math.Cos(erg2);
                        if (this.erg1 != 0)
                        {
                            this.erg1 = Math.Sin(erg2) / this.erg1;
                        }
                        else
                        {
                            this.FktWert_Berechne_Fehler();
                        }

                        break;

                    case symTyp.ctgf:
                        this.erg1 = Math.Sin(erg2);
                        if (this.erg1 != 0)
                        {
                            this.erg1 = Math.Cos(erg2) / this.erg1;
                        }
                        else
                        {
                            this.FktWert_Berechne_Fehler();
                        }

                        break;

                    case symTyp.expf:
                        this.erg1 = Math.Exp(erg2);
                        break;

                    case symTyp.lnf:
                        if (erg2 > 0)
                        {
                            this.erg1 = Math.Log(erg2);
                        }
                        else
                        {
                            this.FktWert_Berechne_Fehler();
                        }

                        break;

                    case symTyp.wurzf:
                        if (erg2 >= 0)
                        {
                            this.erg1 = Math.Sqrt(erg2);
                        }
                        else
                        {
                            this.FktWert_Berechne_Fehler();
                        }

                        break;

                    case symTyp.sigf:
                        if (erg2 > 0)
                        {
                            this.erg1 = 1;
                        }
                        else if (erg2 < 0)
                        {
                            this.erg1 = -1;
                        }
                        else
                        {
                            this.erg1 = 0;
                        }

                        break;

                    case symTyp.absf:
                        this.erg1 = Math.Abs(erg2);
                        break;

                    case symTyp.deltaf:
                        if (nr == 0)
                        {
                            this.erg1 = Constants.leerFeld;
                        }
                        else
                        {
                            this.erg1 = this.FktWert_Berechne(fx.Re, nr - 1);
                            if (this.fktWertError)
                            {
                                this.result = this.erg1;
                                return(this.result);
                            }

                            this.erg1 = erg2 - this.erg1;
                        }

                        break;

                    default:
                        this.FktWert_Berechne_Fehler();
                        break;
                    }
                }

                this.result = this.erg1;
                break;
            }

            return(this.result);
        }