예제 #1
0
        /// <summary>
        /// 終端記号のリストを、品詞のリストに変換する。
        /// </summary>
        /// <param name="terminalSymbolList">終端記号のリスト。</param>
        /// <returns>品詞のリスト。</returns>
        public static List <Lexical> convertLexicalList(List <TerminalSymbol> terminalSymbolList)
        {
            var lexicalList      = new List <Lexical>();
            int parenthesisDepth = 0; //括弧の深さ。

            foreach (TerminalSymbol terminalSymbol in terminalSymbolList)
            {
                if (terminalSymbol.type == TerminalSymbolType.LeftP)
                {
                    parenthesisDepth++;
                }
                else if (terminalSymbol.type == TerminalSymbolType.RightP)
                {
                    parenthesisDepth--;
                    if (parenthesisDepth < 0)
                    {
                        throw new ArgumentException("対応する「(」が存在しない「)」があります。");
                    }
                }
                else
                {
                    Lexical lexical = LexicalFactory.create(terminalSymbol, parenthesisDepth);
                    lexicalList.Add(lexical);
                }
            }
            if (parenthesisDepth != 0)
            {
                throw new ArgumentException("「(」の数と「)」の数が一致しません。");
            }
            return(lexicalList);
        }
예제 #2
0
        /// <summary>
        /// 逆ポーランド記法表現の文字列から、数式ツリーを復元する。
        /// ただし、演算子品詞のparenthesisDepthは正しく設定されないので注意。
        /// (逆ポーランド記法表現では再現不能。)
        /// </summary>
        /// <param name="rPolish">逆ポーランド記法表現</param>
        /// <returns>復元した数式ツリー。</returns>
        public static MathTree analyzeRPolish(string rPolish)
        {
            string[] separatingStrings = { DIVIDE_CHAR_R_POLISH };
            string[] lexicalStrList    = rPolish.Split(separatingStrings, StringSplitOptions.RemoveEmptyEntries);
            var      tree  = new MathTree();
            var      queue = new Queue <MathTreeNode>();

            foreach (string lexicalStr in lexicalStrList)
            {
                Lexical lexical = LexicalFactory.createFromRPolish(lexicalStr);
                if (lexical is Literal)
                {
                    var node = new MathTreeNode();
                    node.lex    = lexical;
                    node.master = tree;
                    queue.Enqueue(node);
                }
                else if (lexical is UnaryOperator)
                {
                    MathTreeNode operand = queue.Dequeue();
                    var          node    = new MathTreeNode();
                    node.lex    = lexical;
                    node.master = tree;
                    node.right  = operand;
                    queue.Enqueue(node);
                }
                else if (lexical is BinaryOperator)
                {
                    if (queue.Count < 2)
                    {
                        throw new ArgumentException("2つのリテラルを接続していない2項演算子があります。");
                    }
                    MathTreeNode rightOperand = queue.Dequeue();
                    MathTreeNode leftOperand  = queue.Dequeue();
                    var          node         = new MathTreeNode();
                    node.lex    = lexical;
                    node.master = tree;
                    node.left   = leftOperand;
                    node.right  = rightOperand;
                    queue.Enqueue(node);
                }
                else
                {
                    throw new ArgumentException("評価できない品詞が存在します。対象文字列:" + lexicalStr);
                }
            }
            if (queue.Count != 1)
            {
                throw new ArgumentException("最終評価が複数のリテラルとなります。");
            }
            tree.root = queue.Dequeue();
            return(tree);
        }