예제 #1
0
        public void Process()
        {
            var res = new MajorSegmentList();

            foreach (var token in tokens)
            {
                if (FieldSegment.GetType(token.Keyname) != Field.Type.NONE)
                {
                    res.Add(new FieldSegment(token.Keyname, token.Data, FieldSegment.GetType(token.Keyname)));
                }
                else if (KeywordSegment.GetType(token.Keyname) != Keyword.Type.NONE)
                {
                    if (KeywordSegment.IsEquality(token.Data))
                    {
                        res.Add(new EqKeyword(token.Keyname, token.Data, KeywordSegment.GetType(token.Keyname)));
                    }
                    else
                    {
                        res.Add(new FixedKeyword(token.Keyname, token.Data, KeywordSegment.GetType(token.Keyname)));
                    }
                }
                else
                {
                    res.Add(new ExpressionSegment(token.Keyname, token.Data));
                }
            }
            segms = res;
        }
예제 #2
0
        public CalcResult Compute()
        {
            CalcResult res = new CalcResult();

            try
            {
                // INITIALIZATION OF STUFF
                Lexer         lexer         = new Lexer(rawExpression);
                TokenList     tokenList     = lexer.GenerateTokens();
                Parser        parser        = new Parser(tokenList);
                PostTokenList postTokenList = parser.Parse();
                postTokenList.Freeze();
                MathPreprocessor mathPreprocessor = new MathPreprocessor(postTokenList);
                mathPreprocessor.Process();
                MajorSegmentList         majorSegmentList   = mathPreprocessor.GetSegments();
                List <ExpressionSegment> expressionSegments = new List <ExpressionSegment>();
                expressionSegments.Add(
                    (ExpressionSegment)majorSegmentList.Select("expression").Item()
                    );

                // PROCESSING SOME `WHERE` AND `FOR` TOKENS
                for (int i = majorSegmentList.Count - 1; i >= 0; i--)
                {
                    if (majorSegmentList[i] is ExpressionSegment)
                    {
                        break;
                    }
                    if (majorSegmentList[i] is EqKeyword
                        &&
                        (((EqKeyword)majorSegmentList[i]).Type == Keyword.Type.WHERE ||
                         ((EqKeyword)majorSegmentList[i]).Type == Keyword.Type.FOR)
                        &&
                        FixedKeyword.IsVariable(((EqKeyword)majorSegmentList[i]).GetBeforeEq())
                        &&
                        (CustomData.GetType(((EqKeyword)majorSegmentList[i]).GetAfterEq()) == CustomData.Type.FIXED))
                    {
                        string v    = ((EqKeyword)majorSegmentList[i]).GetBeforeEq();
                        string expr = ((EqKeyword)majorSegmentList[i]).GetAfterEq();
                        expressionSegments[0].Substitute(v, expr);
                    }
                    else
                    {
                        majorSegmentList[i].Ignored = true;
                    }
                }

                MajorSegmentList newExpression = majorSegmentList.CutTill(expressionSegments[0]);
                res.InterpretedAs.Add(expressionSegments[0].Build());
                List <MajorSegmentList> list = DivideByField(newExpression);
                var simplOpt = new MajorSegmentList();
                simplOpt.Add(new FieldSegment("simplify", "", Field.Type.SIMPLIFICATION));
                list.Insert(0, simplOpt);

                // SEQUENTIAL PROCESSING
                list.Reverse();
                foreach (var fieldOpts in list)
                {
                    bool isLast = fieldOpts == list[list.Count - 1];

                    // PROCESSING SOME `WHERE` AND `FOR` TOKENS
                    foreach (var expressionSegment in expressionSegments)
                    {
                        for (int i = 1; i < fieldOpts.Count; i++)
                        {
                            if (fieldOpts[i] is EqKeyword &&
                                ((fieldOpts[i] as EqKeyword).Type == Keyword.Type.WHERE ||
                                 (fieldOpts[i] as EqKeyword).Type == Keyword.Type.FOR) &&
                                CustomData.GetType((fieldOpts[i] as EqKeyword).GetAfterEq()) == CustomData.Type.FIXED &&
                                CustomData.GetType((fieldOpts[i] as EqKeyword).GetBeforeEq()) == CustomData.Type.FIXED &&
                                FixedKeyword.IsVariable((fieldOpts[i] as EqKeyword).GetBeforeEq()))
                            {
                                expressionSegment.Substitute((fieldOpts[i] as EqKeyword).GetBeforeEq(), (fieldOpts[i] as EqKeyword).GetAfterEq());
                            }
                        }
                        res.InterpretedAs.Add(fieldOpts.Build() + " " + expressionSegment.Build());
                    }

                    var fieldType = FindField(fieldOpts[0].Keyname);

                    List <string> newExprs      = new List <string>();
                    List <string> newLatexExprs = new List <string>();
                    bool          quickExit     = false;
                    foreach (var expressionSegment in expressionSegments)
                    {
                        if (fieldType == FieldType.BOOL)
                        {
                            var vars = expressionSegment.tokens.ExtractVariables();
                            vars = Functions.MakeUnique(vars);
                            foreach (var v in vars)
                            {
                                if (v.Length > 1)
                                {
                                    throw new ParsingException("Multi-symbol vars are forbidden in boolean mode");
                                }
                            }
                            var    be = new BoolEng(expressionSegment.Build());
                            string newExpr;
                            newExpr = be.CompileTable();
                            string line = "{";
                            foreach (var onevar in vars)
                            {
                                line += ": " + onevar + " %";
                            }
                            line   += ": F %}\n";
                            newExpr = line + newExpr;
                            newExprs.Add(newExpr);
                            {
                                newExpr = newExpr.Replace(":", "<th>");
                                newExpr = newExpr.Replace("%", "</th>");
                                newExpr = newExpr.Replace("{", "<tr>");
                                newExpr = newExpr.Replace("}", "</tr>");
                                newExpr = newExpr.Replace("[", "<td class=\"cellbool-res\">");
                                newExpr = newExpr.Replace("]", "</td>");
                                newExpr = newExpr.Replace("\n", "");
                                newExpr = "<table id=\"bool-res\">" + newExpr + "</table>";
                            }
                            newLatexExprs.Add(newExpr);
                            quickExit = true;
                            break;
                        }
                        else if (AscCalc.MathAnalysis.Contains(fieldType))
                        {
                            expressionSegment.tokens.AddOmittedOps();
                            var    vars = expressionSegment.tokens.ExtractVariables();
                            string diffVar;
                            vars = Functions.MakeUnique(vars);
                            if (fieldOpts.Select(Names.FOR).Count == 0)
                            {
                                if (vars.Contains("x") || vars.Count == 0)
                                {
                                    diffVar = "x";
                                }
                                else if (vars.Contains("y"))
                                {
                                    diffVar = "y";
                                }
                                else
                                {
                                    diffVar = vars[0];
                                }
                                res.InterpretedAs.Add("Interpreted as `" + Names.FOR + " " + diffVar + "`");
                            }
                            else if (fieldOpts.Select(Names.FOR).Count == 1)
                            {
                                diffVar = (fieldOpts.Select(Names.FOR).Item() as FixedKeyword).GetVariable();
                            }
                            else
                            {
                                diffVar = (fieldOpts.Select(Names.FOR)[0] as FixedKeyword).GetVariable();
                            }
                            vars.Add(diffVar);
                            vars = Functions.MakeUnique(vars);
                            string req = expressionSegment.Build();
                            if (fieldType == FieldType.DERIVATIVE)
                            {
                                newExprs.Add(MathS.FromString(req).Derive(MathS.Var(diffVar)).ToString());
                                if (isLast && latex)
                                {
                                    newLatexExprs.Add("$$" + MathS.FromString(req).Derive(MathS.Var(diffVar)).Latexise().ToString() + "$$");
                                }
                            }
                            else if (fieldType == FieldType.SOLVE)
                            {
                                expressionSegment.tokens.AddOmittedOps();
                                if (vars.Count > 1)
                                {
                                    throw new InvalidRequestException();
                                }
                                var roots = MathS.FromString(req).SolveNt(MathS.Var(diffVar), precision: 400);
                                foreach (var root in roots)
                                {
                                    newExprs.Add(root.ToString());
                                }
                                if (isLast && latex)
                                {
                                    foreach (var root in roots)
                                    {
                                        newExprs.Add("$$" + root.ToString() + "$$");
                                    }
                                }
                            }
                        }

                        else if (fieldType == FieldType.SIMPLIFICATION)
                        {
                            expressionSegment.tokens.AddOmittedOps();
                            var vars = expressionSegment.tokens.ExtractVariables();
                            vars = Functions.MakeUnique(vars);
                            string req = expressionSegment.Build();
                            string newExpr;
                            newExpr = MathS.FromString(req).SimplifyIntelli().ToString();
                            newExprs.Add(newExpr);
                            if (isLast && latex)
                            {
                                newExpr = MathS.FromString(req).SimplifyIntelli().Latexise();
                                newLatexExprs.Add("$$" + newExpr + "$$");
                            }
                        }
                    }
                    if (newExprs.Count == 0)
                    {
                        res.Result = "No answer";
                        break;
                    }
                    if (!isLast && !quickExit)
                    {
                        expressionSegments = new List <ExpressionSegment>();
                        foreach (var nexp in newExprs)
                        {
                            expressionSegments.Add(new ExpressionSegment("expression", nexp));
                        }
                    }
                    else
                    {
                        res.Result = "";
                        foreach (var segm in newExprs)
                        {
                            res.Result += segm + " ";
                        }
                        res.LatexResult = "";
                        foreach (var segm in newLatexExprs)
                        {
                            res.LatexResult += segm + " ";
                        }
                        break; // For quickExit case
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            return(res);
        }