Exemple #1
0
        void CombineTerms(char[] operators)
        {
            foreach (EquationElement element in Stack)
            {
                if (element is Term)
                {
                    ((Term)element).CombineTerms(operators);
                }
            }
            if (NeedSubTerms(operators) == false)
            {
                return;
            }

            int startIndex = 0;
            int startpoint = 0;

            while (startIndex < Stack.Count)
            {
                startIndex = FindOperator(startIndex, operators);
                if (startIndex < 0)
                {
                    return;
                }

                Term newterm = new Term();
                newterm.Parent = this;
                startIndex--;
                startpoint = startIndex;

                while (startIndex < Stack.Count)
                {
                    EquationElement item = Stack[startIndex];
                    if (item is EquationValue)
                    {
                        newterm.Add(item);
                        startIndex++;
                    }
                    if (item is Operator)
                    {
                        Operator op = item as Operator;
                        if (op == null || operators.Contains(op.Value) == false)
                        {
                            Stack.RemoveRange(startpoint, newterm.Stack.Count);
                            Stack.Insert(startpoint, newterm);
                            break;
                        }
                        newterm.Add(item);
                        startIndex++;
                    }

                    if (startIndex >= Stack.Count)
                    {
                        Stack.RemoveRange(startpoint, newterm.Stack.Count);
                        Stack.Insert(startpoint, newterm);
                        return;
                    }
                }
            }
        }
Exemple #2
0
        static string GetVarName(string equation, int index, EquationElement root)
        {
            string varname = Term.ExtractName(equation, index).ToLower();

            if (root != null && root.VarExist(varname))
            {
                return(varname);
            }
            char ch = equation[index];

            if (ch >= 'a' && ch <= 'z')
            {
                //return new string(new char[] { ch });
                return(varname);
            }
            if (ch >= 'A' && ch <= 'Z')
            {
                // return new string(new char[] { ch });
                return(varname);
            }
            if (ch == '_')
            {
                // return new string(new char[] { ch });
                return(varname);
            }
            return(string.Empty);
        }
Exemple #3
0
 /// <summary>
 /// 최상위에서부터 차근차근 풀어감
 /// 연산전 제곱과 나눔 곱셈을 구분해서 연산 순위를 정참.
 /// </summary>
 /// <param name="equation"></param>
 /// <param name="root"></param>
 public void Parse(string equation, EquationElement root)
 {
     Stack.Clear();
     Parse(equation, 0, root);
     CombineTerms(new char[] { '^' });
     CombineTopDown();
     CombineTerms(new char[] { '*', '/' });
 }
Exemple #4
0
        public void ClearVars() // 내부의 변수를 모두 초기화
        {
            EquationElement root = Root;

            if (root.m_variables != null)
            {
                root.m_variables.Clear();
            }
        }
Exemple #5
0
        public Variable(string src, int start, EquationElement root)
        {
            string varname = GetVarName(src, start, root);

            if (varname.Length > 0)
            {
                m_sb.Append(varname);
            }
        }
Exemple #6
0
        /// <summary>
        /// 변수를 설정함
        /// </summary>
        /// <param name="varname"></param>
        /// <param name="value"></param>
        public void SetVar(string varname, double value)
        {
            EquationElement root = Root;

            if (root.m_variables == null)
            {
                root.m_variables = new Dictionary <string, double>();
            }
            root.m_variables[varname.ToLower()] = value;
        }
Exemple #7
0
        /// <summary>
        /// 모든 변수를 얻어옴
        /// </summary>
        /// <returns></returns>
        public string[] GetVars()
        {
            EquationElement root = Root;

            if (m_variables == null)
            {
                return(new string[0]);
            }
            List <string> I = new List <string>(m_variables.Keys);

            I.Sort();
            return(I.ToArray());
        }
