View Javadoc

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  }