1 /* 2 * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of Clarkware Consulting, Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without prior written permission. For written 18 * permission, please contact clarkware@clarkware.com. 19 * 20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 21 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 23 * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 26 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package jp.sourceforge.rpn_computer; 33 34 /** 35 * <p> 36 * 数式を解析し、逆ポーランド記法に変換し、計算を行います。数式は、実際はコマンドに分解され、それをスタックマシンとして実行します。 37 * </p> 38 * 39 * @author uguu@users.sourceforge.jp 40 */ 41 public final class RpnComputer { 42 43 /** 44 * <p> 45 * 逆ポーランド記法の順序で並んでいるコマンドの配列を解釈し、計算を行います。 46 * </p> 47 * 48 * @param commandList 49 * 計算内容を表すコマンドの配列。nullの場合、{@link NullPointerException}例外をスローします。 50 * @return 計算結果の値。 51 */ 52 public double compute(RpnCommandList commandList) { 53 // 引数をチェックします。 54 if (commandList == null) { 55 throw new NullPointerException("commandListがnullです。"); 56 } 57 // 計算を行います。 58 RpnContext ctx = new RpnContext(); 59 RpnCommand[] commands = commandList.getCommands(); 60 for (int i = 0; i < commands.length; i++) { 61 commands[i].execute(ctx); 62 } 63 // 結果を返します。 64 if (ctx.sizeStack() == 0) { 65 throw new ComputeException("計算終了後にスタックに結果の値が追加されていません。"); 66 } 67 if (ctx.sizeStack() > 1) { 68 throw new ComputeException("計算終了後にスタックに追加されている数が2つ以上あります。"); 69 } 70 Double resultValue = ctx.popStack(); 71 return resultValue.doubleValue(); 72 } 73 74 /** 75 * <p> 76 * 通常の数式を計算します。 77 * </p> 78 * 79 * @param expression 80 * 通常の数式。 81 * @return 計算結果の値。 82 */ 83 public double compute(String expression) { 84 RpnParser parser = new RpnParser(); 85 RpnNode node = parser.parse(expression); 86 87 RpnCompiler compiler = new RpnCompiler(); 88 RpnCommandList cl = compiler.compile(node); 89 90 return this.compute(cl); 91 } 92 }