Exemple #8
0
        EquationElement Add(EquationElement item)
        {
            item.Parent = this;
            if (item is EquationValue)
            {
                // 변수와 변수 사이에 *를 삽입
                if (LastElement is EquationValue)
                {
                    Stack.Add(new Operator('*'));
                }

                if (PopSignOperator() != null)
                {
                    ((EquationValue)item).Signed = true;
                }
                Stack.Add(item);
                return(item);
            }
            if (item is Operator)
            {
                // 괄호앞에 - 이외엔 쓸수 없음.
                if (((Operator)item).CanStartTerm == false && Stack.Count == 0)
                {
                    throw new ParseException(string.Empty, 0, "- 기호 이외엔 괄호앞에 사용 할 수 없습니다.");
                }
                // -(-) 일 경우도 생각
                Operator op = LastElement as Operator;
                if (op != null && ((Operator)item).IsSign == false)
                {
                    throw new ParseException(Root.ToString(), 0, "연속된 연산자는 유효하지 않습니다.");
                }
                if (OperatorCount >= 2)
                {
                    throw new ParseException(Root.ToString(), 0, "연속된 연산자는 유효하지 않습니다.");
                }
                Stack.Add(item);
                return(item);
            }
            if (item is CompareOperator)
            {
                Stack.Add(item);
                return(item);
            }
            return(null);
        }
Exemple #9
0
        void CombineTopDown()
        {
            // ^연산자의 경우 가장 먼저 처리.
            // 2^3^4 일 경우엔 2^(3^4) right -> left(top->down) 형태로 처리
            char operatorCh = '^';

            foreach (EquationElement element in Stack)
            {
                if (element is Term)
                {
                    ((Term)element).CombineTopDown();
                }
            }
            int index = Stack.Count - 1;

            while (index > 0)
            {
                Operator op = Stack[index] as Operator;
                index--;
                if (op == null || op.Value != operatorCh)
                {
                    continue;
                }

                EquationElement left  = Stack[index];
                EquationElement right = Stack[index + 2];

                Term newterm = new Term();
                newterm.Parent = this;
                newterm.Add(left);
                newterm.Add(op);
                newterm.Add(right);

                // move signed to outer term
                if (((EquationValue)left).Signed)
                {
                    ((EquationValue)left).Signed = false;
                    newterm.Signed = true;
                }

                Stack.RemoveRange(index, newterm.Stack.Count);
                Stack.Insert(index, newterm);
            }
        }
Exemple #10
0
        /// <summary>
        /// 변수를 얻어옴
        /// </summary>
        /// <param name="varname"></param>
        /// <returns></returns>
        public double GetVar(string varname)
        {
            EquationElement root   = Root;
            double          result = 0;

            if (root.m_variables == null || root.m_variables.TryGetValue(varname.ToLower(), out result) == false)
            {
                throw new ParseException(this.ToString(), 0, string.Format("변수 {0}가 정의되지 않았습니다.", varname));
            }
            if (m_usedVars == null)
            {
                m_usedVars = new Dictionary <string, bool>();
            }
            if (m_usedVars.ContainsKey(varname) == false)
            {
                m_usedVars[varname] = true;
            }
            return(result);
        }
Exemple #11
0
        /// <summary>
        /// 해당 변수명을 찾아서 지움
        /// </summary>
        /// <param name="varname">변수명</param>
        /// <returns>변수지우는데 성공을 하면 True 실패시 false</returns>
        public bool removeVar(string varname) //
        {
            EquationElement root = Root;

            if (root != null)
            {
                if (root.m_variables == null)
                {
                    root.m_variables = new Dictionary <string, double>();
                    return(false);
                }
                if (root.m_variables.ContainsKey(varname))
                {
                    root.m_variables.Remove(varname);
                    return(true);
                }
            }

            return(false);
        }
