/// <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); }
/// <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); }