Exemple #12
0
        public Function(string src, int start, EquationElement root)
        {
            m_startIndex = start;
            m_func       = Term.ExtractName(src, start).ToLower();
            start       += m_func.Length;
            // space는 무시, 다음문자는 무조건 괄호가 와야함.
            while (src[start] == ' ')
            {
                start++;
            }
            if (src[start] != '(')
            {
                throw new ParseException(src, m_startIndex, "함수는 무조건 () 로 실행해야 합니다.'");
            }
            int termstart = start;
            int end       = Term.FindMatchingEnd('(', src, termstart);

            if (end < termstart)
            {
                throw new ParseException(src, m_startIndex, "함수 매칭 실패");
            }

            m_endindex = end;
            string allterms = src.Substring(termstart + 1, end - termstart - 1);

            //string[] terms = allterms.Split(',');
            string[] terms = GetTerms(allterms);
            m_terms = new List <Term>();
            foreach (string term in terms)
            {
                Term newterm = new Term();
                newterm.Parse(term, root);
                newterm.Parent = this;
                m_terms.Add(newterm);
            }
        }
Exemple #13
0
        /// <summary>
        /// 파싱함수
        /// </summary>
        /// <param name="equation"></param>
        /// <param name="index"></param>
        /// <param name="root"></param>
        /// <returns></returns>
        int Parse(string equation, int index, EquationElement root)
        {
            while (index < equation.Length)
            {
                char ch = equation[index];
                if (char.IsWhiteSpace(ch))                 // 공백무시
                {
                    index++;
                    continue;
                }
                if (Operator.IsValidOperator(ch))                           // 각 클래스에 정의된 Valid옵션을 토대로 Parse
                {
                    EquationElement n = Add(new Operator(equation, index)); // Add에서 해당 Element의 길이를 구해서 스택에 저장.
                    index += n.Length;                                      //인덱스를 n의 길이만큼 늘려서 계속 검색
                    continue;
                }
                if (Number.IsValidDigit(equation, index))
                {
                    EquationElement n = Add(new Number(equation, index));
                    index += n.Length;
                    continue;
                }
                if (Constant.IsValidDigit(equation, index))
                {
                    EquationElement n = Add(new Constant(equation, index));
                    index += n.Length;
                    continue;
                }
                if (Function.IsValidDigit(equation, index))
                {
                    EquationElement n = Add(new Function(equation, index, root));
                    index += n.Length;
                    continue;
                }
                if (CompareOperator.IsValidOperator(equation))
                {
                    EquationElement n = Add(new CompareOperator(equation));
                    index += n.Length;
                    continue;
                }
                if (Variable.IsValidDigit(equation, index, root))
                {
                    EquationElement n = Add(new Variable(equation, index, root));
                    index += n.Length;
                    continue;
                }
                index++;

                if (Term.IsValidDigit(ch))                 // 괄호가 또나오면 그 괄호를 풀어야됨.
                {
                    int endindex = FindMatchingEnd(ch, equation, index - 1);
                    if (endindex > index)
                    {
                        int    len = endindex - index;
                        string s   = equation.Substring(index, len);
                        Term   g   = Add(new Term(s, 0)) as Term;
                        len    = g.Parse(s, 0, root) + 1;
                        index += len;
                        continue;
                    }
                    throw new ParseException(equation, index - 1, "매칭되는 괄호를 찾을 수 없습니다.");
                }
                else
                {
                    if (ch == ']' || ch == ')')
                    {
                        throw new ParseException(equation, index - 1, " 매칭되는 괄호를 찾을 수 없습니다");
                    }
                }
            }
            return(index);
        }
Exemple #14
0
        /// <summary>
        /// 해당 변수가 존재하는가
        /// </summary>
        /// <param name="varname"></param>
        /// <returns></returns>
        public bool VarExist(string varname)
        {
            EquationElement root = Root;

            return(root.m_variables != null && root.m_variables.ContainsKey(varname.ToLower()));
        }
Exemple #15
0
 public bool IsValid(string equation, int index, EquationElement root)
 {
     return(GetVarName(equation, index, root).Length > 0);
 }