OSDN Git Service

CVSリポジトリから移行。 master
authoru6k yu1 <u6k.yu1@gmail.com>
Sat, 25 Sep 2010 19:18:33 +0000 (04:18 +0900)
committeru6k yu1 <u6k.yu1@gmail.com>
Sat, 25 Sep 2010 19:18:33 +0000 (04:18 +0900)
147 files changed:
expression-computer/.checkstyle [new file with mode: 0644]
expression-computer/.classpath [new file with mode: 0644]
expression-computer/.cvsignore [new file with mode: 0644]
expression-computer/.project [new file with mode: 0644]
expression-computer/LICENSE.txt [new file with mode: 0644]
expression-computer/project.properties [new file with mode: 0644]
expression-computer/project.xml [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/Command.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/CommandList.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/CompileContext.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/CompileException.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/Compiler.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeContext.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeException.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeObject.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/Computer.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/Function.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/Node.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/ParseException.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/Parser.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/Serializer.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/AddCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/AndCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ArithmeticRightShiftCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/BitReversingCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionalAndCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionalOrCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/DivideCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/EqualCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ExclusiveOrCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/FunctionCallCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/GreaterThanCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/GreaterThanEqualCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/InclusiveOrCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LeftShiftCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LessThanCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LessThanEqualCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LogicalRightShiftCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/MultiplyCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/NotCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/NotEqualCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PostDecrementCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PostIncrementCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PreDecrementCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PreIncrementCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PushStackCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SetVariableCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SignReversingCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SubtractCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SurplusCommand.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/command/package.html [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAdditiveExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAdditiveExpressionOperator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAndExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAssignmentExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAssignmentExpressionOperator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalAndExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalOrExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTEqualityExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTEqualityExpressionOperator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTExclusiveOrExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFloatingPointLiteral.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFunctionExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFunctionName.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTInclusiveOrExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTIntegerLiteral.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTMultiplicativeExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTMultiplicativeExpressionOperator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTParenthesesExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPostDecrementExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPostIncrementExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPreDecrementExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPreIncrementExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTRelationalExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTRelationalExpressionOperator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTShiftExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTShiftExpressionOperator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpression.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionNotPlusMinus.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionNotPlusMinusOperator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionOperator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTVariable.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/BaseNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JJTJavaCCParserState.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParser.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserConstants.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserTokenManager.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserTreeConstants.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCharStream.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/Node.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ParseException.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/SimpleNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/Token.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/TokenMgrError.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/expression-parser.jj [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/expression-parser.jjt [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/package.html [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/rpn-parser.jjt [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AbstractNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AdditiveExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AndExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AssignmentExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/BracketExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalAndExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalOrExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/EofNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/EqualityExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ExclusiveOrExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ExpressionStatementNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/FloatingPointLiteralNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/FunctionExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/InclusiveOrExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/IntegerLiteralNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/MultiplicativeExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/OperandNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PostDecrementExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PostIncrementExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PreDecrementExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PreIncrementExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/RelationalExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ShiftExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/UnaryExpressionNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/UnaryExpressionNotPlusMinusNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/VariableNode.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/node/package.html [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/package.html [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/type/FloatingPointLiteral.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/type/IntegerLiteral.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/type/Variable.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/type/package.html [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/util/Validator.java [new file with mode: 0644]
expression-computer/src/main/java/jp/sourceforge/expression_computer/util/package.html [new file with mode: 0644]
expression-computer/src/main/java/overview.html [new file with mode: 0644]
expression-computer/src/site/xdoc/downloads.xml [new file with mode: 0644]
expression-computer/src/site/xdoc/environment.xml [new file with mode: 0644]
expression-computer/src/site/xdoc/index.xml [new file with mode: 0644]
expression-computer/src/site/xdoc/navigation.xml [new file with mode: 0644]
expression-computer/src/site/xdoc/tutorial.xml [new file with mode: 0644]
expression-computer/src/test/java/jp/sourceforge/expression_computer/test/CompilerTest.java [new file with mode: 0644]
expression-computer/src/test/java/jp/sourceforge/expression_computer/test/ComputerTest.java [new file with mode: 0644]
expression-computer/src/test/java/jp/sourceforge/expression_computer/test/RpnParserTest.jav_ [new file with mode: 0644]
expression-computer/src/test/java/jp/sourceforge/expression_computer/test/SerializerTest.java [new file with mode: 0644]
expression-computer/uguu.checkstyle.xml [new file with mode: 0644]

diff --git a/expression-computer/.checkstyle b/expression-computer/.checkstyle
new file mode 100644 (file)
index 0000000..f452927
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fileset-config file-format-version="1.2.0" simple-config="false">
+    <local-check-config name="Uguu Checks" location="uguu.checkstyle.xml" type="project" description="">
+        <additional-data name="protect-config-file" value="false"/>
+    </local-check-config>
+    <fileset name="main" enabled="true" check-config-name="Uguu Checks" local="true">
+        <file-match-pattern match-pattern="src\\main\\java\\.*\.java" include-pattern="true"/>
+        <file-match-pattern match-pattern="src\\main\\java\\jp\\sourceforge\\expression_computer\\javacc\\.*\.java" include-pattern="false"/>
+    </fileset>
+</fileset-config>
diff --git a/expression-computer/.classpath b/expression-computer/.classpath
new file mode 100644 (file)
index 0000000..e549eea
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src/main/java"/>
+       <classpathentry kind="src" path="src/test/java"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry kind="var" path="JUNIT_HOME/junit.jar"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/expression-computer/.cvsignore b/expression-computer/.cvsignore
new file mode 100644 (file)
index 0000000..d71e7d4
--- /dev/null
@@ -0,0 +1,5 @@
+bin
+.settings
+target
+build.properties
+.fbprefs
diff --git a/expression-computer/.project b/expression-computer/.project
new file mode 100644 (file)
index 0000000..bbd3553
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>expression-computer</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature>
+       </natures>
+</projectDescription>
diff --git a/expression-computer/LICENSE.txt b/expression-computer/LICENSE.txt
new file mode 100644 (file)
index 0000000..2d54e49
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
\ No newline at end of file
diff --git a/expression-computer/project.properties b/expression-computer/project.properties
new file mode 100644 (file)
index 0000000..f2d97a8
--- /dev/null
@@ -0,0 +1,16 @@
+maven.docs.outputencoding=UTF-8
+maven.docs.src=${basedir}/src/site/xdoc
+
+maven.xdoc.distributionUrl=http://rpolishcomop.sourceforge.jp
+maven.xdoc.distributionType=tar.gz
+
+maven.compile.encoding=UTF-8
+
+maven.javadoc.overview=src/main/java/overview.html
+
+maven.test.failure.ignore=true
+
+maven.checkstyle.includes=src/main/java/*.java
+maven.checkstyle.excludes=src/main/java/jp/sourceforge/expression_computer/javacc/*.java
+maven.checkstyle.properties=uguu.checkstyle.xml
+maven.checkstyle.header.file=LICENSE.txt
diff --git a/expression-computer/project.xml b/expression-computer/project.xml
new file mode 100644 (file)
index 0000000..40a9a1b
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+    <pomVersion>3</pomVersion>
+    <artifactId>expression-computer</artifactId>
+    <name>数式計算機</name>
+    <groupId>expression-computer</groupId>
+    <currentVersion>1.0.0-beta-1</currentVersion>
+    <organization />
+    <inceptionYear>2006</inceptionYear>
+    <package>jp.sourceforge.expression_computer</package>
+    <url>http://rpolishcomop.sourceforge.jp/</url>
+    <logo>http://msig.info/web2v2/Expression+Computer.png</logo>
+    <organization>
+        <name>SourceForge.jp</name>
+        <url>http://www.sourceforge.jp/</url>
+        <logo>http://sourceforge.jp/sflogo.php?group_id=2405</logo>
+    </organization>
+    <repository>
+        <connection>scm:cvs:pserver:anonymous@cvs.sourceforge.jp:/cvsroot/rpolishcomop:expression-computer</connection>
+    </repository>
+    <developers>
+        <developer>
+            <name>uguu</name>
+            <id>2</id>
+            <email>uguu@users.sourceforge.jp</email>
+        </developer>
+    </developers>
+    <licenses>
+        <license>
+            <name>BSD License</name>
+        </license>
+    </licenses>
+    <versions>
+        <version>
+            <name>0.1.0</name>
+            <tag>RELEASE_0_1_0</tag>
+            <id>0.1.0</id>
+        </version>
+        <version>
+            <name>1.0.0 beta 1</name>
+            <tag>RELEASE_1_0_0_BETA_1</tag>
+            <id>1.0.0-beta-1</id>
+        </version>
+    </versions>
+    <branches>
+        <branch>
+            <tag>RELEASE_0_1_0</tag>
+        </branch>
+        <branch>
+            <tag>RELEASE_1_0_0_BETA_1</tag>
+        </branch>
+    </branches>
+    <build>
+        <sourceDirectory>src/main/java</sourceDirectory>
+        <unitTestSourceDirectory>src/test/java</unitTestSourceDirectory>
+        <unitTest>
+            <includes>
+                <include>**/*Test.java</include>
+            </includes>
+        </unitTest>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>maven</groupId>
+            <artifactId>maven-checkstyle-plugin</artifactId>
+            <version>3.0.1</version>
+            <type>plugin</type>
+            <url>http://cvs.apache.org/repository/</url>
+        </dependency>
+    </dependencies>
+    <reports>
+        <report>maven-checkstyle-plugin</report>
+        <report>maven-license-plugin</report>
+        <report>maven-javadoc-plugin</report>
+        <report>maven-junit-report-plugin</report>
+    </reports>
+</project>
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/Command.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/Command.java
new file mode 100644 (file)
index 0000000..8055950
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * {@link Computer}クラスに実行させるコマンドを表します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public interface Command {
+
+    /**
+     * <p>
+     * 真を表す値。
+     * </p>
+     */
+    int TRUE  = 1;
+
+    /**
+     * <p>
+     * 偽を表す値。
+     * </p>
+     */
+    int FALSE = 0;
+
+    /**
+     * <p>
+     * 実行する処理を実装してください。
+     * </p>
+     * 
+     * @param context
+     *            計算コンテキスト。
+     */
+    void execute(ComputeContext context);
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/CommandList.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/CommandList.java
new file mode 100644 (file)
index 0000000..78b5b6f
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * <p>
+ * コンパイルされたコマンドのリストです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class CommandList implements List {
+
+    private List commandList = new ArrayList();
+
+    /**
+     * {@inheritDoc}
+     */
+    public int size() {
+        return this.commandList.size();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isEmpty() {
+        return this.commandList.isEmpty();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean contains(Object o) {
+        return this.commandList.contains(o);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Iterator iterator() {
+        return this.commandList.iterator();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object[] toArray() {
+        return this.commandList.toArray();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object[] toArray(Object[] a) {
+        return this.commandList.toArray(a);
+    }
+
+    /**
+     * <p>
+     * 格納されているコマンドを配列で返します。
+     * </p>
+     * 
+     * @return コマンドの配列。
+     */
+    public Command[] toCommandArray() {
+        return (Command[]) this.commandList.toArray(new Command[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean add(Object o) {
+        return this.addCommand((Command) o);
+    }
+
+    /**
+     * <p>
+     * コマンドを追加します。
+     * </p>
+     * 
+     * @param command
+     *            追加するコマンド。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @return 追加に成功した場合はtrue。
+     */
+    public boolean addCommand(Command command) {
+        if (command == null) {
+            throw new NullPointerException("commandがnullです。");
+        }
+        return this.commandList.add(command);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean remove(Object o) {
+        return this.commandList.remove(o);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean containsAll(Collection c) {
+        return this.commandList.containsAll(c);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean addAll(Collection c) {
+        if (c == null) {
+            throw new NullPointerException("cがnullです。");
+        }
+        for (Iterator i = c.iterator(); i.hasNext();) {
+            Object o = i.next();
+            this.add(o);
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean addAll(int index, Collection c) {
+        if (c == null) {
+            throw new NullPointerException("cがnullです。");
+        }
+        for (Iterator i = c.iterator(); i.hasNext();) {
+            Object o = i.next();
+            this.add(index, o);
+            index++;
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean removeAll(Collection c) {
+        return this.commandList.removeAll(c);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean retainAll(Collection c) {
+        return this.commandList.retainAll(c);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void clear() {
+        this.commandList.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object get(int index) {
+        return this.getCommand(index);
+    }
+
+    /**
+     * <p>
+     * コマンドを返します。
+     * </p>
+     * 
+     * @param index
+     *            取得するコマンドの位置を表すインデックス番号。<br>
+     *            インデックス番号が範囲外の場合、{@link IndexOutOfBoundsException}例外をスローします。
+     * @return 指定した位置のコマンド。
+     */
+    public Command getCommand(int index) {
+        return (Command) this.commandList.get(index);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object set(int index, Object element) {
+        return this.setCommand(index, (Command) element);
+    }
+
+    /**
+     * <p>
+     * 指定した位置のコマンドを指定したコマンドで置き換えます。
+     * </p>
+     * 
+     * @param index
+     *            置き換えるコマンドの位置を表すインデックス番号。<br>
+     *            インデックス番号が範囲外の場合、{@link IndexOutOfBoundsException}例外をスローします。
+     * @param command
+     *            格納するコマンド。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @return 指定した位置に以前あったコマンド。
+     */
+    public Command setCommand(int index, Command command) {
+        if (command == null) {
+            throw new NullPointerException("commandがnullです。");
+        }
+        return (Command) this.commandList.set(index, command);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void add(int index, Object element) {
+        this.addCommand(index, (Command) element);
+    }
+
+    /**
+     * <p>
+     * 指定した位置にコマンドを挿入します。
+     * </p>
+     * 
+     * @param index
+     *            コマンドを挿入する位置を表すインデックス番号。<br>
+     *            インデックス番号が範囲外の場合、{@link IndexOutOfBoundsException}例外をスローします。
+     * @param command
+     *            挿入するコマンド。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public void addCommand(int index, Command command) {
+        if (command == null) {
+            throw new NullPointerException("commandがnullです。");
+        }
+        this.commandList.add(index, command);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object remove(int index) {
+        return this.commandList.remove(index);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int indexOf(Object o) {
+        return this.commandList.indexOf(o);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int lastIndexOf(Object o) {
+        return this.commandList.lastIndexOf(o);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ListIterator listIterator() {
+        return this.commandList.listIterator();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ListIterator listIterator(int index) {
+        return this.commandList.listIterator(index);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List subList(int fromIndex, int toIndex) {
+        return this.commandList.subList(fromIndex, toIndex);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        String str = "";
+        for (Iterator i = this.iterator(); i.hasNext();) {
+            Command c = (Command) i.next();
+            str += c.toString() + "\n";
+        }
+        return str;
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/CompileContext.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/CompileContext.java
new file mode 100644 (file)
index 0000000..283eddc
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * コンパイルの情報を保持するコンテキストです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class CompileContext {
+
+    private CommandList commandList = new CommandList();
+
+    /**
+     * <p>
+     * コマンド リストを返します。
+     * </p>
+     * 
+     * @return コマンド リスト。
+     */
+    public CommandList getCommandList() {
+        return this.commandList;
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/CompileException.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/CompileException.java
new file mode 100644 (file)
index 0000000..b28c34f
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * コンパイルに失敗したことを表す例外です。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public class CompileException extends RuntimeException {
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     */
+    public CompileException() {
+        super();
+    }
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param message
+     *            例外のメッセージ。
+     * @param cause
+     *            例外の原因。
+     */
+    public CompileException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param message
+     *            例外のメッセージ。
+     */
+    public CompileException(String message) {
+        super(message);
+    }
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param cause
+     *            例外の原因。
+     */
+    public CompileException(Throwable cause) {
+        super(cause);
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/Compiler.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/Compiler.java
new file mode 100644 (file)
index 0000000..bffee18
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * 抽象構文木を命令列に変換します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class Compiler {
+
+    /**
+     * <p>
+     * 抽象構文木を命令列に変換します。
+     * </p>
+     * 
+     * @param node
+     *            命令列に変換する抽象構文木。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @return 変換された命令列。
+     */
+    public CommandList compile(Node node) {
+        if (node == null) {
+            throw new NullPointerException("nodeがnullです。");
+        }
+
+        CompileContext ctx = new CompileContext();
+        node.compile(ctx);
+        CommandList cl = ctx.getCommandList();
+
+        return cl;
+    }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeContext.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeContext.java
new file mode 100644 (file)
index 0000000..fa2fd19
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+import jp.sourceforge.expression_computer.util.Validator;
+
+/**
+ * <p>
+ * 計算中の状態を保持するコンテキストです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ComputeContext {
+
+    private Map   variableMap = new HashMap();
+
+    private Map   functionMap = new HashMap();
+
+    private Stack stack       = new Stack();
+
+    /**
+     * <p>
+     * スタックに格納されている要素の数を返します。
+     * </p>
+     * 
+     * @return スタックに格納されている要素の数。
+     */
+    public int sizeStack() {
+        return this.stack.size();
+    }
+
+    /**
+     * <p>
+     * スタックから計算オブジェクトを取り出します。取り出した計算オブジェクトは、スタックから削除されます。スタックが空の場合、{@link ComputeException}例外をスローします。
+     * </p>
+     * 
+     * @return スタックから取り出した計算オブジェクト。
+     */
+    public ComputeObject popStack() {
+        if (this.stack.empty()) {
+            throw new ComputeException("スタックが空です。");
+        }
+        return (ComputeObject) this.stack.pop();
+    }
+
+    /**
+     * <p>
+     * スタックから計算オブジェクトを取り出します。取り出した計算オブジェクトは、スタックから削除されません。スタックが空の場合、{@link ComputeException}例外をスローします。
+     * </p>
+     * 
+     * @return スタックから取り出した計算オブジェクト。
+     */
+    public ComputeObject peekStack() {
+        if (this.stack.empty()) {
+            throw new ComputeException("スタックが空です。");
+        }
+        return (ComputeObject) this.stack.peek();
+    }
+
+    /**
+     * <p>
+     * スタックに計算オブジェクトを追加します。
+     * </p>
+     * 
+     * @param obj
+     *            スタックに追加する計算オブジェクト。
+     */
+    public void pushStack(ComputeObject obj) {
+        this.stack.push(obj);
+    }
+
+    /**
+     * <p>
+     * 変数に値を設定します。変数を宣言することにもなります。
+     * </p>
+     * 
+     * @param name
+     *            変数名。<br>
+     *            nullの場合、{@link ComputeException}例外をスローします。 変数名の形式ではない場合、{@link IllegalArgumentException}例外をスローします。
+     * @param value
+     *            設定する値。
+     */
+    public void setVariable(String name, double value) {
+        if (name == null) {
+            throw new NullPointerException("nameがnullです。");
+        }
+        if (!Validator.isIdentifier(name)) {
+            throw new IllegalArgumentException("nameが変数名の形式ではありません。");
+        }
+        this.variableMap.put(name, new Double(value));
+    }
+
+    /**
+     * <p>
+     * 変数の値を取得します。
+     * </p>
+     * 
+     * @param name
+     *            変数名。<br>
+     *            指定した名前で変数が宣言されていない場合、{@link ComputeException}例外をスローします。
+     * @return 変数の値。
+     */
+    public double getVariable(String name) {
+        if (!this.variableMap.containsKey(name)) {
+            throw new ComputeException("変数{" + name + "}は宣言されていません。");
+        }
+        double value = ((Double) this.variableMap.get(name)).doubleValue();
+        return value;
+    }
+
+    /**
+     * <p>
+     * 宣言されている変数の名前の配列を返します。
+     * </p>
+     * 
+     * @return 宣言されている変数の名前の配列。
+     */
+    public String[] getVariableNames() {
+        String[] variableNames = (String[]) this.variableMap.keySet().toArray(new String[0]);
+        return variableNames;
+    }
+
+    /**
+     * <p>
+     * 呼び出し可能な関数を追加します。この呼び出しは、関数を定義することと同義です。
+     * </p>
+     * 
+     * @param name
+     *            関数名。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。 関数名の形式ではない場合、{@link IllegalArgumentException}例外をスローします。
+     * @param func
+     *            呼び出される関数。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public void addFunction(String name, Function func) {
+        if (name == null) {
+            throw new NullPointerException("nameがnullです。");
+        }
+        if (!Validator.isIdentifier(name)) {
+            throw new IllegalArgumentException("nameが関数名の形式ではありません。");
+        }
+        if (func == null) {
+            throw new NullPointerException("funcがnullです。");
+        }
+        this.functionMap.put(name, func);
+    }
+
+    /**
+     * <p>
+     * 呼び出し可能な関数を返します。
+     * </p>
+     * 
+     * @param name
+     *            関数名。<br>
+     *            指定した名前で関数が定義されていない場合、{@link ComputeException}例外をスローします。
+     * @return 関数。
+     */
+    public Function getFunction(String name) {
+        if (!this.functionMap.containsKey(name)) {
+            throw new ComputeException("関数{" + name + "}は定義されていません。");
+        }
+        Function func = (Function) this.functionMap.get(name);
+        return func;
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeException.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeException.java
new file mode 100644 (file)
index 0000000..89457a8
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * 計算に失敗したことを表す例外です。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public class ComputeException extends RuntimeException {
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     */
+    public ComputeException() {
+        super();
+    }
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param message
+     *            例外のメッセージ。
+     * @param cause
+     *            例外の原因。
+     */
+    public ComputeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param message
+     *            例外のメッセージ。
+     */
+    public ComputeException(String message) {
+        super(message);
+    }
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param cause
+     *            例外の原因。
+     */
+    public ComputeException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeObject.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/ComputeObject.java
new file mode 100644 (file)
index 0000000..bb02cf1
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * 計算対象となるオブジェクト(計算オブジェクト)の基本インターフェイスです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public interface ComputeObject {
+
+    /**
+     * <p>
+     * 保持している値を返します。
+     * </p>
+     * 
+     * @param context
+     *            計算コンテキスト。
+     * @return 保持している値。
+     */
+    double getValue(ComputeContext context);
+
+    /**
+     * <p>
+     * 値を保持します。
+     * </p>
+     * 
+     * @param value
+     *            保持する値。
+     * @param context
+     *            計算コンテキスト。
+     */
+    void setValue(double value, ComputeContext context);
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/Computer.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/Computer.java
new file mode 100644 (file)
index 0000000..0d7e3a4
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+import java.util.Iterator;
+
+/**
+ * <p>
+ * 数式を解析し、計算を行います。数式は、実際はコマンドに分解され、それをスタックマシンとして実行します。
+ * </p>
+ * <p>
+ * 使用する変数、関数は、{@link #compute(CommandList)}, {@link #compute(String)}メソッドを呼び出す前に定義しておいてください。定義されていない場合、処理中に{@link ComputeException}例外がスローされます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class Computer {
+
+    private ComputeContext context = new ComputeContext();
+
+    /**
+     * <p>
+     * 変数に値を設定します。変数を宣言することにもなります。
+     * </p>
+     * 
+     * @param name
+     *            変数名。<br>
+     *            nullの場合、{@link ComputeException}例外をスローします。
+     * @param value
+     *            設定する値。
+     */
+    public void setVariable(String name, double value) {
+        this.context.setVariable(name, value);
+    }
+
+    /**
+     * <p>
+     * 変数の値を取得します。
+     * </p>
+     * 
+     * @param name
+     *            変数名。<br>
+     *            指定した名前で変数が宣言されていない場合、{@link ComputeException}例外をスローします。
+     * @return 変数の値。
+     */
+    public double getVariable(String name) {
+        return this.context.getVariable(name);
+    }
+
+    /**
+     * <p>
+     * 宣言されている変数の名前の配列を返します。
+     * </p>
+     * 
+     * @return 宣言されている変数の名前の配列。
+     */
+    public String[] getVariableNames() {
+        return this.context.getVariableNames();
+    }
+
+    /**
+     * <p>
+     * 呼び出し可能な関数を追加します。この呼び出しは、関数を定義することと同義です。
+     * </p>
+     * 
+     * @param name
+     *            関数名。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @param func
+     *            呼び出される関数。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public void addFunction(String name, Function func) {
+        this.context.addFunction(name, func);
+    }
+
+    /**
+     * <p>
+     * 計算を行います。
+     * </p>
+     * 
+     * @param expression
+     *            通常の数式を表す文字列。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。<br>
+     *            構文解析に失敗した場合、{@link ParseException}例外をスローします。
+     * @return 計算結果の値。
+     */
+    public double compute(String expression) {
+        Parser parser = new Parser();
+        Node node = parser.parse(expression);
+
+        Compiler compiler = new Compiler();
+        CommandList commandList = compiler.compile(node);
+
+        return this.compute(commandList);
+    }
+
+    /**
+     * <p>
+     * 計算を行います。
+     * </p>
+     * 
+     * @param commandList
+     *            コマンド列。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @return 計算結果の値。
+     */
+    public double compute(CommandList commandList) {
+        if (commandList == null) {
+            throw new NullPointerException("commandListがnullです。");
+        }
+
+        for (Iterator i = commandList.iterator(); i.hasNext();) {
+            Command c = (Command) i.next();
+            c.execute(this.context);
+        }
+
+        if (this.context.sizeStack() == 0) {
+            throw new ComputeException("計算終了後にスタックに結果の値が追加されていません。");
+        }
+        if (this.context.sizeStack() > 1) {
+            throw new ComputeException("計算終了後にスタックに追加されている数が2つ以上あります。");
+        }
+        double resultValue = this.context.popStack().getValue(this.context);
+        return resultValue;
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/Function.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/Function.java
new file mode 100644 (file)
index 0000000..0ab628b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * 計算中で呼び出される関数を表します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public interface Function {
+
+    /**
+     * <p>
+     * 演算を行い、結果を返します。引数は、計算された値が渡されます。結果は、スタックにプッシュされます。
+     * </p>
+     * 
+     * @param arguments
+     *            引数の配列。
+     * @return 結果。
+     */
+    double call(double[] arguments);
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/Node.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/Node.java
new file mode 100644 (file)
index 0000000..58a3559
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * 抽象構文木のノードを表します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public interface Node {
+
+    /**
+     * <p>
+     * ノードから命令列を生成して、コンテキストに追加します。
+     * </p>
+     * 
+     * @param context
+     *            コンテキスト。
+     */
+    void compile(CompileContext context);
+
+    /**
+     * <p>
+     * 子ノードの配列を返します。このノードがリーフである場合、要素が0の配列を返します。
+     * </p>
+     * 
+     * @return 子ノードの配列。
+     */
+    Node[] getChildren();
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/ParseException.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/ParseException.java
new file mode 100644 (file)
index 0000000..a3cac16
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+/**
+ * <p>
+ * 構文解析に失敗したことを現す例外です。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ParseException extends RuntimeException {
+
+    private String text;
+
+    private int    line;
+
+    private int    column;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param text
+     *            出現した不明な文字。
+     * @param line
+     *            構文解析に失敗した行の番号。
+     * @param column
+     *            構文解析に失敗した列の番号。
+     */
+    public ParseException(String text, int line, int column) {
+        super("不明な文字{" + text + "}が出現しました。{" + (line + 1) + "行目, " + (column + 1) + "列目}");
+
+        this.text = text;
+        this.line = line;
+        this.column = column;
+    }
+
+    /**
+     * <p>
+     * JavaCCによる構文解析に失敗したことを表す例外を初期化します。
+     * </p>
+     * 
+     * @param cause
+     *            JavaCCの例外。
+     */
+    public ParseException(jp.sourceforge.expression_computer.javacc.ParseException cause) {
+        super("構文解析に失敗しました。{メッセージ=" + cause.getMessage() + "}", cause);
+
+        this.text = null;
+        this.line = -1;
+        this.column = -1;
+    }
+
+    /**
+     * <p>
+     * 出現した不明な文字を返します。
+     * </p>
+     * 
+     * @return 出現した不明な文字
+     */
+    public String getText() {
+        return this.text;
+    }
+
+    /**
+     * <p>
+     * 構文解析に失敗した行の番号を返します。
+     * </p>
+     * 
+     * @return 構文解析に失敗した行の番号。
+     */
+    public int getLine() {
+        return this.line;
+    }
+
+    /**
+     * <p>
+     * 構文解析に失敗した列の番号を返します。
+     * </p>
+     * 
+     * @return 構文解析に失敗した列の番号。
+     */
+    public int getColumn() {
+        return this.column;
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/Parser.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/Parser.java
new file mode 100644 (file)
index 0000000..349ce34
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import jp.sourceforge.expression_computer.javacc.ASTAdditiveExpression;
+import jp.sourceforge.expression_computer.javacc.ASTAdditiveExpressionOperator;
+import jp.sourceforge.expression_computer.javacc.ASTAndExpression;
+import jp.sourceforge.expression_computer.javacc.ASTAssignmentExpression;
+import jp.sourceforge.expression_computer.javacc.ASTAssignmentExpressionOperator;
+import jp.sourceforge.expression_computer.javacc.ASTConditionalAndExpression;
+import jp.sourceforge.expression_computer.javacc.ASTConditionalExpression;
+import jp.sourceforge.expression_computer.javacc.ASTConditionalOrExpression;
+import jp.sourceforge.expression_computer.javacc.ASTEqualityExpression;
+import jp.sourceforge.expression_computer.javacc.ASTEqualityExpressionOperator;
+import jp.sourceforge.expression_computer.javacc.ASTExclusiveOrExpression;
+import jp.sourceforge.expression_computer.javacc.ASTExpression;
+import jp.sourceforge.expression_computer.javacc.ASTFloatingPointLiteral;
+import jp.sourceforge.expression_computer.javacc.ASTFunctionExpression;
+import jp.sourceforge.expression_computer.javacc.ASTFunctionName;
+import jp.sourceforge.expression_computer.javacc.ASTInclusiveOrExpression;
+import jp.sourceforge.expression_computer.javacc.ASTIntegerLiteral;
+import jp.sourceforge.expression_computer.javacc.ASTMultiplicativeExpression;
+import jp.sourceforge.expression_computer.javacc.ASTMultiplicativeExpressionOperator;
+import jp.sourceforge.expression_computer.javacc.ASTParenthesesExpression;
+import jp.sourceforge.expression_computer.javacc.ASTPostDecrementExpression;
+import jp.sourceforge.expression_computer.javacc.ASTPostIncrementExpression;
+import jp.sourceforge.expression_computer.javacc.ASTPreDecrementExpression;
+import jp.sourceforge.expression_computer.javacc.ASTPreIncrementExpression;
+import jp.sourceforge.expression_computer.javacc.ASTRelationalExpression;
+import jp.sourceforge.expression_computer.javacc.ASTRelationalExpressionOperator;
+import jp.sourceforge.expression_computer.javacc.ASTShiftExpression;
+import jp.sourceforge.expression_computer.javacc.ASTShiftExpressionOperator;
+import jp.sourceforge.expression_computer.javacc.ASTUnaryExpression;
+import jp.sourceforge.expression_computer.javacc.ASTUnaryExpressionNotPlusMinus;
+import jp.sourceforge.expression_computer.javacc.ASTUnaryExpressionNotPlusMinusOperator;
+import jp.sourceforge.expression_computer.javacc.ASTUnaryExpressionOperator;
+import jp.sourceforge.expression_computer.javacc.ASTVariable;
+import jp.sourceforge.expression_computer.javacc.JavaCCParser;
+import jp.sourceforge.expression_computer.javacc.SimpleNode;
+import jp.sourceforge.expression_computer.node.AdditiveExpressionNode;
+import jp.sourceforge.expression_computer.node.AndExpressionNode;
+import jp.sourceforge.expression_computer.node.AssignmentExpressionNode;
+import jp.sourceforge.expression_computer.node.BracketExpressionNode;
+import jp.sourceforge.expression_computer.node.ConditionalAndExpressionNode;
+import jp.sourceforge.expression_computer.node.ConditionalExpressionNode;
+import jp.sourceforge.expression_computer.node.ConditionalOrExpressionNode;
+import jp.sourceforge.expression_computer.node.EqualityExpressionNode;
+import jp.sourceforge.expression_computer.node.ExclusiveOrExpressionNode;
+import jp.sourceforge.expression_computer.node.ExpressionStatementNode;
+import jp.sourceforge.expression_computer.node.FloatingPointLiteralNode;
+import jp.sourceforge.expression_computer.node.FunctionExpressionNode;
+import jp.sourceforge.expression_computer.node.InclusiveOrExpressionNode;
+import jp.sourceforge.expression_computer.node.IntegerLiteralNode;
+import jp.sourceforge.expression_computer.node.MultiplicativeExpressionNode;
+import jp.sourceforge.expression_computer.node.OperandNode;
+import jp.sourceforge.expression_computer.node.PostDecrementExpressionNode;
+import jp.sourceforge.expression_computer.node.PostIncrementExpressionNode;
+import jp.sourceforge.expression_computer.node.PreDecrementExpressionNode;
+import jp.sourceforge.expression_computer.node.PreIncrementExpressionNode;
+import jp.sourceforge.expression_computer.node.RelationalExpressionNode;
+import jp.sourceforge.expression_computer.node.ShiftExpressionNode;
+import jp.sourceforge.expression_computer.node.UnaryExpressionNode;
+import jp.sourceforge.expression_computer.node.UnaryExpressionNotPlusMinusNode;
+import jp.sourceforge.expression_computer.node.VariableNode;
+
+/**
+ * <p>
+ * 通常の数式を解析し、抽象構文木を構築します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class Parser {
+
+    /**
+     * <p>
+     * 通常の数式を解析し、抽象構文木を構築します。
+     * </p>
+     * 
+     * @param expression
+     *            通常の数式。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。<br>
+     *            構文解析に失敗した場合、{@link ParseException}例外をスローします。
+     * @return 解析した結果の抽象構文木。
+     */
+    public Node parse(String expression) {
+        if (expression == null) {
+            throw new NullPointerException("expressionがnullです。");
+        }
+
+        JavaCCParser javaCCParser = new JavaCCParser(new StringReader(expression));
+        ASTExpression astExpressionNode;
+        try {
+            astExpressionNode = (ASTExpression) javaCCParser.parse();
+        } catch (jp.sourceforge.expression_computer.javacc.ParseException e) {
+            throw new ParseException(e);
+        }
+
+        Node node = this.buildRpnNode(astExpressionNode);
+
+        return node;
+    }
+
+    private Node buildRpnNode(jp.sourceforge.expression_computer.javacc.Node node) {
+        if (node instanceof ASTExpression) {
+            if (node.jjtGetNumChildren() == 0) {
+                return new ExpressionStatementNode();
+            } else {
+                OperandNode operand = (OperandNode) this.buildRpnNode(node.jjtGetChild(0));
+
+                return new ExpressionStatementNode(operand);
+            }
+        } else if (node instanceof ASTAssignmentExpression) {
+            VariableNode operand1 = (VariableNode) this.buildRpnNode(node.jjtGetChild(0));
+            AssignmentExpressionNode.OperatorNode operator = (AssignmentExpressionNode.OperatorNode) this.buildRpnNode(node.jjtGetChild(1));
+            OperandNode operand2 = (OperandNode) this.buildRpnNode(node.jjtGetChild(2));
+
+            return new AssignmentExpressionNode(operand1, operator, operand2);
+        } else if (node instanceof ASTAssignmentExpressionOperator) {
+            ASTAssignmentExpressionOperator ope = (ASTAssignmentExpressionOperator) node;
+            if ("=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.EqualNode();
+            } else if ("+=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.AddEqualNode();
+            } else if ("-=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.SubtractEqualNode();
+            } else if ("*=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.MultiplyEqualNode();
+            } else if ("/=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.DivideEqualNode();
+            } else if ("%=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.SurplusEqualNode();
+            } else if ("&=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.AndEqualNode();
+            } else if ("^=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.ExclusiveOrEqualNode();
+            } else if ("|=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.InclusiveOrEqualNode();
+            } else if ("<<=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.LeftShiftEqualNode();
+            } else if (">>=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.ArithmeticRightShiftEqualNode();
+            } else if (">>>=".equals(ope.getNodeValue())) {
+                return new AssignmentExpressionNode.LogicalRightShiftEqualNode();
+            } else {
+                throw new ParseException(ope.getNodeValue(), ope.getNodeLine(), ope.getNodeColumn());
+            }
+        } else if (node instanceof ASTConditionalExpression) {
+            OperandNode operand1 = (OperandNode) this.buildRpnNode(node.jjtGetChild(0));
+            OperandNode operand2 = (OperandNode) this.buildRpnNode(node.jjtGetChild(1));
+            OperandNode operand3 = (OperandNode) this.buildRpnNode(node.jjtGetChild(2));
+
+            return new ConditionalExpressionNode(operand1, operand2, operand3);
+        } else if (node instanceof ASTConditionalOrExpression) {
+            OperandNode[] operands = new OperandNode[node.jjtGetNumChildren()];
+            for (int i = 0; i < operands.length; i++) {
+                operands[i] = (OperandNode) this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new ConditionalOrExpressionNode(operands);
+        } else if (node instanceof ASTConditionalAndExpression) {
+            OperandNode[] operands = new OperandNode[node.jjtGetNumChildren()];
+            for (int i = 0; i < operands.length; i++) {
+                operands[i] = (OperandNode) this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new ConditionalAndExpressionNode(operands);
+        } else if (node instanceof ASTInclusiveOrExpression) {
+            OperandNode[] operands = new OperandNode[node.jjtGetNumChildren()];
+            for (int i = 0; i < operands.length; i++) {
+                operands[i] = (OperandNode) this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new InclusiveOrExpressionNode(operands);
+        } else if (node instanceof ASTExclusiveOrExpression) {
+            OperandNode[] operands = new OperandNode[node.jjtGetNumChildren()];
+            for (int i = 0; i < operands.length; i++) {
+                operands[i] = (OperandNode) this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new ExclusiveOrExpressionNode(operands);
+        } else if (node instanceof ASTAndExpression) {
+            OperandNode[] operands = new OperandNode[node.jjtGetNumChildren()];
+            for (int i = 0; i < operands.length; i++) {
+                operands[i] = (OperandNode) this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new AndExpressionNode(operands);
+        } else if (node instanceof ASTEqualityExpression) {
+            Node[] nodes = new Node[node.jjtGetNumChildren()];
+            for (int i = 0; i < nodes.length; i++) {
+                nodes[i] = this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new EqualityExpressionNode(nodes);
+        } else if (node instanceof ASTEqualityExpressionOperator) {
+            ASTEqualityExpressionOperator ope = (ASTEqualityExpressionOperator) node;
+            if ("==".equals(ope.getNodeValue())) {
+                return new EqualityExpressionNode.EqualNode();
+            } else if ("!=".equals(ope.getNodeValue())) {
+                return new EqualityExpressionNode.NotEqualNode();
+            } else {
+                throw new ParseException(ope.getNodeValue(), ope.getNodeLine(), ope.getNodeColumn());
+            }
+        } else if (node instanceof ASTRelationalExpression) {
+            Node[] nodes = new Node[node.jjtGetNumChildren()];
+            for (int i = 0; i < nodes.length; i++) {
+                nodes[i] = this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new RelationalExpressionNode(nodes);
+        } else if (node instanceof ASTRelationalExpressionOperator) {
+            ASTRelationalExpressionOperator ope = (ASTRelationalExpressionOperator) node;
+            if (">".equals(ope.getNodeValue())) {
+                return new RelationalExpressionNode.GreaterThanNode();
+            } else if ("<".equals(ope.getNodeValue())) {
+                return new RelationalExpressionNode.LessThanNode();
+            } else if (">=".equals(ope.getNodeValue())) {
+                return new RelationalExpressionNode.GreaterThanEqualNode();
+            } else if ("<=".equals(ope.getNodeValue())) {
+                return new RelationalExpressionNode.LessThanEqualNode();
+            } else {
+                throw new ParseException(ope.getNodeValue(), ope.getNodeLine(), ope.getNodeColumn());
+            }
+        } else if (node instanceof ASTShiftExpression) {
+            Node[] nodes = new Node[node.jjtGetNumChildren()];
+            for (int i = 0; i < nodes.length; i++) {
+                nodes[i] = this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new ShiftExpressionNode(nodes);
+        } else if (node instanceof ASTShiftExpressionOperator) {
+            ASTShiftExpressionOperator ope = (ASTShiftExpressionOperator) node;
+            if ("<<".equals(ope.getNodeValue())) {
+                return new ShiftExpressionNode.LeftShiftNode();
+            } else if (">>".equals(ope.getNodeValue())) {
+                return new ShiftExpressionNode.ArithmeticRightShiftNode();
+            } else if (">>>".equals(ope.getNodeValue())) {
+                return new ShiftExpressionNode.LogicalRightShiftNode();
+            } else {
+                throw new ParseException(ope.getNodeValue(), ope.getNodeLine(), ope.getNodeColumn());
+            }
+        } else if (node instanceof ASTAdditiveExpression) {
+            Node[] nodes = new Node[node.jjtGetNumChildren()];
+            for (int i = 0; i < nodes.length; i++) {
+                nodes[i] = this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new AdditiveExpressionNode(nodes);
+        } else if (node instanceof ASTAdditiveExpressionOperator) {
+            ASTAdditiveExpressionOperator ope = (ASTAdditiveExpressionOperator) node;
+            if ("+".equals(ope.getNodeValue())) {
+                return new AdditiveExpressionNode.AddNode();
+            } else if ("-".equals(ope.getNodeValue())) {
+                return new AdditiveExpressionNode.SubtractNode();
+            } else {
+                throw new ParseException(ope.getNodeValue(), ope.getNodeLine(), ope.getNodeColumn());
+            }
+        } else if (node instanceof ASTMultiplicativeExpression) {
+            Node[] nodes = new Node[node.jjtGetNumChildren()];
+            for (int i = 0; i < nodes.length; i++) {
+                nodes[i] = this.buildRpnNode(node.jjtGetChild(i));
+            }
+
+            return new MultiplicativeExpressionNode(nodes);
+        } else if (node instanceof ASTMultiplicativeExpressionOperator) {
+            ASTMultiplicativeExpressionOperator ope = (ASTMultiplicativeExpressionOperator) node;
+            if ("*".equals(ope.getNodeValue())) {
+                return new MultiplicativeExpressionNode.MultiplyNode();
+            } else if ("/".equals(ope.getNodeValue())) {
+                return new MultiplicativeExpressionNode.DivideNode();
+            } else if ("%".equals(ope.getNodeValue())) {
+                return new MultiplicativeExpressionNode.SurplusNode();
+            } else {
+                throw new ParseException(ope.getNodeValue(), ope.getNodeLine(), ope.getNodeColumn());
+            }
+        } else if (node instanceof ASTUnaryExpression) {
+            UnaryExpressionNode.OperatorNode operator = (UnaryExpressionNode.OperatorNode) this.buildRpnNode(node.jjtGetChild(0));
+            OperandNode operand = (OperandNode) this.buildRpnNode(node.jjtGetChild(1));
+
+            return new UnaryExpressionNode(operator, operand);
+        } else if (node instanceof ASTUnaryExpressionOperator) {
+            ASTUnaryExpressionOperator ope = (ASTUnaryExpressionOperator) node;
+            if ("+".equals(ope.getNodeValue())) {
+                return new UnaryExpressionNode.PlusSignNode();
+            } else if ("-".equals(ope.getNodeValue())) {
+                return new UnaryExpressionNode.MinusSignNode();
+            } else {
+                throw new ParseException(ope.getNodeValue(), ope.getNodeLine(), ope.getNodeColumn());
+            }
+        } else if (node instanceof ASTPreIncrementExpression) {
+            VariableNode operand = (VariableNode) this.buildRpnNode(node.jjtGetChild(0));
+
+            return new PreIncrementExpressionNode(operand);
+        } else if (node instanceof ASTPreDecrementExpression) {
+            VariableNode operand = (VariableNode) this.buildRpnNode(node.jjtGetChild(0));
+
+            return new PreDecrementExpressionNode(operand);
+        } else if (node instanceof ASTUnaryExpressionNotPlusMinus) {
+            UnaryExpressionNotPlusMinusNode.OperatorNode operator = (UnaryExpressionNotPlusMinusNode.OperatorNode) this.buildRpnNode(node.jjtGetChild(0));
+            OperandNode operand = (OperandNode) this.buildRpnNode(node.jjtGetChild(1));
+
+            return new UnaryExpressionNotPlusMinusNode(operator, operand);
+        } else if (node instanceof ASTUnaryExpressionNotPlusMinusOperator) {
+            ASTUnaryExpressionNotPlusMinusOperator ope = (ASTUnaryExpressionNotPlusMinusOperator) node;
+            if ("~".equals(ope.getNodeValue())) {
+                return new UnaryExpressionNotPlusMinusNode.BitReversingNode();
+            } else if ("!".equals(ope.getNodeValue())) {
+                return new UnaryExpressionNotPlusMinusNode.NotNode();
+            } else {
+                throw new ParseException(ope.getNodeValue(), ope.getNodeLine(), ope.getNodeColumn());
+            }
+        } else if (node instanceof ASTPostIncrementExpression) {
+            VariableNode operand = (VariableNode) this.buildRpnNode(node.jjtGetChild(0));
+
+            return new PostIncrementExpressionNode(operand);
+        } else if (node instanceof ASTPostDecrementExpression) {
+            VariableNode operand = (VariableNode) this.buildRpnNode(node.jjtGetChild(0));
+
+            return new PostDecrementExpressionNode(operand);
+        } else if (node instanceof ASTIntegerLiteral) {
+            ASTIntegerLiteral integerLiteral = (ASTIntegerLiteral) node;
+
+            return new IntegerLiteralNode(integerLiteral.getNodeValue());
+        } else if (node instanceof ASTFloatingPointLiteral) {
+            ASTFloatingPointLiteral floatingPointLiteral = (ASTFloatingPointLiteral) node;
+
+            return new FloatingPointLiteralNode(floatingPointLiteral.getNodeValue());
+        } else if (node instanceof ASTFunctionExpression) {
+            FunctionExpressionNode.FunctionNameNode functionName = (FunctionExpressionNode.FunctionNameNode) this.buildRpnNode(node.jjtGetChild(0));
+            List argumentList = new ArrayList();
+            for (int i = 1; i < node.jjtGetNumChildren(); i++) {
+                OperandNode operand = (OperandNode) this.buildRpnNode(node.jjtGetChild(i));
+                argumentList.add(operand);
+            }
+            OperandNode[] arguments = (OperandNode[]) argumentList.toArray(new OperandNode[0]);
+
+            return new FunctionExpressionNode(functionName, arguments);
+        } else if (node instanceof ASTFunctionName) {
+            ASTFunctionName functionName = (ASTFunctionName) node;
+
+            return new FunctionExpressionNode.FunctionNameNode(functionName.getNodeValue());
+        } else if (node instanceof ASTVariable) {
+            ASTVariable variable = (ASTVariable) node;
+
+            return new VariableNode(variable.getNodeValue());
+        } else if (node instanceof ASTParenthesesExpression) {
+            OperandNode expression = (OperandNode) this.buildRpnNode(node.jjtGetChild(0));
+
+            return new BracketExpressionNode(expression);
+        } else {
+            SimpleNode simpleNode = (SimpleNode) node;
+            throw new ParseException(simpleNode.getNodeValue(), simpleNode.getNodeLine(), simpleNode.getNodeColumn());
+        }
+    }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/Serializer.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/Serializer.java
new file mode 100644 (file)
index 0000000..ec77284
--- /dev/null
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Iterator;
+
+import jp.sourceforge.expression_computer.command.AddCommand;
+import jp.sourceforge.expression_computer.command.AndCommand;
+import jp.sourceforge.expression_computer.command.ArithmeticRightShiftCommand;
+import jp.sourceforge.expression_computer.command.BitReversingCommand;
+import jp.sourceforge.expression_computer.command.ConditionCommand;
+import jp.sourceforge.expression_computer.command.ConditionalAndCommand;
+import jp.sourceforge.expression_computer.command.ConditionalOrCommand;
+import jp.sourceforge.expression_computer.command.DivideCommand;
+import jp.sourceforge.expression_computer.command.EqualCommand;
+import jp.sourceforge.expression_computer.command.ExclusiveOrCommand;
+import jp.sourceforge.expression_computer.command.FunctionCallCommand;
+import jp.sourceforge.expression_computer.command.GreaterThanCommand;
+import jp.sourceforge.expression_computer.command.GreaterThanEqualCommand;
+import jp.sourceforge.expression_computer.command.InclusiveOrCommand;
+import jp.sourceforge.expression_computer.command.LeftShiftCommand;
+import jp.sourceforge.expression_computer.command.LessThanCommand;
+import jp.sourceforge.expression_computer.command.LessThanEqualCommand;
+import jp.sourceforge.expression_computer.command.LogicalRightShiftCommand;
+import jp.sourceforge.expression_computer.command.MultiplyCommand;
+import jp.sourceforge.expression_computer.command.NotCommand;
+import jp.sourceforge.expression_computer.command.NotEqualCommand;
+import jp.sourceforge.expression_computer.command.PostDecrementCommand;
+import jp.sourceforge.expression_computer.command.PostIncrementCommand;
+import jp.sourceforge.expression_computer.command.PreDecrementCommand;
+import jp.sourceforge.expression_computer.command.PreIncrementCommand;
+import jp.sourceforge.expression_computer.command.PushStackCommand;
+import jp.sourceforge.expression_computer.command.SetVariableCommand;
+import jp.sourceforge.expression_computer.command.SignReversingCommand;
+import jp.sourceforge.expression_computer.command.SubtractCommand;
+import jp.sourceforge.expression_computer.command.SurplusCommand;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+import jp.sourceforge.expression_computer.type.IntegerLiteral;
+import jp.sourceforge.expression_computer.type.Variable;
+
+/**
+ * <p>
+ * コマンド リストのシリアライズ、デシリアライズを行う機能を持ちます。バイト配列はJavaのシリアライズ形式とは違い独自形式です。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class Serializer {
+
+    /**
+     * <p>
+     * ファイルの終端を表す種類値。
+     * </p>
+     */
+    private static final byte EOF                            = Byte.MAX_VALUE;
+
+    /**
+     * <p>
+     * {@link AddCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_ADD                    = 0;
+
+    /**
+     * <p>
+     * {@link AndCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_AND                    = 1;
+
+    /**
+     * <p>
+     * {@link ArithmeticRightShiftCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_ARITHMETIC_RIGHT_SHIFT = 2;
+
+    /**
+     * <p>
+     * {@link BitReversingCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_BIT_REVERSING          = 3;
+
+    /**
+     * <p>
+     * {@link ConditionalAndCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_CONDITIONAL_AND        = 4;
+
+    /**
+     * <p>
+     * {@link ConditionalOrCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_CONDITIONAL_OR         = 5;
+
+    /**
+     * <p>
+     * {@link ConditionCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_CONDITION              = 6;
+
+    /**
+     * <p>
+     * {@link DivideCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_DIVIDE                 = 7;
+
+    /**
+     * <p>
+     * {@link EqualCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_EQUAL                  = 8;
+
+    /**
+     * <p>
+     * {@link ExclusiveOrCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_EXCLUSIVE_OR           = 9;
+
+    /**
+     * <p>
+     * {@link FunctionCallCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_FUNCTION_CALL          = 10;
+
+    /**
+     * <p>
+     * {@link GreaterThanCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_GREATER_THAN           = 11;
+
+    /**
+     * <p>
+     * {@link GreaterThanEqualCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_GREATER_THAN_EQUAL     = 12;
+
+    /**
+     * <p>
+     * {@link InclusiveOrCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_INCLUSIVE_OR           = 13;
+
+    /**
+     * <p>
+     * {@link LeftShiftCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_LEFT_SHIFT             = 14;
+
+    /**
+     * <p>
+     * {@link LessThanCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_LESS_THAN              = 15;
+
+    /**
+     * <p>
+     * {@link LessThanEqualCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_LESS_THAN_EQUAL        = 16;
+
+    /**
+     * <p>
+     * {@link LogicalRightShiftCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_LOGICAL_RIGHT_SHIFT    = 17;
+
+    /**
+     * <p>
+     * {@link MultiplyCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_MULTIPLY               = 18;
+
+    /**
+     * <p>
+     * {@link NotCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_NOT                    = 19;
+
+    /**
+     * <p>
+     * {@link NotEqualCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_NOT_EQUAL              = 20;
+
+    /**
+     * <p>
+     * {@link PostDecrementCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_POST_DECREMENT         = 21;
+
+    /**
+     * <p>
+     * {@link PostIncrementCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_POST_INCREMENT         = 22;
+
+    /**
+     * <p>
+     * {@link PreDecrementCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_PRE_DECREMENT          = 23;
+
+    /**
+     * <p>
+     * {@link PreIncrementCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_PRE_INCREMENT          = 24;
+
+    /**
+     * <p>
+     * {@link PushStackCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_PUSH_STACK             = 25;
+
+    /**
+     * <p>
+     * {@link SetVariableCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_SET_VARIABLE           = 26;
+
+    /**
+     * <p>
+     * {@link SignReversingCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_SIGN_REVERSING         = 27;
+
+    /**
+     * <p>
+     * {@link SubtractCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_SUBTRACT               = 28;
+
+    /**
+     * <p>
+     * {@link SurplusCommand}クラスの種類値。
+     * </p>
+     */
+    private static final byte COMMAND_SURPLUS                = 29;
+
+    /**
+     * <p>
+     * {@link FloatingPointLiteral}クラスの種類値。
+     * </p>
+     */
+    private static final byte TYPE_FLOATING_POINT_LITERAL    = 0;
+
+    /**
+     * <p>
+     * {@link IntegerLiteral}クラスの種類値。
+     * </p>
+     */
+    private static final byte TYPE_INTEGER_LITERAL           = 1;
+
+    /**
+     * <p>
+     * {@link Variable}クラスの種類値。
+     * </p>
+     */
+    private static final byte TYPE_VARIABLE                  = 2;
+
+    /**
+     * <p>
+     * コマンド リストをシリアライズし、バイト配列に変換します。
+     * </p>
+     * 
+     * @param commandList
+     *            シリアライズするコマンド リスト。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @return シリアライズしたバイト配列。
+     * @throws IOException
+     *             シリアライズに失敗した場合。
+     */
+    public byte[] serialize(CommandList commandList) throws IOException {
+        if (commandList == null) {
+            throw new NullPointerException("commandListがnullです。");
+        }
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                for (Iterator i = commandList.iterator(); i.hasNext();) {
+                    Command c = (Command) i.next();
+                    if (c instanceof AddCommand) {
+                        objOut.writeByte(Serializer.COMMAND_ADD);
+                    } else if (c instanceof AndCommand) {
+                        objOut.writeByte(Serializer.COMMAND_AND);
+                    } else if (c instanceof ArithmeticRightShiftCommand) {
+                        objOut.writeByte(Serializer.COMMAND_ARITHMETIC_RIGHT_SHIFT);
+                    } else if (c instanceof BitReversingCommand) {
+                        objOut.writeByte(Serializer.COMMAND_BIT_REVERSING);
+                    } else if (c instanceof ConditionalAndCommand) {
+                        objOut.writeByte(Serializer.COMMAND_CONDITIONAL_AND);
+                    } else if (c instanceof ConditionalOrCommand) {
+                        objOut.writeByte(Serializer.COMMAND_CONDITIONAL_OR);
+                    } else if (c instanceof ConditionCommand) {
+                        objOut.writeByte(Serializer.COMMAND_CONDITION);
+                    } else if (c instanceof DivideCommand) {
+                        objOut.writeByte(Serializer.COMMAND_DIVIDE);
+                    } else if (c instanceof EqualCommand) {
+                        objOut.writeByte(Serializer.COMMAND_EQUAL);
+                    } else if (c instanceof ExclusiveOrCommand) {
+                        objOut.writeByte(Serializer.COMMAND_EXCLUSIVE_OR);
+                    } else if (c instanceof FunctionCallCommand) {
+                        objOut.writeByte(Serializer.COMMAND_FUNCTION_CALL);
+
+                        FunctionCallCommand funcCall = (FunctionCallCommand) c;
+                        objOut.writeUTF(funcCall.getName());
+                        objOut.writeInt(funcCall.getArgumentNumber());
+                    } else if (c instanceof GreaterThanCommand) {
+                        objOut.writeByte(Serializer.COMMAND_GREATER_THAN);
+                    } else if (c instanceof GreaterThanEqualCommand) {
+                        objOut.writeByte(Serializer.COMMAND_GREATER_THAN_EQUAL);
+                    } else if (c instanceof InclusiveOrCommand) {
+                        objOut.writeByte(Serializer.COMMAND_INCLUSIVE_OR);
+                    } else if (c instanceof LeftShiftCommand) {
+                        objOut.writeByte(Serializer.COMMAND_LEFT_SHIFT);
+                    } else if (c instanceof LessThanCommand) {
+                        objOut.writeByte(Serializer.COMMAND_LESS_THAN);
+                    } else if (c instanceof LessThanEqualCommand) {
+                        objOut.writeByte(Serializer.COMMAND_LESS_THAN_EQUAL);
+                    } else if (c instanceof LogicalRightShiftCommand) {
+                        objOut.writeByte(Serializer.COMMAND_LOGICAL_RIGHT_SHIFT);
+                    } else if (c instanceof MultiplyCommand) {
+                        objOut.writeByte(Serializer.COMMAND_MULTIPLY);
+                    } else if (c instanceof NotCommand) {
+                        objOut.writeByte(Serializer.COMMAND_NOT);
+                    } else if (c instanceof NotEqualCommand) {
+                        objOut.writeByte(Serializer.COMMAND_NOT_EQUAL);
+                    } else if (c instanceof PostDecrementCommand) {
+                        objOut.writeByte(Serializer.COMMAND_POST_DECREMENT);
+                    } else if (c instanceof PostIncrementCommand) {
+                        objOut.writeByte(Serializer.COMMAND_POST_INCREMENT);
+                    } else if (c instanceof PreDecrementCommand) {
+                        objOut.writeByte(Serializer.COMMAND_PRE_DECREMENT);
+                    } else if (c instanceof PreIncrementCommand) {
+                        objOut.writeByte(Serializer.COMMAND_PRE_INCREMENT);
+                    } else if (c instanceof PushStackCommand) {
+                        objOut.writeByte(Serializer.COMMAND_PUSH_STACK);
+
+                        PushStackCommand pushStack = (PushStackCommand) c;
+                        ComputeObject compObj = pushStack.getValue();
+                        if (compObj instanceof FloatingPointLiteral) {
+                            objOut.writeByte(Serializer.TYPE_FLOATING_POINT_LITERAL);
+                            objOut.writeDouble(compObj.getValue(null));
+                        } else if (compObj instanceof IntegerLiteral) {
+                            objOut.writeByte(Serializer.TYPE_INTEGER_LITERAL);
+                            objOut.writeLong((long) compObj.getValue(null));
+                        } else if (compObj instanceof Variable) {
+                            objOut.writeByte(Serializer.TYPE_VARIABLE);
+                            objOut.writeUTF(((Variable) compObj).getName());
+                        } else {
+                            throw new IOException("不明な計算オブジェクトです。{" + compObj + "}");
+                        }
+                    } else if (c instanceof SetVariableCommand) {
+                        objOut.writeByte(Serializer.COMMAND_SET_VARIABLE);
+                    } else if (c instanceof SignReversingCommand) {
+                        objOut.writeByte(Serializer.COMMAND_SIGN_REVERSING);
+                    } else if (c instanceof SubtractCommand) {
+                        objOut.writeByte(Serializer.COMMAND_SUBTRACT);
+                    } else if (c instanceof SurplusCommand) {
+                        objOut.writeByte(Serializer.COMMAND_SURPLUS);
+                    } else {
+                        throw new IOException("不明なコマンドです。{" + c + "}");
+                    }
+                }
+                objOut.writeByte(Serializer.EOF);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+
+        return byteOut.toByteArray();
+    }
+
+    /**
+     * <p>
+     * バイト配列をデシリアライズし、コマンド リストを構築します。
+     * </p>
+     * 
+     * @param data
+     *            デシリアライズするバイト配列。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @return 構築したコマンド リスト。
+     * @throws IOException
+     *             デシリアライズに失敗した場合。
+     */
+    public CommandList deserialize(byte[] data) throws IOException {
+        if (data == null) {
+            throw new NullPointerException("dataがnullです。");
+        }
+
+        CommandList cl = new CommandList();
+
+        ByteArrayInputStream byteIn = new ByteArrayInputStream(data);
+        try {
+            ObjectInputStream objIn = new ObjectInputStream(byteIn);
+            try {
+                Command c;
+                byte commandType;
+                while ((commandType = objIn.readByte()) != Serializer.EOF) {
+                    switch (commandType) {
+                        case Serializer.COMMAND_ADD:
+                            c = new AddCommand();
+                            break;
+                        case Serializer.COMMAND_AND:
+                            c = new AndCommand();
+                            break;
+                        case Serializer.COMMAND_ARITHMETIC_RIGHT_SHIFT:
+                            c = new ArithmeticRightShiftCommand();
+                            break;
+                        case Serializer.COMMAND_BIT_REVERSING:
+                            c = new BitReversingCommand();
+                            break;
+                        case Serializer.COMMAND_CONDITION:
+                            c = new ConditionCommand();
+                            break;
+                        case Serializer.COMMAND_CONDITIONAL_AND:
+                            c = new ConditionalAndCommand();
+                            break;
+                        case Serializer.COMMAND_CONDITIONAL_OR:
+                            c = new ConditionalOrCommand();
+                            break;
+                        case Serializer.COMMAND_DIVIDE:
+                            c = new DivideCommand();
+                            break;
+                        case Serializer.COMMAND_EQUAL:
+                            c = new EqualCommand();
+                            break;
+                        case Serializer.COMMAND_EXCLUSIVE_OR:
+                            c = new ExclusiveOrCommand();
+                            break;
+                        case Serializer.COMMAND_FUNCTION_CALL:
+                            String name = objIn.readUTF();
+                            int arguments = objIn.readInt();
+                            c = new FunctionCallCommand(name, arguments);
+
+                            break;
+                        case Serializer.COMMAND_GREATER_THAN:
+                            c = new GreaterThanCommand();
+                            break;
+                        case Serializer.COMMAND_GREATER_THAN_EQUAL:
+                            c = new GreaterThanEqualCommand();
+                            break;
+                        case Serializer.COMMAND_INCLUSIVE_OR:
+                            c = new InclusiveOrCommand();
+                            break;
+                        case Serializer.COMMAND_LEFT_SHIFT:
+                            c = new LeftShiftCommand();
+                            break;
+                        case Serializer.COMMAND_LESS_THAN:
+                            c = new LessThanCommand();
+                            break;
+                        case Serializer.COMMAND_LESS_THAN_EQUAL:
+                            c = new LessThanEqualCommand();
+                            break;
+                        case Serializer.COMMAND_LOGICAL_RIGHT_SHIFT:
+                            c = new LogicalRightShiftCommand();
+                            break;
+                        case Serializer.COMMAND_MULTIPLY:
+                            c = new MultiplyCommand();
+                            break;
+                        case Serializer.COMMAND_NOT:
+                            c = new NotCommand();
+                            break;
+                        case Serializer.COMMAND_NOT_EQUAL:
+                            c = new NotEqualCommand();
+                            break;
+                        case Serializer.COMMAND_POST_DECREMENT:
+                            c = new PostDecrementCommand();
+                            break;
+                        case Serializer.COMMAND_POST_INCREMENT:
+                            c = new PostIncrementCommand();
+                            break;
+                        case Serializer.COMMAND_PRE_DECREMENT:
+                            c = new PreDecrementCommand();
+                            break;
+                        case Serializer.COMMAND_PRE_INCREMENT:
+                            c = new PreIncrementCommand();
+                            break;
+                        case Serializer.COMMAND_PUSH_STACK:
+                            ComputeObject compObj;
+                            byte compObjType = objIn.readByte();
+                            switch (compObjType) {
+                                case Serializer.TYPE_FLOATING_POINT_LITERAL:
+                                    compObj = new FloatingPointLiteral(objIn.readDouble());
+                                    break;
+                                case Serializer.TYPE_INTEGER_LITERAL:
+                                    compObj = new IntegerLiteral(objIn.readLong());
+                                    break;
+                                case Serializer.TYPE_VARIABLE:
+                                    compObj = new Variable(objIn.readUTF());
+                                    break;
+                                default:
+                                    throw new IOException("不明な計算オブジェクトの種類です。{" + compObjType + "}");
+                            }
+                            c = new PushStackCommand(compObj);
+                            break;
+                        case Serializer.COMMAND_SET_VARIABLE:
+                            c = new SetVariableCommand();
+                            break;
+                        case Serializer.COMMAND_SIGN_REVERSING:
+                            c = new SignReversingCommand();
+                            break;
+                        case Serializer.COMMAND_SUBTRACT:
+                            c = new SubtractCommand();
+                            break;
+                        case Serializer.COMMAND_SURPLUS:
+                            c = new SurplusCommand();
+                            break;
+                        default:
+                            throw new IOException("不明なコマンドの種類です。{" + commandType + "}");
+                    }
+                    cl.add(c);
+                }
+            } finally {
+                objIn.close();
+            }
+        } finally {
+            byteIn.close();
+        }
+
+        return cl;
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/AddCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/AddCommand.java
new file mode 100644 (file)
index 0000000..452c4a2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、加算し、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class AddCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = value1 + value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/AndCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/AndCommand.java
new file mode 100644 (file)
index 0000000..5c3edb0
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、論理積を行い、その結果をスタックにプッシュします。2つの値は、それぞれ整数値に変換されてから計算されます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class AndCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = (long) value1 & (long) value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ArithmeticRightShiftCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ArithmeticRightShiftCommand.java
new file mode 100644 (file)
index 0000000..a8b18fa
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、算術右シフトし、その結果をスタックにプッシュします。2つの値は、それぞれ整数値に変換されてから計算されます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ArithmeticRightShiftCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = (long) value1 >> (long) value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/BitReversingCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/BitReversingCommand.java
new file mode 100644 (file)
index 0000000..61c8916
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから1つの値をポップし、ビット反転し、その結果をスタックにプッシュします。値は、整数値に変換されてから計算されます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class BitReversingCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value = context.popStack().getValue(context);
+        double resultValue = ~(long) value;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionCommand.java
new file mode 100644 (file)
index 0000000..d04ba9f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeObject;
+
+/**
+ * <p>
+ * スタックから3つの値をポップし、第1項が0以外の場合は第2項を、第1項が0の場合は第3項をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ConditionCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        ComputeObject value3 = context.popStack();
+        ComputeObject value2 = context.popStack();
+        double value1 = context.popStack().getValue(context);
+
+        if (value1 != FALSE) {
+            context.pushStack(value2);
+        } else {
+            context.pushStack(value3);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionalAndCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionalAndCommand.java
new file mode 100644 (file)
index 0000000..07c5eda
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、条件論理積を行い、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ConditionalAndCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        boolean value2 = context.popStack().getValue(context) != 0;
+        boolean value1 = context.popStack().getValue(context) != 0;
+
+        double resultValue;
+        if (value1 && value2) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionalOrCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ConditionalOrCommand.java
new file mode 100644 (file)
index 0000000..5a54d92
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、条件論理和を行い、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ConditionalOrCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        boolean value2 = context.popStack().getValue(context) != 0;
+        boolean value1 = context.popStack().getValue(context) != 0;
+
+        double resultValue;
+        if (value1 || value2) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/DivideCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/DivideCommand.java
new file mode 100644 (file)
index 0000000..99c4511
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、除算し、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class DivideCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = value1 / value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/EqualCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/EqualCommand.java
new file mode 100644 (file)
index 0000000..dc05175
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、比較します。2つの値が同じである場合は1を、そうでない場合は0をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class EqualCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+
+        double resultValue;
+        if (value1 == value2) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ExclusiveOrCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/ExclusiveOrCommand.java
new file mode 100644 (file)
index 0000000..2a73ca6
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、排他的論理和を行い、その結果をスタックにプッシュします。2つの値は、それぞれ整数値に変換されてから計算されます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ExclusiveOrCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = (long) value1 ^ (long) value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/FunctionCallCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/FunctionCallCommand.java
new file mode 100644 (file)
index 0000000..047e17f
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.Function;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+import jp.sourceforge.expression_computer.util.Validator;
+
+/**
+ * <p>
+ * 関数を呼び出し、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class FunctionCallCommand implements Command {
+
+    private String name;
+
+    private int    argumentNumber;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param name
+     *            関数名。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。<br>
+     *            識別子の形式ではない場合、{@link IllegalArgumentException}例外をスローします。
+     * @param argumentNumber
+     *            引数の個数。<br>
+     *            0未満の場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public FunctionCallCommand(String name, int argumentNumber) {
+        if (name == null) {
+            throw new NullPointerException("nameがnullです。");
+        }
+        if (!Validator.isIdentifier(name)) {
+            throw new IllegalArgumentException("nameが識別子の形式ではありません。");
+        }
+        if (argumentNumber < 0) {
+            throw new IllegalArgumentException("{argumentNumber < 0}です。");
+        }
+        this.name = name;
+        this.argumentNumber = argumentNumber;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        Function func = context.getFunction(this.name);
+
+        double[] arguments = new double[this.argumentNumber];
+        for (int i = (this.argumentNumber - 1); i >= 0; i--) {
+            arguments[i] = context.popStack().getValue(context);
+        }
+
+        double resultValue = func.call(arguments);
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * <p>
+     * 関数名を返します。
+     * </p>
+     * 
+     * @return 関数名。
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * <p>
+     * 引数の個数を返します。
+     * </p>
+     * 
+     * @return 引数の個数。
+     */
+    public int getArgumentNumber() {
+        return this.argumentNumber;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + "[name=" + this.name + ", argumentNumber=" + this.argumentNumber + "]";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/GreaterThanCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/GreaterThanCommand.java
new file mode 100644 (file)
index 0000000..d4d5743
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、比較します。左項が右項より大きい場合は1、そうでない場合は0をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class GreaterThanCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+
+        double resultValue;
+        if (value1 > value2) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/GreaterThanEqualCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/GreaterThanEqualCommand.java
new file mode 100644 (file)
index 0000000..6753a09
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、比較します。左項が左項より大きいか同じである場合は1を、そうでない場合は0をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class GreaterThanEqualCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+
+        double resultValue;
+        if (value1 >= value2) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/InclusiveOrCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/InclusiveOrCommand.java
new file mode 100644 (file)
index 0000000..d22daf6
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、論理和を行い、その結果をスタックにプッシュします。2つの値は、それぞれ整数値に変換されてから計算されます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class InclusiveOrCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = (long) value1 | (long) value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LeftShiftCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LeftShiftCommand.java
new file mode 100644 (file)
index 0000000..11e3883
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、左シフトし、その結果をスタックにプッシュします。2つの値は、それぞれ整数値に変換されてから計算されます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class LeftShiftCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = (long) value1 << (long) value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LessThanCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LessThanCommand.java
new file mode 100644 (file)
index 0000000..938918f
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、比較します。左項が右項より小さい場合は1を、そうでない場合は0をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class LessThanCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+
+        double resultValue;
+        if (value1 < value2) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LessThanEqualCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LessThanEqualCommand.java
new file mode 100644 (file)
index 0000000..1b32257
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、比較します。左項が右項より小さいまたは同じ場合は1を、そうでない場合は0をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class LessThanEqualCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+
+        double resultValue;
+        if (value1 <= value2) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LogicalRightShiftCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/LogicalRightShiftCommand.java
new file mode 100644 (file)
index 0000000..ab9e152
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、論理右シフトし、その結果をスタックにプッシュします。2つの値は、それぞれ整数値に変換されてから計算されます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class LogicalRightShiftCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = (long) value1 >>> (long) value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/MultiplyCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/MultiplyCommand.java
new file mode 100644 (file)
index 0000000..9d38701
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、乗算し、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class MultiplyCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = value1 * value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/NotCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/NotCommand.java
new file mode 100644 (file)
index 0000000..d2674dc
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから1つの値をポップし、否定し、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class NotCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value = context.popStack().getValue(context);
+
+        double resultValue;
+        if (value == FALSE) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/NotEqualCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/NotEqualCommand.java
new file mode 100644 (file)
index 0000000..ad0abc9
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、比較します。それぞれ違う値の場合は1を、同じ値の場合は0をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class NotEqualCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+
+        double resultValue;
+        if (value1 != value2) {
+            resultValue = TRUE;
+        } else {
+            resultValue = FALSE;
+        }
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PostDecrementCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PostDecrementCommand.java
new file mode 100644 (file)
index 0000000..c64c8f2
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeObject;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * 変数を後置インクリメントし、その結果をスタックにプッシュします。変数の値も更新します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PostDecrementCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        ComputeObject variable = context.popStack();
+        double value = variable.getValue(context);
+        double resultValue = value--;
+        variable.setValue(value, context);
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PostIncrementCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PostIncrementCommand.java
new file mode 100644 (file)
index 0000000..5ab0240
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeObject;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * 変数を後置インクリメントし、その結果をスタックにプッシュします。変数の値も更新します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PostIncrementCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        ComputeObject variable = context.popStack();
+        double value = variable.getValue(context);
+        double resultValue = value++;
+        variable.setValue(value, context);
+
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PreDecrementCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PreDecrementCommand.java
new file mode 100644 (file)
index 0000000..029ed78
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeObject;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * 変数を前置デクリメントし、その結果をスタックにプッシュします。変数の値も更新します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PreDecrementCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        ComputeObject variable = context.popStack();
+        double value = variable.getValue(context);
+        double resultValue = --value;
+        variable.setValue(resultValue, context);
+
+        context.pushStack(new FloatingPointLiteral(value));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PreIncrementCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PreIncrementCommand.java
new file mode 100644 (file)
index 0000000..f5b94cf
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeObject;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * 変数を前置インクリメントし、その結果をスタックにプッシュします。変数の値も更新します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PreIncrementCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        ComputeObject variable = context.popStack();
+        double value = variable.getValue(context);
+        double resultValue = ++value;
+        variable.setValue(resultValue, context);
+
+        context.pushStack(new FloatingPointLiteral(value));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PushStackCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/PushStackCommand.java
new file mode 100644 (file)
index 0000000..d94afdb
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeObject;
+
+/**
+ * <p>
+ * スタックに値をプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PushStackCommand implements Command {
+
+    private ComputeObject value;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param value
+     *            スタックにプッシュする値。nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public PushStackCommand(ComputeObject value) {
+        if (value == null) {
+            throw new NullPointerException("valueがnullです。");
+        }
+        this.value = value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        context.pushStack(this.value);
+    }
+
+    /**
+     * <p>
+     * スタックにプッシュする値を返します。
+     * </p>
+     * 
+     * @return スタックにプッシュする値。
+     */
+    public ComputeObject getValue() {
+        return this.value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + "[" + this.value + "]";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SetVariableCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SetVariableCommand.java
new file mode 100644 (file)
index 0000000..ff82b0c
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeObject;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから1つの値をポップし、その値を変数に設定します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class SetVariableCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value = context.popStack().getValue(context);
+        ComputeObject variable = context.popStack();
+        variable.setValue(value, context);
+        context.pushStack(new FloatingPointLiteral(value));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SignReversingCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SignReversingCommand.java
new file mode 100644 (file)
index 0000000..ac1e643
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから1つの値をポップし、符号の反転を行い、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class SignReversingCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value = context.popStack().getValue(context);
+        double resultValue = -value;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SubtractCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SubtractCommand.java
new file mode 100644 (file)
index 0000000..bcd1c4f
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、減算を行い、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class SubtractCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = value1 - value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SurplusCommand.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/SurplusCommand.java
new file mode 100644 (file)
index 0000000..b553ea8
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.command;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+
+/**
+ * <p>
+ * スタックから2つの値をポップし、剰余算を行い、その結果をスタックにプッシュします。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class SurplusCommand implements Command {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute(ComputeContext context) {
+        double value2 = context.popStack().getValue(context);
+        double value1 = context.popStack().getValue(context);
+        double resultValue = value1 % value2;
+        context.pushStack(new FloatingPointLiteral(resultValue));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/package.html b/expression-computer/src/main/java/jp/sourceforge/expression_computer/command/package.html
new file mode 100644 (file)
index 0000000..b3e27de
--- /dev/null
@@ -0,0 +1,3 @@
+<body>
+    <p>数式を構成するコマンドを格納しています。</p>
+</body>
\ No newline at end of file
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAdditiveExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAdditiveExpression.java
new file mode 100644 (file)
index 0000000..92eb7e8
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTAdditiveExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTAdditiveExpression extends SimpleNode {
+  public ASTAdditiveExpression(int id) {
+    super(id);
+  }
+
+  public ASTAdditiveExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAdditiveExpressionOperator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAdditiveExpressionOperator.java
new file mode 100644 (file)
index 0000000..3dc58f4
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTAdditiveExpressionOperator.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTAdditiveExpressionOperator extends SimpleNode {
+  public ASTAdditiveExpressionOperator(int id) {
+    super(id);
+  }
+
+  public ASTAdditiveExpressionOperator(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAndExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAndExpression.java
new file mode 100644 (file)
index 0000000..bf7bf77
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTAndExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTAndExpression extends SimpleNode {
+  public ASTAndExpression(int id) {
+    super(id);
+  }
+
+  public ASTAndExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAssignmentExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAssignmentExpression.java
new file mode 100644 (file)
index 0000000..96c890c
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTAssignmentExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTAssignmentExpression extends SimpleNode {
+  public ASTAssignmentExpression(int id) {
+    super(id);
+  }
+
+  public ASTAssignmentExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAssignmentExpressionOperator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTAssignmentExpressionOperator.java
new file mode 100644 (file)
index 0000000..276ba33
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTAssignmentExpressionOperator.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTAssignmentExpressionOperator extends SimpleNode {
+  public ASTAssignmentExpressionOperator(int id) {
+    super(id);
+  }
+
+  public ASTAssignmentExpressionOperator(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalAndExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalAndExpression.java
new file mode 100644 (file)
index 0000000..c2493e2
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTConditionalAndExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTConditionalAndExpression extends SimpleNode {
+  public ASTConditionalAndExpression(int id) {
+    super(id);
+  }
+
+  public ASTConditionalAndExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalExpression.java
new file mode 100644 (file)
index 0000000..db04943
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTConditionalExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTConditionalExpression extends SimpleNode {
+  public ASTConditionalExpression(int id) {
+    super(id);
+  }
+
+  public ASTConditionalExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalOrExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTConditionalOrExpression.java
new file mode 100644 (file)
index 0000000..78a9c4d
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTConditionalOrExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTConditionalOrExpression extends SimpleNode {
+  public ASTConditionalOrExpression(int id) {
+    super(id);
+  }
+
+  public ASTConditionalOrExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTEqualityExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTEqualityExpression.java
new file mode 100644 (file)
index 0000000..d55be61
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTEqualityExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTEqualityExpression extends SimpleNode {
+  public ASTEqualityExpression(int id) {
+    super(id);
+  }
+
+  public ASTEqualityExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTEqualityExpressionOperator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTEqualityExpressionOperator.java
new file mode 100644 (file)
index 0000000..719ae85
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTEqualityExpressionOperator.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTEqualityExpressionOperator extends SimpleNode {
+  public ASTEqualityExpressionOperator(int id) {
+    super(id);
+  }
+
+  public ASTEqualityExpressionOperator(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTExclusiveOrExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTExclusiveOrExpression.java
new file mode 100644 (file)
index 0000000..7f39d12
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTExclusiveOrExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTExclusiveOrExpression extends SimpleNode {
+  public ASTExclusiveOrExpression(int id) {
+    super(id);
+  }
+
+  public ASTExclusiveOrExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTExpression.java
new file mode 100644 (file)
index 0000000..a67c36c
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTExpression extends SimpleNode {
+  public ASTExpression(int id) {
+    super(id);
+  }
+
+  public ASTExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFloatingPointLiteral.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFloatingPointLiteral.java
new file mode 100644 (file)
index 0000000..cb6f3e7
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTFloatingPointLiteral.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTFloatingPointLiteral extends SimpleNode {
+  public ASTFloatingPointLiteral(int id) {
+    super(id);
+  }
+
+  public ASTFloatingPointLiteral(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFunctionExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFunctionExpression.java
new file mode 100644 (file)
index 0000000..d1bc69b
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTFunctionExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTFunctionExpression extends SimpleNode {
+  public ASTFunctionExpression(int id) {
+    super(id);
+  }
+
+  public ASTFunctionExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFunctionName.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTFunctionName.java
new file mode 100644 (file)
index 0000000..2925922
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTFunctionName.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTFunctionName extends SimpleNode {
+  public ASTFunctionName(int id) {
+    super(id);
+  }
+
+  public ASTFunctionName(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTInclusiveOrExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTInclusiveOrExpression.java
new file mode 100644 (file)
index 0000000..6525268
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTInclusiveOrExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTInclusiveOrExpression extends SimpleNode {
+  public ASTInclusiveOrExpression(int id) {
+    super(id);
+  }
+
+  public ASTInclusiveOrExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTIntegerLiteral.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTIntegerLiteral.java
new file mode 100644 (file)
index 0000000..612310b
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTIntegerLiteral.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTIntegerLiteral extends SimpleNode {
+  public ASTIntegerLiteral(int id) {
+    super(id);
+  }
+
+  public ASTIntegerLiteral(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTMultiplicativeExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTMultiplicativeExpression.java
new file mode 100644 (file)
index 0000000..f079bce
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTMultiplicativeExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTMultiplicativeExpression extends SimpleNode {
+  public ASTMultiplicativeExpression(int id) {
+    super(id);
+  }
+
+  public ASTMultiplicativeExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTMultiplicativeExpressionOperator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTMultiplicativeExpressionOperator.java
new file mode 100644 (file)
index 0000000..08549a4
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTMultiplicativeExpressionOperator.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTMultiplicativeExpressionOperator extends SimpleNode {
+  public ASTMultiplicativeExpressionOperator(int id) {
+    super(id);
+  }
+
+  public ASTMultiplicativeExpressionOperator(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTParenthesesExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTParenthesesExpression.java
new file mode 100644 (file)
index 0000000..6a42cfd
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTParenthesesExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTParenthesesExpression extends SimpleNode {
+  public ASTParenthesesExpression(int id) {
+    super(id);
+  }
+
+  public ASTParenthesesExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPostDecrementExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPostDecrementExpression.java
new file mode 100644 (file)
index 0000000..1f6ee93
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTPostDecrementExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTPostDecrementExpression extends SimpleNode {
+  public ASTPostDecrementExpression(int id) {
+    super(id);
+  }
+
+  public ASTPostDecrementExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPostIncrementExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPostIncrementExpression.java
new file mode 100644 (file)
index 0000000..055918c
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTPostIncrementExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTPostIncrementExpression extends SimpleNode {
+  public ASTPostIncrementExpression(int id) {
+    super(id);
+  }
+
+  public ASTPostIncrementExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPreDecrementExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPreDecrementExpression.java
new file mode 100644 (file)
index 0000000..9137fd7
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTPreDecrementExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTPreDecrementExpression extends SimpleNode {
+  public ASTPreDecrementExpression(int id) {
+    super(id);
+  }
+
+  public ASTPreDecrementExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPreIncrementExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTPreIncrementExpression.java
new file mode 100644 (file)
index 0000000..35f44c1
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTPreIncrementExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTPreIncrementExpression extends SimpleNode {
+  public ASTPreIncrementExpression(int id) {
+    super(id);
+  }
+
+  public ASTPreIncrementExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTRelationalExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTRelationalExpression.java
new file mode 100644 (file)
index 0000000..e10d692
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTRelationalExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTRelationalExpression extends SimpleNode {
+  public ASTRelationalExpression(int id) {
+    super(id);
+  }
+
+  public ASTRelationalExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTRelationalExpressionOperator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTRelationalExpressionOperator.java
new file mode 100644 (file)
index 0000000..0fbfaa8
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTRelationalExpressionOperator.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTRelationalExpressionOperator extends SimpleNode {
+  public ASTRelationalExpressionOperator(int id) {
+    super(id);
+  }
+
+  public ASTRelationalExpressionOperator(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTShiftExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTShiftExpression.java
new file mode 100644 (file)
index 0000000..c0277cb
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTShiftExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTShiftExpression extends SimpleNode {
+  public ASTShiftExpression(int id) {
+    super(id);
+  }
+
+  public ASTShiftExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTShiftExpressionOperator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTShiftExpressionOperator.java
new file mode 100644 (file)
index 0000000..d49ff5e
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTShiftExpressionOperator.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTShiftExpressionOperator extends SimpleNode {
+  public ASTShiftExpressionOperator(int id) {
+    super(id);
+  }
+
+  public ASTShiftExpressionOperator(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpression.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpression.java
new file mode 100644 (file)
index 0000000..1f0210d
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTUnaryExpression.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTUnaryExpression extends SimpleNode {
+  public ASTUnaryExpression(int id) {
+    super(id);
+  }
+
+  public ASTUnaryExpression(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionNotPlusMinus.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionNotPlusMinus.java
new file mode 100644 (file)
index 0000000..c477c2a
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTUnaryExpressionNotPlusMinus.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTUnaryExpressionNotPlusMinus extends SimpleNode {
+  public ASTUnaryExpressionNotPlusMinus(int id) {
+    super(id);
+  }
+
+  public ASTUnaryExpressionNotPlusMinus(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionNotPlusMinusOperator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionNotPlusMinusOperator.java
new file mode 100644 (file)
index 0000000..f5900c1
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTUnaryExpressionNotPlusMinusOperator.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTUnaryExpressionNotPlusMinusOperator extends SimpleNode {
+  public ASTUnaryExpressionNotPlusMinusOperator(int id) {
+    super(id);
+  }
+
+  public ASTUnaryExpressionNotPlusMinusOperator(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionOperator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTUnaryExpressionOperator.java
new file mode 100644 (file)
index 0000000..8628ef7
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTUnaryExpressionOperator.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTUnaryExpressionOperator extends SimpleNode {
+  public ASTUnaryExpressionOperator(int id) {
+    super(id);
+  }
+
+  public ASTUnaryExpressionOperator(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTVariable.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ASTVariable.java
new file mode 100644 (file)
index 0000000..b31db8a
--- /dev/null
@@ -0,0 +1,14 @@
+/* Generated By:JJTree: Do not edit this line. ASTVariable.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class ASTVariable extends SimpleNode {
+  public ASTVariable(int id) {
+    super(id);
+  }
+
+  public ASTVariable(JavaCCParser p, int id) {
+    super(p, id);
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/BaseNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/BaseNode.java
new file mode 100644 (file)
index 0000000..c1ed404
--- /dev/null
@@ -0,0 +1,23 @@
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class BaseNode {
+
+    protected String nodeValue;
+
+    protected int    nodeLine;
+
+    protected int    nodeColumn;
+
+    public String getNodeValue() {
+        return this.nodeValue;
+    }
+
+    public int getNodeLine() {
+        return this.nodeLine;
+    }
+
+    public int getNodeColumn() {
+        return this.nodeColumn;
+    }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JJTJavaCCParserState.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JJTJavaCCParserState.java
new file mode 100644 (file)
index 0000000..c21cd49
--- /dev/null
@@ -0,0 +1,123 @@
+/* Generated By:JJTree: Do not edit this line. .\JJTJavaCCParserState.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+class JJTJavaCCParserState {
+  private java.util.Stack nodes;
+  private java.util.Stack marks;
+
+  private int sp;              // number of nodes on stack
+  private int mk;              // current mark
+  private boolean node_created;
+
+  JJTJavaCCParserState() {
+    nodes = new java.util.Stack();
+    marks = new java.util.Stack();
+    sp = 0;
+    mk = 0;
+  }
+
+  /* Determines whether the current node was actually closed and
+     pushed.  This should only be called in the final user action of a
+     node scope.  */
+  boolean nodeCreated() {
+    return node_created;
+  }
+
+  /* Call this to reinitialize the node stack.  It is called
+     automatically by the parser's ReInit() method. */
+  void reset() {
+    nodes.removeAllElements();
+    marks.removeAllElements();
+    sp = 0;
+    mk = 0;
+  }
+
+  /* Returns the root node of the AST.  It only makes sense to call
+     this after a successful parse. */
+  Node rootNode() {
+    return (Node)nodes.elementAt(0);
+  }
+
+  /* Pushes a node on to the stack. */
+  void pushNode(Node n) {
+    nodes.push(n);
+    ++sp;
+  }
+
+  /* Returns the node on the top of the stack, and remove it from the
+     stack.  */
+  Node popNode() {
+    if (--sp < mk) {
+      mk = ((Integer)marks.pop()).intValue();
+    }
+    return (Node)nodes.pop();
+  }
+
+  /* Returns the node currently on the top of the stack. */
+  Node peekNode() {
+    return (Node)nodes.peek();
+  }
+
+  /* Returns the number of children on the stack in the current node
+     scope. */
+  int nodeArity() {
+    return sp - mk;
+  }
+
+
+  void clearNodeScope(Node n) {
+    while (sp > mk) {
+      popNode();
+    }
+    mk = ((Integer)marks.pop()).intValue();
+  }
+
+
+  void openNodeScope(Node n) {
+    marks.push(new Integer(mk));
+    mk = sp;
+    n.jjtOpen();
+  }
+
+
+  /* A definite node is constructed from a specified number of
+     children.  That number of nodes are popped from the stack and
+     made the children of the definite node.  Then the definite node
+     is pushed on to the stack. */
+  void closeNodeScope(Node n, int num) {
+    mk = ((Integer)marks.pop()).intValue();
+    while (num-- > 0) {
+      Node c = popNode();
+      c.jjtSetParent(n);
+      n.jjtAddChild(c, num);
+    }
+    n.jjtClose();
+    pushNode(n);
+    node_created = true;
+  }
+
+
+  /* A conditional node is constructed if its condition is true.  All
+     the nodes that have been pushed since the node was opened are
+     made children of the the conditional node, which is then pushed
+     on to the stack.  If the condition is false the node is not
+     constructed and they are left on the stack. */
+  void closeNodeScope(Node n, boolean condition) {
+    if (condition) {
+      int a = nodeArity();
+      mk = ((Integer)marks.pop()).intValue();
+      while (a-- > 0) {
+       Node c = popNode();
+       c.jjtSetParent(n);
+       n.jjtAddChild(c, a);
+      }
+      n.jjtClose();
+      pushNode(n);
+      node_created = true;
+    } else {
+      mk = ((Integer)marks.pop()).intValue();
+      node_created = false;
+    }
+  }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParser.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParser.java
new file mode 100644 (file)
index 0000000..7a92c4d
--- /dev/null
@@ -0,0 +1,1641 @@
+/* Generated By:JJTree&JavaCC: Do not edit this line. JavaCCParser.java */
+package jp.sourceforge.expression_computer.javacc;
+public final class JavaCCParser/*@bgen(jjtree)*/implements JavaCCParserTreeConstants, JavaCCParserConstants {/*@bgen(jjtree)*/
+  protected JJTJavaCCParserState jjtree = new JJTJavaCCParserState();public Node parse() throws ParseException {
+        this.Expression();
+        return this.jjtree.rootNode();
+    }
+
+  final public void Expression() throws ParseException {
+ /*@bgen(jjtree) Expression */
+  ASTExpression jjtn000 = new ASTExpression(JJTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      AssignmentExpression();
+      jj_consume_token(0);
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void AssignmentExpression() throws ParseException {
+ /*@bgen(jjtree) #AssignmentExpression(> 1) */
+  ASTAssignmentExpression jjtn000 = new ASTAssignmentExpression(JJTASSIGNMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      if (jj_2_1(2)) {
+        Variable();
+        AssignmentExpressionOperator();
+        AssignmentExpression();
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case IDENTIFIER:
+        case 42:
+        case 43:
+        case 47:
+        case 48:
+        case 49:
+        case 50:
+        case 51:
+          ConditionalExpression();
+          break;
+        default:
+          jj_la1[0] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void AssignmentExpressionOperator() throws ParseException {
+ /*@bgen(jjtree) AssignmentExpressionOperator */
+    ASTAssignmentExpressionOperator jjtn000 = new ASTAssignmentExpressionOperator(JJTASSIGNMENTEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 14:
+        t = jj_consume_token(14);
+        break;
+      case 15:
+        t = jj_consume_token(15);
+        break;
+      case 16:
+        t = jj_consume_token(16);
+        break;
+      case 17:
+        t = jj_consume_token(17);
+        break;
+      case 18:
+        t = jj_consume_token(18);
+        break;
+      case 19:
+        t = jj_consume_token(19);
+        break;
+      case 20:
+        t = jj_consume_token(20);
+        break;
+      case 21:
+        t = jj_consume_token(21);
+        break;
+      case 22:
+        t = jj_consume_token(22);
+        break;
+      case 23:
+        t = jj_consume_token(23);
+        break;
+      case 24:
+        t = jj_consume_token(24);
+        break;
+      case 25:
+        t = jj_consume_token(25);
+        break;
+      default:
+        jj_la1[1] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void ConditionalExpression() throws ParseException {
+ /*@bgen(jjtree) #ConditionalExpression(> 1) */
+  ASTConditionalExpression jjtn000 = new ASTConditionalExpression(JJTCONDITIONALEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      ConditionalOrExpression();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 26:
+        jj_consume_token(26);
+        AssignmentExpression();
+        jj_consume_token(27);
+        AssignmentExpression();
+        break;
+      default:
+        jj_la1[2] = jj_gen;
+        ;
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void ConditionalOrExpression() throws ParseException {
+ /*@bgen(jjtree) #ConditionalOrExpression(> 1) */
+  ASTConditionalOrExpression jjtn000 = new ASTConditionalOrExpression(JJTCONDITIONALOREXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      ConditionalAndExpression();
+      label_1:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 28:
+          ;
+          break;
+        default:
+          jj_la1[3] = jj_gen;
+          break label_1;
+        }
+        jj_consume_token(28);
+        ConditionalAndExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void ConditionalAndExpression() throws ParseException {
+ /*@bgen(jjtree) #ConditionalAndExpression(> 1) */
+  ASTConditionalAndExpression jjtn000 = new ASTConditionalAndExpression(JJTCONDITIONALANDEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      InclusiveOrExpression();
+      label_2:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 29:
+          ;
+          break;
+        default:
+          jj_la1[4] = jj_gen;
+          break label_2;
+        }
+        jj_consume_token(29);
+        InclusiveOrExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void InclusiveOrExpression() throws ParseException {
+ /*@bgen(jjtree) #InclusiveOrExpression(> 1) */
+  ASTInclusiveOrExpression jjtn000 = new ASTInclusiveOrExpression(JJTINCLUSIVEOREXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      ExclusiveOrExpression();
+      label_3:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 30:
+          ;
+          break;
+        default:
+          jj_la1[5] = jj_gen;
+          break label_3;
+        }
+        jj_consume_token(30);
+        ExclusiveOrExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void ExclusiveOrExpression() throws ParseException {
+ /*@bgen(jjtree) #ExclusiveOrExpression(> 1) */
+  ASTExclusiveOrExpression jjtn000 = new ASTExclusiveOrExpression(JJTEXCLUSIVEOREXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      AndExpression();
+      label_4:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 31:
+          ;
+          break;
+        default:
+          jj_la1[6] = jj_gen;
+          break label_4;
+        }
+        jj_consume_token(31);
+        AndExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void AndExpression() throws ParseException {
+ /*@bgen(jjtree) #AndExpression(> 1) */
+  ASTAndExpression jjtn000 = new ASTAndExpression(JJTANDEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      EqualityExpression();
+      label_5:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 32:
+          ;
+          break;
+        default:
+          jj_la1[7] = jj_gen;
+          break label_5;
+        }
+        jj_consume_token(32);
+        EqualityExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void EqualityExpression() throws ParseException {
+ /*@bgen(jjtree) #EqualityExpression(> 1) */
+  ASTEqualityExpression jjtn000 = new ASTEqualityExpression(JJTEQUALITYEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      RelationalExpression();
+      label_6:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 33:
+        case 34:
+          ;
+          break;
+        default:
+          jj_la1[8] = jj_gen;
+          break label_6;
+        }
+        EqualityExpressionOperator();
+        RelationalExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void EqualityExpressionOperator() throws ParseException {
+ /*@bgen(jjtree) EqualityExpressionOperator */
+    ASTEqualityExpressionOperator jjtn000 = new ASTEqualityExpressionOperator(JJTEQUALITYEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 33:
+        t = jj_consume_token(33);
+        break;
+      case 34:
+        t = jj_consume_token(34);
+        break;
+      default:
+        jj_la1[9] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void RelationalExpression() throws ParseException {
+ /*@bgen(jjtree) #RelationalExpression(> 1) */
+  ASTRelationalExpression jjtn000 = new ASTRelationalExpression(JJTRELATIONALEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      ShiftExpression();
+      label_7:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 35:
+        case 36:
+        case 37:
+        case 38:
+          ;
+          break;
+        default:
+          jj_la1[10] = jj_gen;
+          break label_7;
+        }
+        RelationalExpressionOperator();
+        ShiftExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void RelationalExpressionOperator() throws ParseException {
+ /*@bgen(jjtree) RelationalExpressionOperator */
+    ASTRelationalExpressionOperator jjtn000 = new ASTRelationalExpressionOperator(JJTRELATIONALEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 35:
+        t = jj_consume_token(35);
+        break;
+      case 36:
+        t = jj_consume_token(36);
+        break;
+      case 37:
+        t = jj_consume_token(37);
+        break;
+      case 38:
+        t = jj_consume_token(38);
+        break;
+      default:
+        jj_la1[11] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void ShiftExpression() throws ParseException {
+ /*@bgen(jjtree) #ShiftExpression(> 1) */
+  ASTShiftExpression jjtn000 = new ASTShiftExpression(JJTSHIFTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      AdditiveExpression();
+      label_8:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 39:
+        case 40:
+        case 41:
+          ;
+          break;
+        default:
+          jj_la1[12] = jj_gen;
+          break label_8;
+        }
+        ShiftExpressionOperator();
+        AdditiveExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void ShiftExpressionOperator() throws ParseException {
+ /*@bgen(jjtree) ShiftExpressionOperator */
+    ASTShiftExpressionOperator jjtn000 = new ASTShiftExpressionOperator(JJTSHIFTEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 39:
+        t = jj_consume_token(39);
+        break;
+      case 40:
+        t = jj_consume_token(40);
+        break;
+      case 41:
+        t = jj_consume_token(41);
+        break;
+      default:
+        jj_la1[13] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void AdditiveExpression() throws ParseException {
+ /*@bgen(jjtree) #AdditiveExpression(> 1) */
+  ASTAdditiveExpression jjtn000 = new ASTAdditiveExpression(JJTADDITIVEEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      MultiplicativeExpression();
+      label_9:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 42:
+        case 43:
+          ;
+          break;
+        default:
+          jj_la1[14] = jj_gen;
+          break label_9;
+        }
+        AdditiveExpressionOperator();
+        MultiplicativeExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void AdditiveExpressionOperator() throws ParseException {
+ /*@bgen(jjtree) AdditiveExpressionOperator */
+    ASTAdditiveExpressionOperator jjtn000 = new ASTAdditiveExpressionOperator(JJTADDITIVEEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 42:
+        t = jj_consume_token(42);
+        break;
+      case 43:
+        t = jj_consume_token(43);
+        break;
+      default:
+        jj_la1[15] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void MultiplicativeExpression() throws ParseException {
+ /*@bgen(jjtree) #MultiplicativeExpression(> 1) */
+  ASTMultiplicativeExpression jjtn000 = new ASTMultiplicativeExpression(JJTMULTIPLICATIVEEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      UnaryExpression();
+      label_10:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 44:
+        case 45:
+        case 46:
+          ;
+          break;
+        default:
+          jj_la1[16] = jj_gen;
+          break label_10;
+        }
+        MultiplicativeExpressionOperator();
+        UnaryExpression();
+      }
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+  }
+
+  final public void MultiplicativeExpressionOperator() throws ParseException {
+ /*@bgen(jjtree) MultiplicativeExpressionOperator */
+    ASTMultiplicativeExpressionOperator jjtn000 = new ASTMultiplicativeExpressionOperator(JJTMULTIPLICATIVEEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 44:
+        t = jj_consume_token(44);
+        break;
+      case 45:
+        t = jj_consume_token(45);
+        break;
+      case 46:
+        t = jj_consume_token(46);
+        break;
+      default:
+        jj_la1[17] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void UnaryExpression() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 42:
+    case 43:
+        ASTUnaryExpression jjtn001 = new ASTUnaryExpression(JJTUNARYEXPRESSION);
+        boolean jjtc001 = true;
+        jjtree.openNodeScope(jjtn001);
+      try {
+        UnaryExpressionOperator();
+        UnaryExpressionNotPlusMinus();
+      } catch (Throwable jjte001) {
+        if (jjtc001) {
+          jjtree.clearNodeScope(jjtn001);
+          jjtc001 = false;
+        } else {
+          jjtree.popNode();
+        }
+        if (jjte001 instanceof RuntimeException) {
+          {if (true) throw (RuntimeException)jjte001;}
+        }
+        if (jjte001 instanceof ParseException) {
+          {if (true) throw (ParseException)jjte001;}
+        }
+        {if (true) throw (Error)jjte001;}
+      } finally {
+        if (jjtc001) {
+          jjtree.closeNodeScope(jjtn001, true);
+        }
+      }
+      break;
+    case 47:
+      PreIncrementExpression();
+      break;
+    case 48:
+      PreDecrementExpression();
+      break;
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case IDENTIFIER:
+    case 49:
+    case 50:
+    case 51:
+      UnaryExpressionNotPlusMinus();
+      break;
+    default:
+      jj_la1[18] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+  final public void UnaryExpressionOperator() throws ParseException {
+ /*@bgen(jjtree) UnaryExpressionOperator */
+    ASTUnaryExpressionOperator jjtn000 = new ASTUnaryExpressionOperator(JJTUNARYEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 42:
+        t = jj_consume_token(42);
+        break;
+      case 43:
+        t = jj_consume_token(43);
+        break;
+      default:
+        jj_la1[19] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void PreIncrementExpression() throws ParseException {
+ /*@bgen(jjtree) PreIncrementExpression */
+  ASTPreIncrementExpression jjtn000 = new ASTPreIncrementExpression(JJTPREINCREMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(47);
+      Variable();
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void PreDecrementExpression() throws ParseException {
+ /*@bgen(jjtree) PreDecrementExpression */
+  ASTPreDecrementExpression jjtn000 = new ASTPreDecrementExpression(JJTPREDECREMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(48);
+      Variable();
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void UnaryExpressionNotPlusMinus() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 49:
+    case 50:
+        ASTUnaryExpressionNotPlusMinus jjtn001 = new ASTUnaryExpressionNotPlusMinus(JJTUNARYEXPRESSIONNOTPLUSMINUS);
+        boolean jjtc001 = true;
+        jjtree.openNodeScope(jjtn001);
+      try {
+        UnaryExpressionNotPlusMinusOperator();
+        PrimaryExpression();
+      } catch (Throwable jjte001) {
+        if (jjtc001) {
+          jjtree.clearNodeScope(jjtn001);
+          jjtc001 = false;
+        } else {
+          jjtree.popNode();
+        }
+        if (jjte001 instanceof RuntimeException) {
+          {if (true) throw (RuntimeException)jjte001;}
+        }
+        if (jjte001 instanceof ParseException) {
+          {if (true) throw (ParseException)jjte001;}
+        }
+        {if (true) throw (Error)jjte001;}
+      } finally {
+        if (jjtc001) {
+          jjtree.closeNodeScope(jjtn001, true);
+        }
+      }
+      break;
+    default:
+      jj_la1[20] = jj_gen;
+      if (jj_2_2(2)) {
+        PostIncrementExpression();
+      } else if (jj_2_3(2)) {
+        PostDecrementExpression();
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case IDENTIFIER:
+        case 51:
+          PrimaryExpression();
+          break;
+        default:
+          jj_la1[21] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+    }
+  }
+
+  final public void UnaryExpressionNotPlusMinusOperator() throws ParseException {
+ /*@bgen(jjtree) UnaryExpressionNotPlusMinusOperator */
+    ASTUnaryExpressionNotPlusMinusOperator jjtn000 = new ASTUnaryExpressionNotPlusMinusOperator(JJTUNARYEXPRESSIONNOTPLUSMINUSOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 49:
+        t = jj_consume_token(49);
+        break;
+      case 50:
+        t = jj_consume_token(50);
+        break;
+      default:
+        jj_la1[22] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void PostIncrementExpression() throws ParseException {
+ /*@bgen(jjtree) PostIncrementExpression */
+  ASTPostIncrementExpression jjtn000 = new ASTPostIncrementExpression(JJTPOSTINCREMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      Variable();
+      jj_consume_token(47);
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void PostDecrementExpression() throws ParseException {
+ /*@bgen(jjtree) PostDecrementExpression */
+  ASTPostDecrementExpression jjtn000 = new ASTPostDecrementExpression(JJTPOSTDECREMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      Variable();
+      jj_consume_token(48);
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void PrimaryExpression() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INTEGER_LITERAL:
+      IntegerLiteral();
+      break;
+    case FLOATING_POINT_LITERAL:
+      FloatingPointLiteral();
+      break;
+    default:
+      jj_la1[23] = jj_gen;
+      if (jj_2_4(2)) {
+        FunctionExpression();
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case IDENTIFIER:
+          Variable();
+          break;
+        case 51:
+          ParenthesesExpression();
+          break;
+        default:
+          jj_la1[24] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+    }
+  }
+
+  final public void IntegerLiteral() throws ParseException {
+ /*@bgen(jjtree) IntegerLiteral */
+    ASTIntegerLiteral jjtn000 = new ASTIntegerLiteral(JJTINTEGERLITERAL);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      t = jj_consume_token(INTEGER_LITERAL);
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void FloatingPointLiteral() throws ParseException {
+ /*@bgen(jjtree) FloatingPointLiteral */
+    ASTFloatingPointLiteral jjtn000 = new ASTFloatingPointLiteral(JJTFLOATINGPOINTLITERAL);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      t = jj_consume_token(FLOATING_POINT_LITERAL);
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void FunctionExpression() throws ParseException {
+ /*@bgen(jjtree) FunctionExpression */
+  ASTFunctionExpression jjtn000 = new ASTFunctionExpression(JJTFUNCTIONEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      FunctionName();
+      jj_consume_token(51);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case IDENTIFIER:
+      case 42:
+      case 43:
+      case 47:
+      case 48:
+      case 49:
+      case 50:
+      case 51:
+        AssignmentExpression();
+        label_11:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case 52:
+            ;
+            break;
+          default:
+            jj_la1[25] = jj_gen;
+            break label_11;
+          }
+          jj_consume_token(52);
+          AssignmentExpression();
+        }
+        break;
+      default:
+        jj_la1[26] = jj_gen;
+        ;
+      }
+      jj_consume_token(53);
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void Variable() throws ParseException {
+ /*@bgen(jjtree) Variable */
+    ASTVariable jjtn000 = new ASTVariable(JJTVARIABLE);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      t = jj_consume_token(IDENTIFIER);
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void ParenthesesExpression() throws ParseException {
+ /*@bgen(jjtree) ParenthesesExpression */
+  ASTParenthesesExpression jjtn000 = new ASTParenthesesExpression(JJTPARENTHESESEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(51);
+      AssignmentExpression();
+      jj_consume_token(53);
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        {if (true) throw (RuntimeException)jjte000;}
+      }
+      if (jjte000 instanceof ParseException) {
+        {if (true) throw (ParseException)jjte000;}
+      }
+      {if (true) throw (Error)jjte000;}
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final public void FunctionName() throws ParseException {
+ /*@bgen(jjtree) FunctionName */
+    ASTFunctionName jjtn000 = new ASTFunctionName(JJTFUNCTIONNAME);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);Token t;
+    try {
+      t = jj_consume_token(IDENTIFIER);
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+  }
+
+  final private boolean jj_2_1(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_1(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(0, xla); }
+  }
+
+  final private boolean jj_2_2(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_2(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(1, xla); }
+  }
+
+  final private boolean jj_2_3(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_3(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(2, xla); }
+  }
+
+  final private boolean jj_2_4(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_4(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(3, xla); }
+  }
+
+  final private boolean jj_3R_17() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  final private boolean jj_3R_15() {
+    if (jj_3R_12()) return true;
+    if (jj_scan_token(48)) return true;
+    return false;
+  }
+
+  final private boolean jj_3R_16() {
+    if (jj_3R_17()) return true;
+    if (jj_scan_token(51)) return true;
+    return false;
+  }
+
+  final private boolean jj_3_3() {
+    if (jj_3R_15()) return true;
+    return false;
+  }
+
+  final private boolean jj_3_2() {
+    if (jj_3R_14()) return true;
+    return false;
+  }
+
+  final private boolean jj_3R_14() {
+    if (jj_3R_12()) return true;
+    if (jj_scan_token(47)) return true;
+    return false;
+  }
+
+  final private boolean jj_3R_13() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(14)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(15)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(16)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(17)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(18)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(19)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(20)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(21)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(22)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(23)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(24)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(25)) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  final private boolean jj_3_4() {
+    if (jj_3R_16()) return true;
+    return false;
+  }
+
+  final private boolean jj_3_1() {
+    if (jj_3R_12()) return true;
+    if (jj_3R_13()) return true;
+    return false;
+  }
+
+  final private boolean jj_3R_12() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  public JavaCCParserTokenManager token_source;
+  JavaCharStream jj_input_stream;
+  public Token token, jj_nt;
+  private int jj_ntk;
+  private Token jj_scanpos, jj_lastpos;
+  private int jj_la;
+  public boolean lookingAhead = false;
+  private int jj_gen;
+  final private int[] jj_la1 = new int[27];
+  static private int[] jj_la1_0;
+  static private int[] jj_la1_1;
+  static {
+      jj_la1_0();
+      jj_la1_1();
+   }
+   private static void jj_la1_0() {
+      jj_la1_0 = new int[] {0xc40,0x3ffc000,0x4000000,0x10000000,0x20000000,0x40000000,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc40,0x0,0x0,0xc40,0x0,0x440,0x800,0x0,0xc40,};
+   }
+   private static void jj_la1_1() {
+      jj_la1_1 = new int[] {0xf8c00,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x6,0x6,0x78,0x78,0x380,0x380,0xc00,0xc00,0x7000,0x7000,0xf8c00,0xc00,0x60000,0x80000,0x60000,0x0,0x80000,0x100000,0xf8c00,};
+   }
+  final private JJCalls[] jj_2_rtns = new JJCalls[4];
+  private boolean jj_rescan = false;
+  private int jj_gc = 0;
+
+  public JavaCCParser(java.io.InputStream stream) {
+     this(stream, null);
+  }
+  public JavaCCParser(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source = new JavaCCParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 27; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  public void ReInit(java.io.InputStream stream) {
+     ReInit(stream, null);
+  }
+  public void ReInit(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jjtree.reset();
+    jj_gen = 0;
+    for (int i = 0; i < 27; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  public JavaCCParser(java.io.Reader stream) {
+    jj_input_stream = new JavaCharStream(stream, 1, 1);
+    token_source = new JavaCCParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 27; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  public void ReInit(java.io.Reader stream) {
+    jj_input_stream.ReInit(stream, 1, 1);
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jjtree.reset();
+    jj_gen = 0;
+    for (int i = 0; i < 27; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  public JavaCCParser(JavaCCParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 27; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  public void ReInit(JavaCCParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jjtree.reset();
+    jj_gen = 0;
+    for (int i = 0; i < 27; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  final private Token jj_consume_token(int kind) throws ParseException {
+    Token oldToken;
+    if ((oldToken = token).next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    if (token.kind == kind) {
+      jj_gen++;
+      if (++jj_gc > 100) {
+        jj_gc = 0;
+        for (int i = 0; i < jj_2_rtns.length; i++) {
+          JJCalls c = jj_2_rtns[i];
+          while (c != null) {
+            if (c.gen < jj_gen) c.first = null;
+            c = c.next;
+          }
+        }
+      }
+      return token;
+    }
+    token = oldToken;
+    jj_kind = kind;
+    throw generateParseException();
+  }
+
+  static private final class LookaheadSuccess extends java.lang.Error { }
+  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
+  final private boolean jj_scan_token(int kind) {
+    if (jj_scanpos == jj_lastpos) {
+      jj_la--;
+      if (jj_scanpos.next == null) {
+        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
+      } else {
+        jj_lastpos = jj_scanpos = jj_scanpos.next;
+      }
+    } else {
+      jj_scanpos = jj_scanpos.next;
+    }
+    if (jj_rescan) {
+      int i = 0; Token tok = token;
+      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
+      if (tok != null) jj_add_error_token(kind, i);
+    }
+    if (jj_scanpos.kind != kind) return true;
+    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
+    return false;
+  }
+
+  final public Token getNextToken() {
+    if (token.next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    jj_gen++;
+    return token;
+  }
+
+  final public Token getToken(int index) {
+    Token t = lookingAhead ? jj_scanpos : token;
+    for (int i = 0; i < index; i++) {
+      if (t.next != null) t = t.next;
+      else t = t.next = token_source.getNextToken();
+    }
+    return t;
+  }
+
+  final private int jj_ntk() {
+    if ((jj_nt=token.next) == null)
+      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+    else
+      return (jj_ntk = jj_nt.kind);
+  }
+
+  private java.util.Vector jj_expentries = new java.util.Vector();
+  private int[] jj_expentry;
+  private int jj_kind = -1;
+  private int[] jj_lasttokens = new int[100];
+  private int jj_endpos;
+
+  private void jj_add_error_token(int kind, int pos) {
+    if (pos >= 100) return;
+    if (pos == jj_endpos + 1) {
+      jj_lasttokens[jj_endpos++] = kind;
+    } else if (jj_endpos != 0) {
+      jj_expentry = new int[jj_endpos];
+      for (int i = 0; i < jj_endpos; i++) {
+        jj_expentry[i] = jj_lasttokens[i];
+      }
+      boolean exists = false;
+      for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
+        int[] oldentry = (int[])(e.nextElement());
+        if (oldentry.length == jj_expentry.length) {
+          exists = true;
+          for (int i = 0; i < jj_expentry.length; i++) {
+            if (oldentry[i] != jj_expentry[i]) {
+              exists = false;
+              break;
+            }
+          }
+          if (exists) break;
+        }
+      }
+      if (!exists) jj_expentries.addElement(jj_expentry);
+      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
+    }
+  }
+
+  public ParseException generateParseException() {
+    jj_expentries.removeAllElements();
+    boolean[] la1tokens = new boolean[54];
+    for (int i = 0; i < 54; i++) {
+      la1tokens[i] = false;
+    }
+    if (jj_kind >= 0) {
+      la1tokens[jj_kind] = true;
+      jj_kind = -1;
+    }
+    for (int i = 0; i < 27; i++) {
+      if (jj_la1[i] == jj_gen) {
+        for (int j = 0; j < 32; j++) {
+          if ((jj_la1_0[i] & (1<<j)) != 0) {
+            la1tokens[j] = true;
+          }
+          if ((jj_la1_1[i] & (1<<j)) != 0) {
+            la1tokens[32+j] = true;
+          }
+        }
+      }
+    }
+    for (int i = 0; i < 54; i++) {
+      if (la1tokens[i]) {
+        jj_expentry = new int[1];
+        jj_expentry[0] = i;
+        jj_expentries.addElement(jj_expentry);
+      }
+    }
+    jj_endpos = 0;
+    jj_rescan_token();
+    jj_add_error_token(0, 0);
+    int[][] exptokseq = new int[jj_expentries.size()][];
+    for (int i = 0; i < jj_expentries.size(); i++) {
+      exptokseq[i] = (int[])jj_expentries.elementAt(i);
+    }
+    return new ParseException(token, exptokseq, tokenImage);
+  }
+
+  final public void enable_tracing() {
+  }
+
+  final public void disable_tracing() {
+  }
+
+  final private void jj_rescan_token() {
+    jj_rescan = true;
+    for (int i = 0; i < 4; i++) {
+    try {
+      JJCalls p = jj_2_rtns[i];
+      do {
+        if (p.gen > jj_gen) {
+          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
+          switch (i) {
+            case 0: jj_3_1(); break;
+            case 1: jj_3_2(); break;
+            case 2: jj_3_3(); break;
+            case 3: jj_3_4(); break;
+          }
+        }
+        p = p.next;
+      } while (p != null);
+      } catch(LookaheadSuccess ls) { }
+    }
+    jj_rescan = false;
+  }
+
+  final private void jj_save(int index, int xla) {
+    JJCalls p = jj_2_rtns[index];
+    while (p.gen > jj_gen) {
+      if (p.next == null) { p = p.next = new JJCalls(); break; }
+      p = p.next;
+    }
+    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
+  }
+
+  static final class JJCalls {
+    int gen;
+    Token first;
+    int arg;
+    JJCalls next;
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserConstants.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserConstants.java
new file mode 100644 (file)
index 0000000..3bb4a9d
--- /dev/null
@@ -0,0 +1,75 @@
+/* Generated By:JJTree&JavaCC: Do not edit this line. JavaCCParserConstants.java */
+package jp.sourceforge.expression_computer.javacc;
+
+public interface JavaCCParserConstants {
+
+  int EOF = 0;
+  int INTEGER_LITERAL = 6;
+  int DECIMAL_LITERAL = 7;
+  int HEX_LITERAL = 8;
+  int OCTAL_LITERAL = 9;
+  int FLOATING_POINT_LITERAL = 10;
+  int IDENTIFIER = 11;
+  int LETTER = 12;
+  int DIGIT = 13;
+
+  int DEFAULT = 0;
+
+  String[] tokenImage = {
+    "<EOF>",
+    "\" \"",
+    "\"\\t\"",
+    "\"\\n\"",
+    "\"\\r\"",
+    "\"\\f\"",
+    "<INTEGER_LITERAL>",
+    "<DECIMAL_LITERAL>",
+    "<HEX_LITERAL>",
+    "<OCTAL_LITERAL>",
+    "<FLOATING_POINT_LITERAL>",
+    "<IDENTIFIER>",
+    "<LETTER>",
+    "<DIGIT>",
+    "\"=\"",
+    "\"+=\"",
+    "\"-=\"",
+    "\"*=\"",
+    "\"/=\"",
+    "\"%=\"",
+    "\"&=\"",
+    "\"^=\"",
+    "\"|=\"",
+    "\"<<=\"",
+    "\">>=\"",
+    "\">>>=\"",
+    "\"?\"",
+    "\":\"",
+    "\"||\"",
+    "\"&&\"",
+    "\"|\"",
+    "\"^\"",
+    "\"&\"",
+    "\"==\"",
+    "\"!=\"",
+    "\">\"",
+    "\"<\"",
+    "\">=\"",
+    "\"<=\"",
+    "\"<<\"",
+    "\">>\"",
+    "\">>>\"",
+    "\"+\"",
+    "\"-\"",
+    "\"*\"",
+    "\"/\"",
+    "\"%\"",
+    "\"++\"",
+    "\"--\"",
+    "\"~\"",
+    "\"!\"",
+    "\"(\"",
+    "\",\"",
+    "\")\"",
+  };
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserTokenManager.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserTokenManager.java
new file mode 100644 (file)
index 0000000..42257d3
--- /dev/null
@@ -0,0 +1,574 @@
+/* Generated By:JJTree&JavaCC: Do not edit this line. JavaCCParserTokenManager.java */
+package jp.sourceforge.expression_computer.javacc;
+
+public class JavaCCParserTokenManager implements JavaCCParserConstants
+{
+  public  java.io.PrintStream debugStream = System.out;
+  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjStopStringLiteralDfa_0(int pos, long active0)
+{
+   switch (pos)
+   {
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_0(int pos, long active0)
+{
+   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
+}
+private final int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private final int jjMoveStringLiteralDfa0_0()
+{
+   switch(curChar)
+   {
+      case 33:
+         jjmatchedKind = 50;
+         return jjMoveStringLiteralDfa1_0(0x400000000L);
+      case 37:
+         jjmatchedKind = 46;
+         return jjMoveStringLiteralDfa1_0(0x80000L);
+      case 38:
+         jjmatchedKind = 32;
+         return jjMoveStringLiteralDfa1_0(0x20100000L);
+      case 40:
+         return jjStopAtPos(0, 51);
+      case 41:
+         return jjStopAtPos(0, 53);
+      case 42:
+         jjmatchedKind = 44;
+         return jjMoveStringLiteralDfa1_0(0x20000L);
+      case 43:
+         jjmatchedKind = 42;
+         return jjMoveStringLiteralDfa1_0(0x800000008000L);
+      case 44:
+         return jjStopAtPos(0, 52);
+      case 45:
+         jjmatchedKind = 43;
+         return jjMoveStringLiteralDfa1_0(0x1000000010000L);
+      case 47:
+         jjmatchedKind = 45;
+         return jjMoveStringLiteralDfa1_0(0x40000L);
+      case 58:
+         return jjStopAtPos(0, 27);
+      case 60:
+         jjmatchedKind = 36;
+         return jjMoveStringLiteralDfa1_0(0xc000800000L);
+      case 61:
+         jjmatchedKind = 14;
+         return jjMoveStringLiteralDfa1_0(0x200000000L);
+      case 62:
+         jjmatchedKind = 35;
+         return jjMoveStringLiteralDfa1_0(0x32003000000L);
+      case 63:
+         return jjStopAtPos(0, 26);
+      case 94:
+         jjmatchedKind = 31;
+         return jjMoveStringLiteralDfa1_0(0x200000L);
+      case 124:
+         jjmatchedKind = 30;
+         return jjMoveStringLiteralDfa1_0(0x10400000L);
+      case 126:
+         return jjStopAtPos(0, 49);
+      default :
+         return jjMoveNfa_0(0, 0);
+   }
+}
+private final int jjMoveStringLiteralDfa1_0(long active0)
+{
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(0, active0);
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 38:
+         if ((active0 & 0x20000000L) != 0L)
+            return jjStopAtPos(1, 29);
+         break;
+      case 43:
+         if ((active0 & 0x800000000000L) != 0L)
+            return jjStopAtPos(1, 47);
+         break;
+      case 45:
+         if ((active0 & 0x1000000000000L) != 0L)
+            return jjStopAtPos(1, 48);
+         break;
+      case 60:
+         if ((active0 & 0x8000000000L) != 0L)
+         {
+            jjmatchedKind = 39;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0x800000L);
+      case 61:
+         if ((active0 & 0x8000L) != 0L)
+            return jjStopAtPos(1, 15);
+         else if ((active0 & 0x10000L) != 0L)
+            return jjStopAtPos(1, 16);
+         else if ((active0 & 0x20000L) != 0L)
+            return jjStopAtPos(1, 17);
+         else if ((active0 & 0x40000L) != 0L)
+            return jjStopAtPos(1, 18);
+         else if ((active0 & 0x80000L) != 0L)
+            return jjStopAtPos(1, 19);
+         else if ((active0 & 0x100000L) != 0L)
+            return jjStopAtPos(1, 20);
+         else if ((active0 & 0x200000L) != 0L)
+            return jjStopAtPos(1, 21);
+         else if ((active0 & 0x400000L) != 0L)
+            return jjStopAtPos(1, 22);
+         else if ((active0 & 0x200000000L) != 0L)
+            return jjStopAtPos(1, 33);
+         else if ((active0 & 0x400000000L) != 0L)
+            return jjStopAtPos(1, 34);
+         else if ((active0 & 0x2000000000L) != 0L)
+            return jjStopAtPos(1, 37);
+         else if ((active0 & 0x4000000000L) != 0L)
+            return jjStopAtPos(1, 38);
+         break;
+      case 62:
+         if ((active0 & 0x10000000000L) != 0L)
+         {
+            jjmatchedKind = 40;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0x20003000000L);
+      case 124:
+         if ((active0 & 0x10000000L) != 0L)
+            return jjStopAtPos(1, 28);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(0, active0);
+}
+private final int jjMoveStringLiteralDfa2_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(0, old0); 
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(1, active0);
+      return 2;
+   }
+   switch(curChar)
+   {
+      case 61:
+         if ((active0 & 0x800000L) != 0L)
+            return jjStopAtPos(2, 23);
+         else if ((active0 & 0x1000000L) != 0L)
+            return jjStopAtPos(2, 24);
+         break;
+      case 62:
+         if ((active0 & 0x20000000000L) != 0L)
+         {
+            jjmatchedKind = 41;
+            jjmatchedPos = 2;
+         }
+         return jjMoveStringLiteralDfa3_0(active0, 0x2000000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(1, active0);
+}
+private final int jjMoveStringLiteralDfa3_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(1, old0); 
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(2, active0);
+      return 3;
+   }
+   switch(curChar)
+   {
+      case 61:
+         if ((active0 & 0x2000000L) != 0L)
+            return jjStopAtPos(3, 25);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(2, active0);
+}
+private final void jjCheckNAdd(int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
+private final void jjCheckNAddTwoStates(int state1, int state2)
+{
+   jjCheckNAdd(state1);
+   jjCheckNAdd(state2);
+}
+static final long[] jjbitVec0 = {
+   0x1ff00000fffffffeL, 0xffffffffffffc000L, 0xffffffffL, 0x600000000000000L
+};
+static final long[] jjbitVec2 = {
+   0x0L, 0x0L, 0x0L, 0xff7fffffff7fffffL
+};
+static final long[] jjbitVec3 = {
+   0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec4 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffL, 0x0L
+};
+static final long[] jjbitVec5 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0x0L, 0x0L
+};
+static final long[] jjbitVec6 = {
+   0x3fffffffffffL, 0x0L, 0x0L, 0x0L
+};
+private final int jjMoveNfa_0(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 13;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(2, 3);
+                  else if (curChar == 36)
+                  {
+                     if (kind > 11)
+                        kind = 11;
+                     jjCheckNAdd(8);
+                  }
+                  else if (curChar == 46)
+                     jjCheckNAdd(6);
+                  if ((0x3fe000000000000L & l) != 0L)
+                  {
+                     if (kind > 6)
+                        kind = 6;
+                     jjCheckNAdd(1);
+                  }
+                  else if (curChar == 48)
+                  {
+                     if (kind > 6)
+                        kind = 6;
+                     jjCheckNAddTwoStates(10, 12);
+                  }
+                  break;
+               case 1:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 6)
+                     kind = 6;
+                  jjCheckNAdd(1);
+                  break;
+               case 2:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(2, 3);
+                  break;
+               case 3:
+                  if (curChar == 46)
+                     jjCheckNAdd(4);
+                  break;
+               case 4:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 10)
+                     kind = 10;
+                  jjCheckNAdd(4);
+                  break;
+               case 5:
+                  if (curChar == 46)
+                     jjCheckNAdd(6);
+                  break;
+               case 6:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 10)
+                     kind = 10;
+                  jjCheckNAdd(6);
+                  break;
+               case 7:
+                  if (curChar != 36)
+                     break;
+                  if (kind > 11)
+                     kind = 11;
+                  jjCheckNAdd(8);
+                  break;
+               case 8:
+                  if ((0x3ff001000000000L & l) == 0L)
+                     break;
+                  if (kind > 11)
+                     kind = 11;
+                  jjCheckNAdd(8);
+                  break;
+               case 9:
+                  if (curChar != 48)
+                     break;
+                  if (kind > 6)
+                     kind = 6;
+                  jjCheckNAddTwoStates(10, 12);
+                  break;
+               case 11:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 6)
+                     kind = 6;
+                  jjstateSet[jjnewStateCnt++] = 11;
+                  break;
+               case 12:
+                  if ((0xff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 6)
+                     kind = 6;
+                  jjCheckNAdd(12);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+               case 8:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 11)
+                     kind = 11;
+                  jjCheckNAdd(8);
+                  break;
+               case 10:
+                  if ((0x100000001000000L & l) != 0L)
+                     jjCheckNAdd(11);
+                  break;
+               case 11:
+                  if ((0x7e0000007eL & l) == 0L)
+                     break;
+                  if (kind > 6)
+                     kind = 6;
+                  jjCheckNAdd(11);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+               case 8:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 11)
+                     kind = 11;
+                  jjCheckNAdd(8);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 13 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+static final int[] jjnextStates = {
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec2[i2] & l2) != 0L);
+      case 48:
+         return ((jjbitVec3[i2] & l2) != 0L);
+      case 49:
+         return ((jjbitVec4[i2] & l2) != 0L);
+      case 51:
+         return ((jjbitVec5[i2] & l2) != 0L);
+      case 61:
+         return ((jjbitVec6[i2] & l2) != 0L);
+      default : 
+         if ((jjbitVec0[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, null, null, null, null, null, 
+null, "\75", "\53\75", "\55\75", "\52\75", "\57\75", "\45\75", "\46\75", "\136\75", 
+"\174\75", "\74\74\75", "\76\76\75", "\76\76\76\75", "\77", "\72", "\174\174", "\46\46", 
+"\174", "\136", "\46", "\75\75", "\41\75", "\76", "\74", "\76\75", "\74\75", "\74\74", 
+"\76\76", "\76\76\76", "\53", "\55", "\52", "\57", "\45", "\53\53", "\55\55", "\176", 
+"\41", "\50", "\54", "\51", };
+public static final String[] lexStateNames = {
+   "DEFAULT", 
+};
+static final long[] jjtoToken = {
+   0x3fffffffffcc41L, 
+};
+static final long[] jjtoSkip = {
+   0x3eL, 
+};
+protected JavaCharStream input_stream;
+private final int[] jjrounds = new int[13];
+private final int[] jjstateSet = new int[26];
+protected char curChar;
+public JavaCCParserTokenManager(JavaCharStream stream){
+   if (JavaCharStream.staticFlag)
+      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+   input_stream = stream;
+}
+public JavaCCParserTokenManager(JavaCharStream stream, int lexState){
+   this(stream);
+   SwitchTo(lexState);
+}
+public void ReInit(JavaCharStream stream)
+{
+   jjmatchedPos = jjnewStateCnt = 0;
+   curLexState = defaultLexState;
+   input_stream = stream;
+   ReInitRounds();
+}
+private final void ReInitRounds()
+{
+   int i;
+   jjround = 0x80000001;
+   for (i = 13; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+}
+public void ReInit(JavaCharStream stream, int lexState)
+{
+   ReInit(stream);
+   SwitchTo(lexState);
+}
+public void SwitchTo(int lexState)
+{
+   if (lexState >= 1 || lexState < 0)
+      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+   else
+      curLexState = lexState;
+}
+
+protected Token jjFillToken()
+{
+   Token t = Token.newToken(jjmatchedKind);
+   t.kind = jjmatchedKind;
+   String im = jjstrLiteralImages[jjmatchedKind];
+   t.image = (im == null) ? input_stream.GetImage() : im;
+   t.beginLine = input_stream.getBeginLine();
+   t.beginColumn = input_stream.getBeginColumn();
+   t.endLine = input_stream.getEndLine();
+   t.endColumn = input_stream.getEndColumn();
+   return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+public Token getNextToken() 
+{
+  Token matchedToken;
+  int curPos = 0;
+
+  EOFLoop :
+  for (;;)
+  {   
+   try   
+   {     
+      curChar = input_stream.BeginToken();
+   }     
+   catch(java.io.IOException e)
+   {        
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      return matchedToken;
+   }
+
+   try { input_stream.backup(0);
+      while (curChar <= 32 && (0x100003600L & (1L << curChar)) != 0L)
+         curChar = input_stream.BeginToken();
+   }
+   catch (java.io.IOException e1) { continue EOFLoop; }
+   jjmatchedKind = 0x7fffffff;
+   jjmatchedPos = 0;
+   curPos = jjMoveStringLiteralDfa0_0();
+   if (jjmatchedKind != 0x7fffffff)
+   {
+      if (jjmatchedPos + 1 < curPos)
+         input_stream.backup(curPos - jjmatchedPos - 1);
+      if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+      {
+         matchedToken = jjFillToken();
+         return matchedToken;
+      }
+      else
+      {
+         continue EOFLoop;
+      }
+   }
+   int error_line = input_stream.getEndLine();
+   int error_column = input_stream.getEndColumn();
+   String error_after = null;
+   boolean EOFSeen = false;
+   try { input_stream.readChar(); input_stream.backup(1); }
+   catch (java.io.IOException e1) {
+      EOFSeen = true;
+      error_after = curPos <= 1 ? "" : input_stream.GetImage();
+      if (curChar == '\n' || curChar == '\r') {
+         error_line++;
+         error_column = 0;
+      }
+      else
+         error_column++;
+   }
+   if (!EOFSeen) {
+      input_stream.backup(1);
+      error_after = curPos <= 1 ? "" : input_stream.GetImage();
+   }
+   throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+  }
+}
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserTreeConstants.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCCParserTreeConstants.java
new file mode 100644 (file)
index 0000000..a2ddc33
--- /dev/null
@@ -0,0 +1,79 @@
+/* Generated By:JJTree: Do not edit this line. .\JavaCCParserTreeConstants.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public interface JavaCCParserTreeConstants
+{
+  public int JJTEXPRESSION = 0;
+  public int JJTASSIGNMENTEXPRESSION = 1;
+  public int JJTASSIGNMENTEXPRESSIONOPERATOR = 2;
+  public int JJTCONDITIONALEXPRESSION = 3;
+  public int JJTCONDITIONALOREXPRESSION = 4;
+  public int JJTCONDITIONALANDEXPRESSION = 5;
+  public int JJTINCLUSIVEOREXPRESSION = 6;
+  public int JJTEXCLUSIVEOREXPRESSION = 7;
+  public int JJTANDEXPRESSION = 8;
+  public int JJTEQUALITYEXPRESSION = 9;
+  public int JJTEQUALITYEXPRESSIONOPERATOR = 10;
+  public int JJTRELATIONALEXPRESSION = 11;
+  public int JJTRELATIONALEXPRESSIONOPERATOR = 12;
+  public int JJTSHIFTEXPRESSION = 13;
+  public int JJTSHIFTEXPRESSIONOPERATOR = 14;
+  public int JJTADDITIVEEXPRESSION = 15;
+  public int JJTADDITIVEEXPRESSIONOPERATOR = 16;
+  public int JJTMULTIPLICATIVEEXPRESSION = 17;
+  public int JJTMULTIPLICATIVEEXPRESSIONOPERATOR = 18;
+  public int JJTVOID = 19;
+  public int JJTUNARYEXPRESSION = 20;
+  public int JJTUNARYEXPRESSIONOPERATOR = 21;
+  public int JJTPREINCREMENTEXPRESSION = 22;
+  public int JJTPREDECREMENTEXPRESSION = 23;
+  public int JJTUNARYEXPRESSIONNOTPLUSMINUS = 24;
+  public int JJTUNARYEXPRESSIONNOTPLUSMINUSOPERATOR = 25;
+  public int JJTPOSTINCREMENTEXPRESSION = 26;
+  public int JJTPOSTDECREMENTEXPRESSION = 27;
+  public int JJTINTEGERLITERAL = 28;
+  public int JJTFLOATINGPOINTLITERAL = 29;
+  public int JJTFUNCTIONEXPRESSION = 30;
+  public int JJTVARIABLE = 31;
+  public int JJTPARENTHESESEXPRESSION = 32;
+  public int JJTFUNCTIONNAME = 33;
+
+
+  public String[] jjtNodeName = {
+    "Expression",
+    "AssignmentExpression",
+    "AssignmentExpressionOperator",
+    "ConditionalExpression",
+    "ConditionalOrExpression",
+    "ConditionalAndExpression",
+    "InclusiveOrExpression",
+    "ExclusiveOrExpression",
+    "AndExpression",
+    "EqualityExpression",
+    "EqualityExpressionOperator",
+    "RelationalExpression",
+    "RelationalExpressionOperator",
+    "ShiftExpression",
+    "ShiftExpressionOperator",
+    "AdditiveExpression",
+    "AdditiveExpressionOperator",
+    "MultiplicativeExpression",
+    "MultiplicativeExpressionOperator",
+    "void",
+    "UnaryExpression",
+    "UnaryExpressionOperator",
+    "PreIncrementExpression",
+    "PreDecrementExpression",
+    "UnaryExpressionNotPlusMinus",
+    "UnaryExpressionNotPlusMinusOperator",
+    "PostIncrementExpression",
+    "PostDecrementExpression",
+    "IntegerLiteral",
+    "FloatingPointLiteral",
+    "FunctionExpression",
+    "Variable",
+    "ParenthesesExpression",
+    "FunctionName",
+  };
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCharStream.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/JavaCharStream.java
new file mode 100644 (file)
index 0000000..a5caed8
--- /dev/null
@@ -0,0 +1,584 @@
+/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 4.0 */
+package jp.sourceforge.expression_computer.javacc;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (with java-like unicode escape processing).
+ */
+
+public class JavaCharStream
+{
+  public static final boolean staticFlag = false;
+  static final int hexval(char c) throws java.io.IOException {
+    switch(c)
+    {
+       case '0' :
+          return 0;
+       case '1' :
+          return 1;
+       case '2' :
+          return 2;
+       case '3' :
+          return 3;
+       case '4' :
+          return 4;
+       case '5' :
+          return 5;
+       case '6' :
+          return 6;
+       case '7' :
+          return 7;
+       case '8' :
+          return 8;
+       case '9' :
+          return 9;
+
+       case 'a' :
+       case 'A' :
+          return 10;
+       case 'b' :
+       case 'B' :
+          return 11;
+       case 'c' :
+       case 'C' :
+          return 12;
+       case 'd' :
+       case 'D' :
+          return 13;
+       case 'e' :
+       case 'E' :
+          return 14;
+       case 'f' :
+       case 'F' :
+          return 15;
+    }
+
+    throw new java.io.IOException(); // Should never come here
+  }
+
+  public int bufpos = -1;
+  int bufsize;
+  int available;
+  int tokenBegin;
+  protected int bufline[];
+  protected int bufcolumn[];
+
+  protected int column = 0;
+  protected int line = 1;
+
+  protected boolean prevCharIsCR = false;
+  protected boolean prevCharIsLF = false;
+
+  protected java.io.Reader inputStream;
+
+  protected char[] nextCharBuf;
+  protected char[] buffer;
+  protected int maxNextCharInd = 0;
+  protected int nextCharInd = -1;
+  protected int inBuf = 0;
+  protected int tabSize = 8;
+
+  protected void setTabSize(int i) { tabSize = i; }
+  protected int getTabSize(int i) { return tabSize; }
+
+  protected void ExpandBuff(boolean wrapAround)
+  {
+     char[] newbuffer = new char[bufsize + 2048];
+     int newbufline[] = new int[bufsize + 2048];
+     int newbufcolumn[] = new int[bufsize + 2048];
+
+     try
+     {
+        if (wrapAround)
+        {
+           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+           System.arraycopy(buffer, 0, newbuffer,
+                                             bufsize - tokenBegin, bufpos);
+           buffer = newbuffer;
+
+           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+           bufline = newbufline;
+
+           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+           bufcolumn = newbufcolumn;
+
+           bufpos += (bufsize - tokenBegin);
+        }
+        else
+        {
+           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+           buffer = newbuffer;
+
+           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+           bufline = newbufline;
+
+           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+           bufcolumn = newbufcolumn;
+
+           bufpos -= tokenBegin;
+        }
+     }
+     catch (Throwable t)
+     {
+        throw new Error(t.getMessage());
+     }
+
+     available = (bufsize += 2048);
+     tokenBegin = 0;
+  }
+
+  protected void FillBuff() throws java.io.IOException
+  {
+     int i;
+     if (maxNextCharInd == 4096)
+        maxNextCharInd = nextCharInd = 0;
+
+     try {
+        if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
+                                            4096 - maxNextCharInd)) == -1)
+        {
+           inputStream.close();
+           throw new java.io.IOException();
+        }
+        else
+           maxNextCharInd += i;
+        return;
+     }
+     catch(java.io.IOException e) {
+        if (bufpos != 0)
+        {
+           --bufpos;
+           backup(0);
+        }
+        else
+        {
+           bufline[bufpos] = line;
+           bufcolumn[bufpos] = column;
+        }
+        throw e;
+     }
+  }
+
+  protected char ReadByte() throws java.io.IOException
+  {
+     if (++nextCharInd >= maxNextCharInd)
+        FillBuff();
+
+     return nextCharBuf[nextCharInd];
+  }
+
+  public char BeginToken() throws java.io.IOException
+  {     
+     if (inBuf > 0)
+     {
+        --inBuf;
+
+        if (++bufpos == bufsize)
+           bufpos = 0;
+
+        tokenBegin = bufpos;
+        return buffer[bufpos];
+     }
+
+     tokenBegin = 0;
+     bufpos = -1;
+
+     return readChar();
+  }     
+
+  protected void AdjustBuffSize()
+  {
+     if (available == bufsize)
+     {
+        if (tokenBegin > 2048)
+        {
+           bufpos = 0;
+           available = tokenBegin;
+        }
+        else
+           ExpandBuff(false);
+     }
+     else if (available > tokenBegin)
+        available = bufsize;
+     else if ((tokenBegin - available) < 2048)
+        ExpandBuff(true);
+     else
+        available = tokenBegin;
+  }
+
+  protected void UpdateLineColumn(char c)
+  {
+     column++;
+
+     if (prevCharIsLF)
+     {
+        prevCharIsLF = false;
+        line += (column = 1);
+     }
+     else if (prevCharIsCR)
+     {
+        prevCharIsCR = false;
+        if (c == '\n')
+        {
+           prevCharIsLF = true;
+        }
+        else
+           line += (column = 1);
+     }
+
+     switch (c)
+     {
+        case '\r' :
+           prevCharIsCR = true;
+           break;
+        case '\n' :
+           prevCharIsLF = true;
+           break;
+        case '\t' :
+           column--;
+           column += (tabSize - (column % tabSize));
+           break;
+        default :
+           break;
+     }
+
+     bufline[bufpos] = line;
+     bufcolumn[bufpos] = column;
+  }
+
+  public char readChar() throws java.io.IOException
+  {
+     if (inBuf > 0)
+     {
+        --inBuf;
+
+        if (++bufpos == bufsize)
+           bufpos = 0;
+
+        return buffer[bufpos];
+     }
+
+     char c;
+
+     if (++bufpos == available)
+        AdjustBuffSize();
+
+     if ((buffer[bufpos] = c = ReadByte()) == '\\')
+     {
+        UpdateLineColumn(c);
+
+        int backSlashCnt = 1;
+
+        for (;;) // Read all the backslashes
+        {
+           if (++bufpos == available)
+              AdjustBuffSize();
+
+           try
+           {
+              if ((buffer[bufpos] = c = ReadByte()) != '\\')
+              {
+                 UpdateLineColumn(c);
+                 // found a non-backslash char.
+                 if ((c == 'u') && ((backSlashCnt & 1) == 1))
+                 {
+                    if (--bufpos < 0)
+                       bufpos = bufsize - 1;
+
+                    break;
+                 }
+
+                 backup(backSlashCnt);
+                 return '\\';
+              }
+           }
+           catch(java.io.IOException e)
+           {
+              if (backSlashCnt > 1)
+                 backup(backSlashCnt);
+
+              return '\\';
+           }
+
+           UpdateLineColumn(c);
+           backSlashCnt++;
+        }
+
+        // Here, we have seen an odd number of backslash's followed by a 'u'
+        try
+        {
+           while ((c = ReadByte()) == 'u')
+              ++column;
+
+           buffer[bufpos] = c = (char)(hexval(c) << 12 |
+                                       hexval(ReadByte()) << 8 |
+                                       hexval(ReadByte()) << 4 |
+                                       hexval(ReadByte()));
+
+           column += 4;
+        }
+        catch(java.io.IOException e)
+        {
+           throw new Error("Invalid escape character at line " + line +
+                                         " column " + column + ".");
+        }
+
+        if (backSlashCnt == 1)
+           return c;
+        else
+        {
+           backup(backSlashCnt - 1);
+           return '\\';
+        }
+     }
+     else
+     {
+        UpdateLineColumn(c);
+        return (c);
+     }
+  }
+
+  /**
+   * @deprecated 
+   * @see #getEndColumn
+   */
+
+  public int getColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  /**
+   * @deprecated 
+   * @see #getEndLine
+   */
+
+  public int getLine() {
+     return bufline[bufpos];
+  }
+
+  public int getEndColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  public int getEndLine() {
+     return bufline[bufpos];
+  }
+
+  public int getBeginColumn() {
+     return bufcolumn[tokenBegin];
+  }
+
+  public int getBeginLine() {
+     return bufline[tokenBegin];
+  }
+
+  public void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+       bufpos += bufsize;
+  }
+
+  public JavaCharStream(java.io.Reader dstream,
+                 int startline, int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+    nextCharBuf = new char[4096];
+  }
+
+  public JavaCharStream(java.io.Reader dstream,
+                                        int startline, int startcolumn)
+  {
+     this(dstream, startline, startcolumn, 4096);
+  }
+
+  public JavaCharStream(java.io.Reader dstream)
+  {
+     this(dstream, 1, 1, 4096);
+  }
+  public void ReInit(java.io.Reader dstream,
+                 int startline, int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+      nextCharBuf = new char[4096];
+    }
+    prevCharIsLF = prevCharIsCR = false;
+    tokenBegin = inBuf = maxNextCharInd = 0;
+    nextCharInd = bufpos = -1;
+  }
+
+  public void ReInit(java.io.Reader dstream,
+                                        int startline, int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
+  }
+
+  public void ReInit(java.io.Reader dstream)
+  {
+     ReInit(dstream, 1, 1, 4096);
+  }
+  public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  public JavaCharStream(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+     this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
+  }
+
+  public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
+                        int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+     this(dstream, encoding, startline, startcolumn, 4096);
+  }
+
+  public JavaCharStream(java.io.InputStream dstream, int startline,
+                        int startcolumn)
+  {
+     this(dstream, startline, startcolumn, 4096);
+  }
+
+  public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+     this(dstream, encoding, 1, 1, 4096);
+  }
+
+  public JavaCharStream(java.io.InputStream dstream)
+  {
+     this(dstream, 1, 1, 4096);
+  }
+
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  public void ReInit(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                     int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(dstream, encoding, startline, startcolumn, 4096);
+  }
+  public void ReInit(java.io.InputStream dstream, int startline,
+                     int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
+  }
+  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(dstream, encoding, 1, 1, 4096);
+  }
+
+  public void ReInit(java.io.InputStream dstream)
+  {
+     ReInit(dstream, 1, 1, 4096);
+  }
+
+  public String GetImage()
+  {
+     if (bufpos >= tokenBegin)
+        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+     else
+        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                              new String(buffer, 0, bufpos + 1);
+  }
+
+  public char[] GetSuffix(int len)
+  {
+     char[] ret = new char[len];
+
+     if ((bufpos + 1) >= len)
+        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+     else
+     {
+        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                          len - bufpos - 1);
+        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+     }
+
+     return ret;
+  }
+
+  public void Done()
+  {
+     nextCharBuf = null;
+     buffer = null;
+     bufline = null;
+     bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.
+   */
+  public void adjustBeginLineColumn(int newLine, int newCol)
+  {
+     int start = tokenBegin;
+     int len;
+
+     if (bufpos >= tokenBegin)
+     {
+        len = bufpos - tokenBegin + inBuf + 1;
+     }
+     else
+     {
+        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+     }
+
+     int i = 0, j = 0, k = 0;
+     int nextColDiff = 0, columnDiff = 0;
+
+     while (i < len &&
+            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+     {
+        bufline[j] = newLine;
+        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+        bufcolumn[j] = newCol + columnDiff;
+        columnDiff = nextColDiff;
+        i++;
+     } 
+
+     if (i < len)
+     {
+        bufline[j] = newLine++;
+        bufcolumn[j] = newCol + columnDiff;
+
+        while (i++ < len)
+        {
+           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+              bufline[j] = newLine++;
+           else
+              bufline[j] = newLine;
+        }
+     }
+
+     line = bufline[j];
+     column = bufcolumn[j];
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/Node.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/Node.java
new file mode 100644 (file)
index 0000000..18b87ab
--- /dev/null
@@ -0,0 +1,34 @@
+/* Generated By:JJTree: Do not edit this line. Node.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+/* All AST nodes must implement this interface.  It provides basic
+   machinery for constructing the parent and child relationships
+   between nodes. */
+
+public interface Node {
+
+  /** This method is called after the node has been made the current
+    node.  It indicates that child nodes can now be added to it. */
+  public void jjtOpen();
+
+  /** This method is called after all the child nodes have been
+    added. */
+  public void jjtClose();
+
+  /** This pair of methods are used to inform the node of its
+    parent. */
+  public void jjtSetParent(Node n);
+  public Node jjtGetParent();
+
+  /** This method tells the node to add its argument to the node's
+    list of children.  */
+  public void jjtAddChild(Node n, int i);
+
+  /** This method returns a child node.  The children are numbered
+     from zero, left to right. */
+  public Node jjtGetChild(int i);
+
+  /** Return the number of children the node has. */
+  public int jjtGetNumChildren();
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ParseException.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/ParseException.java
new file mode 100644 (file)
index 0000000..d5908e3
--- /dev/null
@@ -0,0 +1,192 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
+package jp.sourceforge.expression_computer.javacc;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+  /**
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.  The boolean
+   * flag "specialConstructor" is also set to true to indicate that
+   * this constructor was used to create this object.
+   * This constructor calls its super class with the empty string
+   * to force the "toString" method of parent class "Throwable" to
+   * print the error message in the form:
+   *     ParseException: <result of getMessage>
+   */
+  public ParseException(Token currentTokenVal,
+                        int[][] expectedTokenSequencesVal,
+                        String[] tokenImageVal
+                       )
+  {
+    super("");
+    specialConstructor = true;
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    super();
+    specialConstructor = false;
+  }
+
+  public ParseException(String message) {
+    super(message);
+    specialConstructor = false;
+  }
+
+  /**
+   * This variable determines which constructor was used to create
+   * this object and thereby affects the semantics of the
+   * "getMessage" method (see below).
+   */
+  protected boolean specialConstructor;
+
+  /**
+   * This is the last token that has been consumed successfully.  If
+   * this object has been created due to a parse error, the token
+   * followng this token will (therefore) be the first error token.
+   */
+  public Token currentToken;
+
+  /**
+   * Each entry in this array is an array of integers.  Each array
+   * of integers represents a sequence of tokens (by their ordinal
+   * values) that is expected at this point of the parse.
+   */
+  public int[][] expectedTokenSequences;
+
+  /**
+   * This is a reference to the "tokenImage" array of the generated
+   * parser within which the parse error occurred.  This array is
+   * defined in the generated ...Constants interface.
+   */
+  public String[] tokenImage;
+
+  /**
+   * This method has the standard behavior when this object has been
+   * created using the standard constructors.  Otherwise, it uses
+   * "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser), then this method is called during the printing
+   * of the final stack trace, and hence the correct error message
+   * gets displayed.
+   */
+  public String getMessage() {
+    if (!specialConstructor) {
+      return super.getMessage();
+    }
+    StringBuffer expected = new StringBuffer();
+    int maxSize = 0;
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
+      if (maxSize < expectedTokenSequences[i].length) {
+        maxSize = expectedTokenSequences[i].length;
+      }
+      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" ");
+      }
+      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+        expected.append("...");
+      }
+      expected.append(eol).append("    ");
+    }
+    String retval = "Encountered \"";
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      if (i != 0) retval += " ";
+      if (tok.kind == 0) {
+        retval += tokenImage[0];
+        break;
+      }
+      retval += add_escapes(tok.image);
+      tok = tok.next; 
+    }
+    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+    retval += "." + eol;
+    if (expectedTokenSequences.length == 1) {
+      retval += "Was expecting:" + eol + "    ";
+    } else {
+      retval += "Was expecting one of:" + eol + "    ";
+    }
+    retval += expected.toString();
+    return retval;
+  }
+
+  /**
+   * The end of line string for this machine.
+   */
+  protected String eol = System.getProperty("line.separator", "\n");
+  /**
+   * Used to convert raw characters to their escaped version
+   * when these raw version cannot be used as part of an ASCII
+   * string literal.
+   */
+  protected String add_escapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/SimpleNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/SimpleNode.java
new file mode 100644 (file)
index 0000000..22123fd
--- /dev/null
@@ -0,0 +1,72 @@
+/* Generated By:JJTree: Do not edit this line. SimpleNode.java */
+
+package jp.sourceforge.expression_computer.javacc;
+
+public class SimpleNode extends jp.sourceforge.expression_computer.javacc.BaseNode implements Node {
+  protected Node parent;
+  protected Node[] children;
+  protected int id;
+  protected JavaCCParser parser;
+
+  public SimpleNode(int i) {
+    id = i;
+  }
+
+  public SimpleNode(JavaCCParser p, int i) {
+    this(i);
+    parser = p;
+  }
+
+  public void jjtOpen() {
+  }
+
+  public void jjtClose() {
+  }
+  
+  public void jjtSetParent(Node n) { parent = n; }
+  public Node jjtGetParent() { return parent; }
+
+  public void jjtAddChild(Node n, int i) {
+    if (children == null) {
+      children = new Node[i + 1];
+    } else if (i >= children.length) {
+      Node c[] = new Node[i + 1];
+      System.arraycopy(children, 0, c, 0, children.length);
+      children = c;
+    }
+    children[i] = n;
+  }
+
+  public Node jjtGetChild(int i) {
+    return children[i];
+  }
+
+  public int jjtGetNumChildren() {
+    return (children == null) ? 0 : children.length;
+  }
+
+  /* You can override these two methods in subclasses of SimpleNode to
+     customize the way the node appears when the tree is dumped.  If
+     your output uses more than one line you should override
+     toString(String), otherwise overriding toString() is probably all
+     you need to do. */
+
+  public String toString() { return JavaCCParserTreeConstants.jjtNodeName[id]; }
+  public String toString(String prefix) { return prefix + toString(); }
+
+  /* Override this method if you want to customize how the node dumps
+     out its children. */
+
+  public void dump(String prefix) {
+    System.out.println(toString(prefix));
+    if (children != null) {
+      for (int i = 0; i < children.length; ++i) {
+       SimpleNode n = (SimpleNode)children[i];
+       if (n != null) {
+         n.dump(prefix + " ");
+       }
+      }
+    }
+  }
+}
+
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/Token.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/Token.java
new file mode 100644 (file)
index 0000000..b55d170
--- /dev/null
@@ -0,0 +1,81 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */
+package jp.sourceforge.expression_computer.javacc;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token {
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /**
+   * beginLine and beginColumn describe the position of the first character
+   * of this token; endLine and endColumn describe the position of the
+   * last character of this token.
+   */
+  public int beginLine, beginColumn, endLine, endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+     return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simlpy add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken();
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use it in your lexical actions.
+   */
+  public static final Token newToken(int ofKind)
+  {
+     switch(ofKind)
+     {
+       default : return new Token();
+     }
+  }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/TokenMgrError.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/TokenMgrError.java
new file mode 100644 (file)
index 0000000..362b134
--- /dev/null
@@ -0,0 +1,133 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
+package jp.sourceforge.expression_computer.javacc;
+
+public class TokenMgrError extends Error
+{
+   /*
+    * Ordinals for various reasons why an Error of this type can be thrown.
+    */
+
+   /**
+    * Lexical error occured.
+    */
+   static final int LEXICAL_ERROR = 0;
+
+   /**
+    * An attempt wass made to create a second instance of a static token manager.
+    */
+   static final int STATIC_LEXER_ERROR = 1;
+
+   /**
+    * Tried to change to an invalid lexical state.
+    */
+   static final int INVALID_LEXICAL_STATE = 2;
+
+   /**
+    * Detected (and bailed out of) an infinite loop in the token manager.
+    */
+   static final int LOOP_DETECTED = 3;
+
+   /**
+    * Indicates the reason why the exception is thrown. It will have
+    * one of the above 4 values.
+    */
+   int errorCode;
+
+   /**
+    * Replaces unprintable characters by their espaced (or unicode escaped)
+    * equivalents in the given string
+    */
+   protected static final String addEscapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+   /**
+    * Returns a detailed message for the Error when it is thrown by the
+    * token manager to indicate a lexical error.
+    * Parameters : 
+    *    EOFSeen     : indicates if EOF caused the lexicl error
+    *    curLexState : lexical state in which this error occured
+    *    errorLine   : line number when the error occured
+    *    errorColumn : column number when the error occured
+    *    errorAfter  : prefix that was seen before this error occured
+    *    curchar     : the offending character
+    * Note: You can customize the lexical error message by modifying this method.
+    */
+   protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+      return("Lexical error at line " +
+           errorLine + ", column " +
+           errorColumn + ".  Encountered: " +
+           (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+           "after : \"" + addEscapes(errorAfter) + "\"");
+   }
+
+   /**
+    * You can also modify the body of this method to customize your error messages.
+    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+    * of end-users concern, so you can return something like : 
+    *
+    *     "Internal Error : Please file a bug report .... "
+    *
+    * from this method for such cases in the release version of your parser.
+    */
+   public String getMessage() {
+      return super.getMessage();
+   }
+
+   /*
+    * Constructors of various flavors follow.
+    */
+
+   public TokenMgrError() {
+   }
+
+   public TokenMgrError(String message, int reason) {
+      super(message);
+      errorCode = reason;
+   }
+
+   public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+   }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/expression-parser.jj b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/expression-parser.jj
new file mode 100644 (file)
index 0000000..4d1d3f7
--- /dev/null
@@ -0,0 +1,1167 @@
+/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. .\expression-parser.jj */
+/*@egen*/options {                   
+    STATIC = false;                      
+    JAVA_UNICODE_ESCAPE = true;
+    UNICODE_INPUT = true;                                                                          
+}
+
+PARSER_BEGIN(JavaCCParser)
+package jp.sourceforge.expression_computer.javacc;
+public final class JavaCCParser/*@bgen(jjtree)*/implements JavaCCParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/
+  protected JJTJavaCCParserState jjtree = new JJTJavaCCParserState();
+
+/*@egen*/
+    public Node parse() throws ParseException {
+        this.Expression();
+        return this.jjtree.rootNode();
+    }
+}
+PARSER_END(JavaCCParser)
+
+SKIP :
+{
+  " "
+| "\t"
+| "\n"
+| "\r"
+| "\f"
+}
+
+TOKEN :
+{
+  < INTEGER_LITERAL: <DECIMAL_LITERAL> | <HEX_LITERAL> | <OCTAL_LITERAL> >
+| < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])*
+                    | "0"
+  >
+| < #HEX_LITERAL: "0" ["x", "X"] (["0"-"9", "a"-"f", "A"-"F"])+ >
+| < #OCTAL_LITERAL: "0" (["0"-"7"])+ >
+| < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])+
+                          | "." (["0"-"9"])+
+  >
+}
+
+TOKEN :
+{
+  < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
+| < #LETTER:
+    [
+    "$",
+    "A"-"Z",
+    "_",
+    "a"-"z",
+    "\u00c0"-"\u00d6",
+    "\u00d8"-"\u00f6",
+    "\u00f8"-"\u00ff",
+    "\u0100"-"\u1fff",
+    "\u3040"-"\u318f",
+    "\u3300"-"\u337f",
+    "\u3400"-"\u3d2d",
+    "\u4e00"-"\u9fff",
+    "\uf900"-"\ufaff"
+    ]
+  >
+| < #DIGIT:
+    [
+    "0"-"9",
+    "\u0660"-"\u0669",
+    "\u06f0"-"\u06f9",
+    "\u0966"-"\u096f",
+    "\u09e6"-"\u09ef",
+    "\u0a66"-"\u0a6f",
+    "\u0ae6"-"\u0aef",
+    "\u0b66"-"\u0b6f",
+    "\u0be7"-"\u0bef",
+    "\u0c66"-"\u0c6f",
+    "\u0ce6"-"\u0cef",
+    "\u0d66"-"\u0d6f",
+    "\u0e50"-"\u0e59",
+    "\u0ed0"-"\u0ed9",
+    "\u1040"-"\u1049"
+    ]
+  >
+}
+
+void Expression() :
+{/*@bgen(jjtree) Expression */
+  ASTExpression jjtn000 = new ASTExpression(JJTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) Expression */
+    try {
+/*@egen*/
+    AssignmentExpression() <EOF>/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void AssignmentExpression()                          :
+{/*@bgen(jjtree) #AssignmentExpression(> 1) */
+  ASTAssignmentExpression jjtn000 = new ASTAssignmentExpression(JJTASSIGNMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #AssignmentExpression(> 1) */
+    try {
+/*@egen*/
+    ( LOOKAHEAD(2) Variable() AssignmentExpressionOperator() AssignmentExpression()
+    | ConditionalExpression()
+    )/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void AssignmentExpressionOperator() :
+{/*@bgen(jjtree) AssignmentExpressionOperator */
+    ASTAssignmentExpressionOperator jjtn000 = new ASTAssignmentExpressionOperator(JJTASSIGNMENTEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) AssignmentExpressionOperator */
+    try {
+/*@egen*/
+    ( t = "="
+    | t = "+="
+    | t = "-="
+    | t = "*="
+    | t = "/="
+    | t = "%="
+    | t = "&="
+    | t = "^="
+    | t = "|="
+    | t = "<<="
+    | t = ">>="
+    | t = ">>>="
+    )/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void ConditionalExpression()                           :
+{/*@bgen(jjtree) #ConditionalExpression(> 1) */
+  ASTConditionalExpression jjtn000 = new ASTConditionalExpression(JJTCONDITIONALEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #ConditionalExpression(> 1) */
+    try {
+/*@egen*/
+    ConditionalOrExpression() ("?" AssignmentExpression() ":" AssignmentExpression())?/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void ConditionalOrExpression()                             :
+{/*@bgen(jjtree) #ConditionalOrExpression(> 1) */
+  ASTConditionalOrExpression jjtn000 = new ASTConditionalOrExpression(JJTCONDITIONALOREXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #ConditionalOrExpression(> 1) */
+    try {
+/*@egen*/
+    ConditionalAndExpression() ("||" ConditionalAndExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void ConditionalAndExpression()                              :
+{/*@bgen(jjtree) #ConditionalAndExpression(> 1) */
+  ASTConditionalAndExpression jjtn000 = new ASTConditionalAndExpression(JJTCONDITIONALANDEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #ConditionalAndExpression(> 1) */
+    try {
+/*@egen*/
+    InclusiveOrExpression() ("&&" InclusiveOrExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void InclusiveOrExpression()                           :
+{/*@bgen(jjtree) #InclusiveOrExpression(> 1) */
+  ASTInclusiveOrExpression jjtn000 = new ASTInclusiveOrExpression(JJTINCLUSIVEOREXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #InclusiveOrExpression(> 1) */
+    try {
+/*@egen*/
+    ExclusiveOrExpression() ("|" ExclusiveOrExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void ExclusiveOrExpression()                           :
+{/*@bgen(jjtree) #ExclusiveOrExpression(> 1) */
+  ASTExclusiveOrExpression jjtn000 = new ASTExclusiveOrExpression(JJTEXCLUSIVEOREXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #ExclusiveOrExpression(> 1) */
+    try {
+/*@egen*/
+    AndExpression() ("^" AndExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void AndExpression()                   :
+{/*@bgen(jjtree) #AndExpression(> 1) */
+  ASTAndExpression jjtn000 = new ASTAndExpression(JJTANDEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #AndExpression(> 1) */
+    try {
+/*@egen*/
+    EqualityExpression() ("&" EqualityExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void EqualityExpression()                        :
+{/*@bgen(jjtree) #EqualityExpression(> 1) */
+  ASTEqualityExpression jjtn000 = new ASTEqualityExpression(JJTEQUALITYEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #EqualityExpression(> 1) */
+    try {
+/*@egen*/
+    RelationalExpression() (EqualityExpressionOperator() RelationalExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void EqualityExpressionOperator() :
+{/*@bgen(jjtree) EqualityExpressionOperator */
+    ASTEqualityExpressionOperator jjtn000 = new ASTEqualityExpressionOperator(JJTEQUALITYEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) EqualityExpressionOperator */
+    try {
+/*@egen*/
+    ( t = "=="
+    | t = "!="
+    )/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void RelationalExpression()                          :
+{/*@bgen(jjtree) #RelationalExpression(> 1) */
+  ASTRelationalExpression jjtn000 = new ASTRelationalExpression(JJTRELATIONALEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #RelationalExpression(> 1) */
+    try {
+/*@egen*/
+    ShiftExpression() (RelationalExpressionOperator() ShiftExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void RelationalExpressionOperator() :
+{/*@bgen(jjtree) RelationalExpressionOperator */
+    ASTRelationalExpressionOperator jjtn000 = new ASTRelationalExpressionOperator(JJTRELATIONALEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) RelationalExpressionOperator */
+    try {
+/*@egen*/
+    ( t = ">"
+    | t = "<"
+    | t = ">="
+    | t = "<="
+    )/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void ShiftExpression()                     :
+{/*@bgen(jjtree) #ShiftExpression(> 1) */
+  ASTShiftExpression jjtn000 = new ASTShiftExpression(JJTSHIFTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #ShiftExpression(> 1) */
+    try {
+/*@egen*/
+    AdditiveExpression() (ShiftExpressionOperator() AdditiveExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void ShiftExpressionOperator() :
+{/*@bgen(jjtree) ShiftExpressionOperator */
+    ASTShiftExpressionOperator jjtn000 = new ASTShiftExpressionOperator(JJTSHIFTEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) ShiftExpressionOperator */
+    try {
+/*@egen*/
+    ( t = "<<"
+    | t = ">>"
+    | t = ">>>"
+    )/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void AdditiveExpression()                        :
+{/*@bgen(jjtree) #AdditiveExpression(> 1) */
+  ASTAdditiveExpression jjtn000 = new ASTAdditiveExpression(JJTADDITIVEEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #AdditiveExpression(> 1) */
+    try {
+/*@egen*/
+    MultiplicativeExpression() (AdditiveExpressionOperator() MultiplicativeExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void AdditiveExpressionOperator() :
+{/*@bgen(jjtree) AdditiveExpressionOperator */
+    ASTAdditiveExpressionOperator jjtn000 = new ASTAdditiveExpressionOperator(JJTADDITIVEEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) AdditiveExpressionOperator */
+    try {
+/*@egen*/
+    ( t = "+"
+    | t = "-"
+    )/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void MultiplicativeExpression()                              :
+{/*@bgen(jjtree) #MultiplicativeExpression(> 1) */
+  ASTMultiplicativeExpression jjtn000 = new ASTMultiplicativeExpression(JJTMULTIPLICATIVEEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) #MultiplicativeExpression(> 1) */
+    try {
+/*@egen*/
+    UnaryExpression() (MultiplicativeExpressionOperator() UnaryExpression())*/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, jjtree.nodeArity() > 1);
+      }
+    }
+/*@egen*/
+}
+
+void MultiplicativeExpressionOperator() :
+{/*@bgen(jjtree) MultiplicativeExpressionOperator */
+    ASTMultiplicativeExpressionOperator jjtn000 = new ASTMultiplicativeExpressionOperator(JJTMULTIPLICATIVEEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) MultiplicativeExpressionOperator */
+    try {
+/*@egen*/
+    ( t = "*"
+    | t = "/"
+    | t = "%"
+    )/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void UnaryExpression()      :
+{}
+{
+    (/*@bgen(jjtree) UnaryExpression */
+      {
+        ASTUnaryExpression jjtn001 = new ASTUnaryExpression(JJTUNARYEXPRESSION);
+        boolean jjtc001 = true;
+        jjtree.openNodeScope(jjtn001);
+      }
+      try {
+/*@egen*/ (UnaryExpressionOperator() UnaryExpressionNotPlusMinus())/*@bgen(jjtree)*/
+      } catch (Throwable jjte001) {
+        if (jjtc001) {
+          jjtree.clearNodeScope(jjtn001);
+          jjtc001 = false;
+        } else {
+          jjtree.popNode();
+        }
+        if (jjte001 instanceof RuntimeException) {
+          throw (RuntimeException)jjte001;
+        }
+        if (jjte001 instanceof ParseException) {
+          throw (ParseException)jjte001;
+        }
+        throw (Error)jjte001;
+      } finally {
+        if (jjtc001) {
+          jjtree.closeNodeScope(jjtn001, true);
+        }
+      }
+/*@egen*/
+    | PreIncrementExpression()
+    | PreDecrementExpression()
+    | UnaryExpressionNotPlusMinus()
+    )
+}
+
+void UnaryExpressionOperator() :
+{/*@bgen(jjtree) UnaryExpressionOperator */
+    ASTUnaryExpressionOperator jjtn000 = new ASTUnaryExpressionOperator(JJTUNARYEXPRESSIONOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) UnaryExpressionOperator */
+    try {
+/*@egen*/
+    ( t = "+"
+    | t = "-"
+    )/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void PreIncrementExpression() :
+{/*@bgen(jjtree) PreIncrementExpression */
+  ASTPreIncrementExpression jjtn000 = new ASTPreIncrementExpression(JJTPREINCREMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) PreIncrementExpression */
+    try {
+/*@egen*/
+    "++" Variable()/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void PreDecrementExpression() :
+{/*@bgen(jjtree) PreDecrementExpression */
+  ASTPreDecrementExpression jjtn000 = new ASTPreDecrementExpression(JJTPREDECREMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) PreDecrementExpression */
+    try {
+/*@egen*/
+    "--" Variable()/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void UnaryExpressionNotPlusMinus()      :
+{}
+{
+    (/*@bgen(jjtree) UnaryExpressionNotPlusMinus */
+      {
+        ASTUnaryExpressionNotPlusMinus jjtn001 = new ASTUnaryExpressionNotPlusMinus(JJTUNARYEXPRESSIONNOTPLUSMINUS);
+        boolean jjtc001 = true;
+        jjtree.openNodeScope(jjtn001);
+      }
+      try {
+/*@egen*/ (UnaryExpressionNotPlusMinusOperator() PrimaryExpression())/*@bgen(jjtree)*/
+      } catch (Throwable jjte001) {
+        if (jjtc001) {
+          jjtree.clearNodeScope(jjtn001);
+          jjtc001 = false;
+        } else {
+          jjtree.popNode();
+        }
+        if (jjte001 instanceof RuntimeException) {
+          throw (RuntimeException)jjte001;
+        }
+        if (jjte001 instanceof ParseException) {
+          throw (ParseException)jjte001;
+        }
+        throw (Error)jjte001;
+      } finally {
+        if (jjtc001) {
+          jjtree.closeNodeScope(jjtn001, true);
+        }
+      }
+/*@egen*/
+    | LOOKAHEAD(2) PostIncrementExpression()
+    | LOOKAHEAD(2) PostDecrementExpression()
+    | PrimaryExpression()
+    )
+}
+
+void UnaryExpressionNotPlusMinusOperator() :
+{/*@bgen(jjtree) UnaryExpressionNotPlusMinusOperator */
+    ASTUnaryExpressionNotPlusMinusOperator jjtn000 = new ASTUnaryExpressionNotPlusMinusOperator(JJTUNARYEXPRESSIONNOTPLUSMINUSOPERATOR);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) UnaryExpressionNotPlusMinusOperator */
+    try {
+/*@egen*/
+    ( t = "~"
+    | t = "!"
+    )/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void PostIncrementExpression() :
+{/*@bgen(jjtree) PostIncrementExpression */
+  ASTPostIncrementExpression jjtn000 = new ASTPostIncrementExpression(JJTPOSTINCREMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) PostIncrementExpression */
+    try {
+/*@egen*/
+    Variable() "++"/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void PostDecrementExpression() :
+{/*@bgen(jjtree) PostDecrementExpression */
+  ASTPostDecrementExpression jjtn000 = new ASTPostDecrementExpression(JJTPOSTDECREMENTEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) PostDecrementExpression */
+    try {
+/*@egen*/
+    Variable() "--"/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void PrimaryExpression()      :
+{}
+{
+    ( IntegerLiteral()
+    | FloatingPointLiteral()
+    | LOOKAHEAD(2) FunctionExpression()
+    | Variable()
+    | ParenthesesExpression()
+    )
+}
+
+void IntegerLiteral() :
+{/*@bgen(jjtree) IntegerLiteral */
+    ASTIntegerLiteral jjtn000 = new ASTIntegerLiteral(JJTINTEGERLITERAL);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) IntegerLiteral */
+    try {
+/*@egen*/
+    t = <INTEGER_LITERAL>/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void FloatingPointLiteral() :
+{/*@bgen(jjtree) FloatingPointLiteral */
+    ASTFloatingPointLiteral jjtn000 = new ASTFloatingPointLiteral(JJTFLOATINGPOINTLITERAL);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) FloatingPointLiteral */
+    try {
+/*@egen*/
+    t = <FLOATING_POINT_LITERAL>/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void FunctionExpression() :
+{/*@bgen(jjtree) FunctionExpression */
+  ASTFunctionExpression jjtn000 = new ASTFunctionExpression(JJTFUNCTIONEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) FunctionExpression */
+    try {
+/*@egen*/
+    FunctionName() "(" (AssignmentExpression() ("," AssignmentExpression())* )? ")"/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void Variable() :
+{/*@bgen(jjtree) Variable */
+    ASTVariable jjtn000 = new ASTVariable(JJTVARIABLE);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) Variable */
+    try {
+/*@egen*/
+    t = <IDENTIFIER>/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void ParenthesesExpression() :
+{/*@bgen(jjtree) ParenthesesExpression */
+  ASTParenthesesExpression jjtn000 = new ASTParenthesesExpression(JJTPARENTHESESEXPRESSION);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+/*@egen*/}
+{/*@bgen(jjtree) ParenthesesExpression */
+    try {
+/*@egen*/
+    "(" AssignmentExpression() ")"/*@bgen(jjtree)*/
+    } catch (Throwable jjte000) {
+      if (jjtc000) {
+        jjtree.clearNodeScope(jjtn000);
+        jjtc000 = false;
+      } else {
+        jjtree.popNode();
+      }
+      if (jjte000 instanceof RuntimeException) {
+        throw (RuntimeException)jjte000;
+      }
+      if (jjte000 instanceof ParseException) {
+        throw (ParseException)jjte000;
+      }
+      throw (Error)jjte000;
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
+
+void FunctionName() :
+{/*@bgen(jjtree) FunctionName */
+    ASTFunctionName jjtn000 = new ASTFunctionName(JJTFUNCTIONNAME);
+    boolean jjtc000 = true;
+    jjtree.openNodeScope(jjtn000);
+/*@egen*/
+    Token t;
+}
+{/*@bgen(jjtree) FunctionName */
+    try {
+/*@egen*/
+    t = <IDENTIFIER>/*@bgen(jjtree)*/
+    {
+      jjtree.closeNodeScope(jjtn000, true);
+      jjtc000 = false;
+    }
+/*@egen*/
+    {
+        jjtn000.nodeValue = t.image;
+        jjtn000.nodeLine = t.beginLine;
+        jjtn000.nodeColumn = t.beginColumn;
+    }/*@bgen(jjtree)*/
+    } finally {
+      if (jjtc000) {
+        jjtree.closeNodeScope(jjtn000, true);
+      }
+    }
+/*@egen*/
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/expression-parser.jjt b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/expression-parser.jjt
new file mode 100644 (file)
index 0000000..a771216
--- /dev/null
@@ -0,0 +1,414 @@
+options {
+    MULTI = true;
+    STATIC = false;
+    VISITOR = false;
+    JAVA_UNICODE_ESCAPE = true;
+    UNICODE_INPUT = true;
+    NODE_EXTENDS = "jp.sourceforge.expression_computer.javacc.BaseNode";
+}
+
+PARSER_BEGIN(JavaCCParser)
+package jp.sourceforge.expression_computer.javacc;
+public final class JavaCCParser {
+    public Node parse() throws ParseException {
+        this.Expression();
+        return this.jjtree.rootNode();
+    }
+}
+PARSER_END(JavaCCParser)
+
+SKIP :
+{
+  " "
+| "\t"
+| "\n"
+| "\r"
+| "\f"
+}
+
+TOKEN :
+{
+  < INTEGER_LITERAL: <DECIMAL_LITERAL> | <HEX_LITERAL> | <OCTAL_LITERAL> >
+| < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])*
+                    | "0"
+  >
+| < #HEX_LITERAL: "0" ["x", "X"] (["0"-"9", "a"-"f", "A"-"F"])+ >
+| < #OCTAL_LITERAL: "0" (["0"-"7"])+ >
+| < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])+
+                          | "." (["0"-"9"])+
+  >
+}
+
+TOKEN :
+{
+  < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
+| < #LETTER:
+    [
+    "\u0024",
+    "\u0041"-"\u005a",
+    "\u005f",
+    "\u0061"-"\u007a",
+    "\u00c0"-"\u00d6",
+    "\u00d8"-"\u00f6",
+    "\u00f8"-"\u00ff",
+    "\u0100"-"\u1fff",
+    "\u3040"-"\u318f",
+    "\u3300"-"\u337f",
+    "\u3400"-"\u3d2d",
+    "\u4e00"-"\u9fff",
+    "\uf900"-"\ufaff"
+    ]
+  >
+| < #DIGIT:
+    [
+    "\u0030"-"\u0039",
+    "\u0660"-"\u0669",
+    "\u06f0"-"\u06f9",
+    "\u0966"-"\u096f",
+    "\u09e6"-"\u09ef",
+    "\u0a66"-"\u0a6f",
+    "\u0ae6"-"\u0aef",
+    "\u0b66"-"\u0b6f",
+    "\u0be7"-"\u0bef",
+    "\u0c66"-"\u0c6f",
+    "\u0ce6"-"\u0cef",
+    "\u0d66"-"\u0d6f",
+    "\u0e50"-"\u0e59",
+    "\u0ed0"-"\u0ed9",
+    "\u1040"-"\u1049"
+    ]
+  >
+}
+
+void Expression() :
+{}
+{
+    AssignmentExpression() <EOF>
+}
+
+void AssignmentExpression() #AssignmentExpression(>1):
+{}
+{
+    ( LOOKAHEAD(2) Variable() AssignmentExpressionOperator() AssignmentExpression()
+    | ConditionalExpression()
+    )
+}
+
+void AssignmentExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "="
+    | t = "+="
+    | t = "-="
+    | t = "*="
+    | t = "/="
+    | t = "%="
+    | t = "&="
+    | t = "^="
+    | t = "|="
+    | t = "<<="
+    | t = ">>="
+    | t = ">>>="
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void ConditionalExpression() #ConditionalExpression(>1):
+{}
+{
+    ConditionalOrExpression() ("?" AssignmentExpression() ":" AssignmentExpression())?
+}
+
+void ConditionalOrExpression() #ConditionalOrExpression(>1):
+{}
+{
+    ConditionalAndExpression() ("||" ConditionalAndExpression())*
+}
+
+void ConditionalAndExpression() #ConditionalAndExpression(>1):
+{}
+{
+    InclusiveOrExpression() ("&&" InclusiveOrExpression())*
+}
+
+void InclusiveOrExpression() #InclusiveOrExpression(>1):
+{}
+{
+    ExclusiveOrExpression() ("|" ExclusiveOrExpression())*
+}
+
+void ExclusiveOrExpression() #ExclusiveOrExpression(>1):
+{}
+{
+    AndExpression() ("^" AndExpression())*
+}
+
+void AndExpression() #AndExpression(>1):
+{}
+{
+    EqualityExpression() ("&" EqualityExpression())*
+}
+
+void EqualityExpression() #EqualityExpression(>1):
+{}
+{
+    RelationalExpression() (EqualityExpressionOperator() RelationalExpression())*
+}
+
+void EqualityExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "=="
+    | t = "!="
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void RelationalExpression() #RelationalExpression(>1):
+{}
+{
+    ShiftExpression() (RelationalExpressionOperator() ShiftExpression())*
+}
+
+void RelationalExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = ">"
+    | t = "<"
+    | t = ">="
+    | t = "<="
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void ShiftExpression() #ShiftExpression(>1):
+{}
+{
+    AdditiveExpression() (ShiftExpressionOperator() AdditiveExpression())*
+}
+
+void ShiftExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "<<"
+    | t = ">>"
+    | t = ">>>"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void AdditiveExpression() #AdditiveExpression(>1):
+{}
+{
+    MultiplicativeExpression() (AdditiveExpressionOperator() MultiplicativeExpression())*
+}
+
+void AdditiveExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "+"
+    | t = "-"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void MultiplicativeExpression() #MultiplicativeExpression(>1):
+{}
+{
+    UnaryExpression() (MultiplicativeExpressionOperator() UnaryExpression())*
+}
+
+void MultiplicativeExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "*"
+    | t = "/"
+    | t = "%"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void UnaryExpression() #void:
+{}
+{
+    ( (UnaryExpressionOperator() UnaryExpressionNotPlusMinus()) #UnaryExpression
+    | PreIncrementExpression()
+    | PreDecrementExpression()
+    | UnaryExpressionNotPlusMinus()
+    )
+}
+
+void UnaryExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "+"
+    | t = "-"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void PreIncrementExpression() :
+{}
+{
+    "++" Variable()
+}
+
+void PreDecrementExpression() :
+{}
+{
+    "--" Variable()
+}
+
+void UnaryExpressionNotPlusMinus() #void:
+{}
+{
+    ( (UnaryExpressionNotPlusMinusOperator() PrimaryExpression()) #UnaryExpressionNotPlusMinus
+    | LOOKAHEAD(2) PostIncrementExpression()
+    | LOOKAHEAD(2) PostDecrementExpression()
+    | PrimaryExpression()
+    )
+}
+
+void UnaryExpressionNotPlusMinusOperator() :
+{
+    Token t;
+}
+{
+    ( t = "~"
+    | t = "!"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void PostIncrementExpression() :
+{}
+{
+    Variable() "++"
+}
+
+void PostDecrementExpression() :
+{}
+{
+    Variable() "--"
+}
+
+void PrimaryExpression() #void:
+{}
+{
+    ( IntegerLiteral()
+    | FloatingPointLiteral()
+    | LOOKAHEAD(2) FunctionExpression()
+    | Variable()
+    | ParenthesesExpression()
+    )
+}
+
+void IntegerLiteral() :
+{
+    Token t;
+}
+{
+    t = <INTEGER_LITERAL>
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void FloatingPointLiteral() :
+{
+    Token t;
+}
+{
+    t = <FLOATING_POINT_LITERAL>
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void FunctionExpression() :
+{}
+{
+    FunctionName() "(" (AssignmentExpression() ("," AssignmentExpression())* )? ")"
+}
+
+void Variable() :
+{
+    Token t;
+}
+{
+    t = <IDENTIFIER>
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void ParenthesesExpression() :
+{}
+{
+    "(" AssignmentExpression() ")"
+}
+
+void FunctionName() :
+{
+    Token t;
+}
+{
+    t = <IDENTIFIER>
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/package.html b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/package.html
new file mode 100644 (file)
index 0000000..3ee04bc
--- /dev/null
@@ -0,0 +1,3 @@
+<body>
+    <p>JavaCCが生成したクラスを格納しています。</p>
+</body>
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/rpn-parser.jjt b/expression-computer/src/main/java/jp/sourceforge/expression_computer/javacc/rpn-parser.jjt
new file mode 100644 (file)
index 0000000..3a17c07
--- /dev/null
@@ -0,0 +1,414 @@
+options {
+    MULTI = true;
+    STATIC = false;
+    VISITOR = false;
+    JAVA_UNICODE_ESCAPE = true;
+    UNICODE_INPUT = true;
+    NODE_EXTENDS = "jp.sourceforge.rpn_computer.javacc.BaseNode";
+}
+
+PARSER_BEGIN(RpnJavaCCParser)
+package jp.sourceforge.rpn_computer.javacc;
+public final class RpnJavaCCParser {
+    public Node parse() throws ParseException {
+        this.Expression();
+        return this.jjtree.rootNode();
+    }
+}
+PARSER_END(RpnJavaCCParser)
+
+SKIP :
+{
+  " "
+| "\t"
+| "\n"
+| "\r"
+| "\f"
+}
+
+TOKEN :
+{
+  < INTEGER_LITERAL: <DECIMAL_LITERAL> | <HEX_LITERAL> | <OCTAL_LITERAL> >
+| < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])*
+                    | "0"
+  >
+| < #HEX_LITERAL: "0" ["x", "X"] (["0"-"9", "a"-"f", "A"-"F"])+ >
+| < #OCTAL_LITERAL: "0" (["0"-"7"])+ >
+| < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])+
+                          | "." (["0"-"9"])+
+  >
+}
+
+TOKEN :
+{
+  < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
+| < #LETTER:
+    [
+    "\u0024",
+    "\u0041"-"\u005a",
+    "\u005f",
+    "\u0061"-"\u007a",
+    "\u00c0"-"\u00d6",
+    "\u00d8"-"\u00f6",
+    "\u00f8"-"\u00ff",
+    "\u0100"-"\u1fff",
+    "\u3040"-"\u318f",
+    "\u3300"-"\u337f",
+    "\u3400"-"\u3d2d",
+    "\u4e00"-"\u9fff",
+    "\uf900"-"\ufaff"
+    ]
+  >
+| < #DIGIT:
+    [
+    "\u0030"-"\u0039",
+    "\u0660"-"\u0669",
+    "\u06f0"-"\u06f9",
+    "\u0966"-"\u096f",
+    "\u09e6"-"\u09ef",
+    "\u0a66"-"\u0a6f",
+    "\u0ae6"-"\u0aef",
+    "\u0b66"-"\u0b6f",
+    "\u0be7"-"\u0bef",
+    "\u0c66"-"\u0c6f",
+    "\u0ce6"-"\u0cef",
+    "\u0d66"-"\u0d6f",
+    "\u0e50"-"\u0e59",
+    "\u0ed0"-"\u0ed9",
+    "\u1040"-"\u1049"
+    ]
+  >
+}
+
+void Expression() :
+{}
+{
+    AssignmentExpression() <EOF>
+}
+
+void AssignmentExpression() #AssignmentExpression(>1):
+{}
+{
+    ( LOOKAHEAD(2) Variable() AssignmentExpressionOperator() AssignmentExpression()
+    | ConditionalExpression()
+    )
+}
+
+void AssignmentExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "="
+    | t = "+="
+    | t = "-="
+    | t = "*="
+    | t = "/="
+    | t = "%="
+    | t = "&="
+    | t = "^="
+    | t = "|="
+    | t = "<<="
+    | t = ">>="
+    | t = ">>>="
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void ConditionalExpression() #ConditionalExpression(>1):
+{}
+{
+    ConditionalOrExpression() ("?" AssignmentExpression() ":" AssignmentExpression())?
+}
+
+void ConditionalOrExpression() #ConditionalOrExpression(>1):
+{}
+{
+    ConditionalAndExpression() ("||" ConditionalAndExpression())*
+}
+
+void ConditionalAndExpression() #ConditionalAndExpression(>1):
+{}
+{
+    InclusiveOrExpression() ("&&" InclusiveOrExpression())*
+}
+
+void InclusiveOrExpression() #InclusiveOrExpression(>1):
+{}
+{
+    ExclusiveOrExpression() ("|" ExclusiveOrExpression())*
+}
+
+void ExclusiveOrExpression() #ExclusiveOrExpression(>1):
+{}
+{
+    AndExpression() ("^" AndExpression())*
+}
+
+void AndExpression() #AndExpression(>1):
+{}
+{
+    EqualityExpression() ("&" EqualityExpression())*
+}
+
+void EqualityExpression() #EqualityExpression(>1):
+{}
+{
+    RelationalExpression() (EqualityExpressionOperator() RelationalExpression())*
+}
+
+void EqualityExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "=="
+    | t = "!="
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void RelationalExpression() #RelationalExpression(>1):
+{}
+{
+    ShiftExpression() (RelationalExpressionOperator() ShiftExpression())*
+}
+
+void RelationalExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = ">"
+    | t = "<"
+    | t = ">="
+    | t = "<="
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void ShiftExpression() #ShiftExpression(>1):
+{}
+{
+    AdditiveExpression() (ShiftExpressionOperator() AdditiveExpression())*
+}
+
+void ShiftExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "<<"
+    | t = ">>"
+    | t = ">>>"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void AdditiveExpression() #AdditiveExpression(>1):
+{}
+{
+    MultiplicativeExpression() (AdditiveExpressionOperator() MultiplicativeExpression())*
+}
+
+void AdditiveExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "+"
+    | t = "-"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void MultiplicativeExpression() #MultiplicativeExpression(>1):
+{}
+{
+    UnaryExpression() (MultiplicativeExpressionOperator() UnaryExpression())*
+}
+
+void MultiplicativeExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "*"
+    | t = "/"
+    | t = "%"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void UnaryExpression() #void:
+{}
+{
+    ( (UnaryExpressionOperator() UnaryExpressionNotPlusMinus()) #UnaryExpression
+    | PreIncrementExpression()
+    | PreDecrementExpression()
+    | UnaryExpressionNotPlusMinus()
+    )
+}
+
+void UnaryExpressionOperator() :
+{
+    Token t;
+}
+{
+    ( t = "+"
+    | t = "-"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void PreIncrementExpression() :
+{}
+{
+    "++" Variable()
+}
+
+void PreDecrementExpression() :
+{}
+{
+    "--" Variable()
+}
+
+void UnaryExpressionNotPlusMinus() #void:
+{}
+{
+    ( (UnaryExpressionNotPlusMinusOperator() PrimaryExpression()) #UnaryExpressionNotPlusMinus
+    | LOOKAHEAD(2) PostIncrementExpression()
+    | LOOKAHEAD(2) PostDecrementExpression()
+    | PrimaryExpression()
+    )
+}
+
+void UnaryExpressionNotPlusMinusOperator() :
+{
+    Token t;
+}
+{
+    ( t = "~"
+    | t = "!"
+    )
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void PostIncrementExpression() :
+{}
+{
+    Variable() "++"
+}
+
+void PostDecrementExpression() :
+{}
+{
+    Variable() "--"
+}
+
+void PrimaryExpression() #void:
+{}
+{
+    ( IntegerLiteral()
+    | FloatingPointLiteral()
+    | LOOKAHEAD(2) FunctionExpression()
+    | Variable()
+    | ParenthesesExpression()
+    )
+}
+
+void IntegerLiteral() :
+{
+    Token t;
+}
+{
+    t = <INTEGER_LITERAL>
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void FloatingPointLiteral() :
+{
+    Token t;
+}
+{
+    t = <FLOATING_POINT_LITERAL>
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void FunctionExpression() :
+{}
+{
+    FunctionName() "(" (AssignmentExpression() ("," AssignmentExpression())* )? ")"
+}
+
+void Variable() :
+{
+    Token t;
+}
+{
+    t = <IDENTIFIER>
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
+
+void ParenthesesExpression() :
+{}
+{
+    "(" AssignmentExpression() ")"
+}
+
+void FunctionName() :
+{
+    Token t;
+}
+{
+    t = <IDENTIFIER>
+    {
+        jjtThis.nodeValue = t.image;
+        jjtThis.nodeLine = t.beginLine;
+        jjtThis.nodeColumn = t.beginColumn;
+    }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AbstractNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AbstractNode.java
new file mode 100644 (file)
index 0000000..b0e5758
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.Node;
+
+/**
+ * <p>
+ * ノードの基底抽象クラスです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public abstract class AbstractNode implements Node {
+
+    /**
+     * <p>
+     * 子ノードの文字列表現を返します。
+     * </p>
+     * 
+     * @return 子ノードの文字列表現。
+     */
+    protected final String toChildrenString() {
+        String str = "\n";
+        for (int i = 0; i < this.getChildren().length; i++) {
+            Node node = this.getChildren()[i];
+            String[] nodeString = node.toString().split("\n");
+            for (int j = 0; j < nodeString.length; j++) {
+                str += "\t" + nodeString[j] + "\n";
+            }
+        }
+        return str;
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AdditiveExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AdditiveExpressionNode.java
new file mode 100644 (file)
index 0000000..f803631
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.AddCommand;
+import jp.sourceforge.expression_computer.command.SubtractCommand;
+
+/**
+ * <p>
+ * AdditiveExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class AdditiveExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            式の要素。"項 (演算子 項)+"という順序で並んでいる必要があります。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素の並び順が間違えている場合、配列の要素数が3未満の場合、配列の要素数が奇数ではない場合、{@link IllegalArgumentException}例外をスローします。<br>
+     */
+    public AdditiveExpressionNode(Node[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+            if ((i % 2 == 0) && !(nodes[i] instanceof OperandNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が項ではありません。");
+            } else if ((i % 2 == 1) && !(nodes[i] instanceof AdditiveExpressionNode.OperatorNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が演算子ではありません。");
+            }
+        }
+        if (nodes.length < 3) {
+            throw new IllegalArgumentException("nodes.length < 3です。");
+        }
+        if ((nodes.length % 2) != 1) {
+            throw new IllegalArgumentException("nodes.lengthが奇数ではありません。");
+        }
+
+        this.nodes = (Node[]) nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * AdditiveExpressionNodeの演算子を表す抽象基底ノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+
+    }
+
+    /**
+     * <p>
+     * AdditiveExpressionNodeの"+"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class AddNode extends AdditiveExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new AddCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AdditiveExpressionNodeの"-"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class SubtractNode extends AdditiveExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new SubtractCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AndExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AndExpressionNode.java
new file mode 100644 (file)
index 0000000..44bcef1
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.AndCommand;
+
+/**
+ * <p>
+ * AndExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class AndExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            項の配列。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素数が2未満の場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public AndExpressionNode(Node[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+        }
+        if (nodes.length < 2) {
+            throw new IllegalArgumentException("nodes.length < 2です。");
+        }
+
+        List nodeList = new ArrayList();
+        for (int i = 0; i < nodes.length; i++) {
+            if (i > 0) {
+                nodeList.add(new AndExpressionNode.OperatorNode());
+            }
+            nodeList.add(nodes[i]);
+        }
+
+        this.nodes = (Node[]) nodeList.toArray(new Node[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * AndExpressionの"&"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new AndCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AssignmentExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/AssignmentExpressionNode.java
new file mode 100644 (file)
index 0000000..a83e1e4
--- /dev/null
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.CommandList;
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.AddCommand;
+import jp.sourceforge.expression_computer.command.AndCommand;
+import jp.sourceforge.expression_computer.command.ArithmeticRightShiftCommand;
+import jp.sourceforge.expression_computer.command.DivideCommand;
+import jp.sourceforge.expression_computer.command.ExclusiveOrCommand;
+import jp.sourceforge.expression_computer.command.InclusiveOrCommand;
+import jp.sourceforge.expression_computer.command.LeftShiftCommand;
+import jp.sourceforge.expression_computer.command.LogicalRightShiftCommand;
+import jp.sourceforge.expression_computer.command.MultiplyCommand;
+import jp.sourceforge.expression_computer.command.SetVariableCommand;
+import jp.sourceforge.expression_computer.command.SubtractCommand;
+import jp.sourceforge.expression_computer.command.SurplusCommand;
+
+/**
+ * <p>
+ * AssignmentExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class AssignmentExpressionNode extends AbstractNode implements OperandNode {
+
+    private VariableNode                          operand1;
+
+    private AssignmentExpressionNode.OperatorNode operator;
+
+    private OperandNode                           operand2;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operand1
+     *            左項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @param operator
+     *            演算子。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @param operand2
+     *            右項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public AssignmentExpressionNode(VariableNode operand1, AssignmentExpressionNode.OperatorNode operator, OperandNode operand2) {
+        if (operand1 == null) {
+            throw new NullPointerException("operand1がnullです。");
+        }
+        if (operator == null) {
+            throw new NullPointerException("operatorがnullです。");
+        }
+        if (operand2 == null) {
+            throw new NullPointerException("operand2がnullです。");
+        }
+        this.operand1 = operand1;
+        this.operator = operator;
+        this.operand2 = operand2;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand1.compile(context);
+        this.operand2.compile(context);
+        this.operator.compile(context);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operand1, this.operator, this.operand2 };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class EqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"+="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class AddEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new AddCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"-="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class SubtractEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new SubtractCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"*="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class MultiplyEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new MultiplyCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"/="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class DivideEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new DivideCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"%="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class SurplusEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new SurplusCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"&="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class AndEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new AndCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"^="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class ExclusiveOrEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new ExclusiveOrCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"|="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class InclusiveOrEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new InclusiveOrCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"&lt;&lt;="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class LeftShiftEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new LeftShiftCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"&gt;&gt;="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class ArithmeticRightShiftEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new ArithmeticRightShiftCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * AssignmentExpressionの"&gt;&gt;&gt;="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class LogicalRightShiftEqualNode extends AssignmentExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            CommandList cl = context.getCommandList();
+
+            Command c = cl.getCommand(cl.size() - 2);
+            cl.addCommand(cl.size() - 1, c);
+            cl.add(new LogicalRightShiftCommand());
+            cl.add(new SetVariableCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/BracketExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/BracketExpressionNode.java
new file mode 100644 (file)
index 0000000..3cb0d1b
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+
+/**
+ * <p>
+ * BracketExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class BracketExpressionNode extends AbstractNode implements OperandNode {
+
+    private BracketExpressionNode.LeftBracketNode  leftBracket;
+
+    private OperandNode                            expression;
+
+    private BracketExpressionNode.RightBracketNode rightBracket;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param expression
+     *            式。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public BracketExpressionNode(OperandNode expression) {
+        if (expression == null) {
+            throw new NullPointerException("expressionがnullです。");
+        }
+        this.expression = expression;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        if (this.expression != null) {
+            this.expression.compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.leftBracket, this.expression, this.rightBracket };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * BracketExpressionの"("演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class LeftBracketNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * BracketExpressionの")"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class RightBracketNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalAndExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalAndExpressionNode.java
new file mode 100644 (file)
index 0000000..6a42161
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.ConditionalAndCommand;
+
+/**
+ * <p>
+ * ConditionalAndExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ConditionalAndExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            項の配列。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素数が2未満の場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public ConditionalAndExpressionNode(Node[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+        }
+        if (nodes.length < 2) {
+            throw new IllegalArgumentException("nodes.length < 2です。");
+        }
+
+        List nodeList = new ArrayList();
+        for (int i = 0; i < nodes.length; i++) {
+            if (i > 0) {
+                nodeList.add(new ConditionalAndExpressionNode.OperatorNode());
+            }
+            nodeList.add(nodes[i]);
+        }
+
+        this.nodes = (Node[]) nodeList.toArray(new Node[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * ConditionalAndExpressionの"&"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new ConditionalAndCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalExpressionNode.java
new file mode 100644 (file)
index 0000000..cba4afb
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.ConditionCommand;
+
+/**
+ * <p>
+ * ConditionalExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ConditionalExpressionNode extends AbstractNode implements OperandNode {
+
+    private OperandNode                            operand1;
+
+    private ConditionalExpressionNode.QuestionNode question;
+
+    private OperandNode                            operand2;
+
+    private ConditionalExpressionNode.ColonNode    colon;
+
+    private OperandNode                            operand3;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operand1
+     *            第1項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @param operand2
+     *            第2項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @param operand3
+     *            第3項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public ConditionalExpressionNode(OperandNode operand1, OperandNode operand2, OperandNode operand3) {
+        if (operand1 == null) {
+            throw new NullPointerException("operand1がnullです。");
+        }
+        if (operand2 == null) {
+            throw new NullPointerException("operand2がnullです。");
+        }
+        if (operand3 == null) {
+            throw new NullPointerException("operand3がnullです。");
+        }
+        this.operand1 = operand1;
+        this.question = new ConditionalExpressionNode.QuestionNode();
+        this.operand2 = operand2;
+        this.colon = new ConditionalExpressionNode.ColonNode();
+        this.operand3 = operand3;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand1.compile(context);
+        if (this.question != null) {
+            this.operand2.compile(context);
+            this.operand3.compile(context);
+            context.getCommandList().add(new ConditionCommand());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operand1, this.question, this.operand2, this.colon, this.operand3 };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * ConditionalExpressionの演算子を表す抽象既定ノードです。
+     * </p>
+     * 
+     * @author naono
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+
+    }
+
+    /**
+     * <p>
+     * ConditionalExpressionの"?"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class QuestionNode extends ConditionalExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * ConditionalExpressionの":"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class ColonNode extends ConditionalExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalOrExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ConditionalOrExpressionNode.java
new file mode 100644 (file)
index 0000000..f2046fb
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.ConditionalOrCommand;
+
+/**
+ * <p>
+ * ConditionalOrExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ConditionalOrExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            項の配列。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素数が2未満の場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public ConditionalOrExpressionNode(Node[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+        }
+        if (nodes.length < 2) {
+            throw new IllegalArgumentException("nodes.length < 2です。");
+        }
+
+        List nodeList = new ArrayList();
+        for (int i = 0; i < nodes.length; i++) {
+            if (i > 0) {
+                nodeList.add(new ConditionalOrExpressionNode.OperatorNode());
+            }
+            nodeList.add(nodes[i]);
+        }
+
+        this.nodes = (Node[]) nodeList.toArray(new Node[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * ConditionalOrExpressionの"||"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new ConditionalOrCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/EofNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/EofNode.java
new file mode 100644 (file)
index 0000000..3042bdd
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+
+/**
+ * <p>
+ * EOFを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class EofNode extends AbstractNode {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[0];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return "EOF";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/EqualityExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/EqualityExpressionNode.java
new file mode 100644 (file)
index 0000000..1fded1d
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.EqualCommand;
+import jp.sourceforge.expression_computer.command.NotEqualCommand;
+
+/**
+ * <p>
+ * EqualityExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class EqualityExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            式の要素。"項 (演算子 項)+"という順序で並んでいる必要があります。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素の並び順が間違えている場合、配列の要素数が3未満の場合、配列の要素数が奇数ではない場合、{@link IllegalArgumentException}例外をスローします。<br>
+     */
+    public EqualityExpressionNode(Node[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+            if ((i % 2 == 0) && !(nodes[i] instanceof OperandNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が項ではありません。");
+            } else if ((i % 2 == 1) && !(nodes[i] instanceof EqualityExpressionNode.OperatorNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が演算子ではありません。");
+            }
+        }
+        if (nodes.length < 3) {
+            throw new IllegalArgumentException("nodes.length < 3です。");
+        }
+        if ((nodes.length % 2) != 1) {
+            throw new IllegalArgumentException("nodes.lengthが奇数ではありません。");
+        }
+
+        this.nodes = (Node[]) nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * EqualityExpressionNodeの演算子を表す抽象基底ノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+
+    }
+
+    /**
+     * <p>
+     * EqualityExpressionNodeの"=="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class EqualNode extends EqualityExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new EqualCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * EqualityExpressionNodeの"!="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class NotEqualNode extends EqualityExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new NotEqualCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ExclusiveOrExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ExclusiveOrExpressionNode.java
new file mode 100644 (file)
index 0000000..0d0c535
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.ExclusiveOrCommand;
+
+/**
+ * <p>
+ * ExclusiveOrExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ExclusiveOrExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            項の配列。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素数が2未満の場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public ExclusiveOrExpressionNode(OperandNode[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+        }
+        if (nodes.length < 2) {
+            throw new IllegalArgumentException("nodes.length < 2です。");
+        }
+
+        List nodeList = new ArrayList();
+        for (int i = 0; i < nodes.length; i++) {
+            if (i > 0) {
+                nodeList.add(new ExclusiveOrExpressionNode.OperatorNode());
+            }
+            nodeList.add(nodes[i]);
+        }
+
+        this.nodes = (Node[]) nodeList.toArray(new Node[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * ExclusiveOrExpressionの"^"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new ExclusiveOrCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ExpressionStatementNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ExpressionStatementNode.java
new file mode 100644 (file)
index 0000000..ad09218
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+
+/**
+ * <p>
+ * ExpressionStatementを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ExpressionStatementNode extends AbstractNode {
+
+    private OperandNode operand;
+
+    private EofNode     eofNode;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operand
+     *            項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public ExpressionStatementNode(OperandNode operand) {
+        if (operand == null) {
+            throw new NullPointerException("operandがnullです。");
+        }
+        this.operand = operand;
+        this.eofNode = new EofNode();
+    }
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     */
+    public ExpressionStatementNode() {
+        this.eofNode = new EofNode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand.compile(context);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operand, this.eofNode };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/FloatingPointLiteralNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/FloatingPointLiteralNode.java
new file mode 100644 (file)
index 0000000..211da3b
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.PushStackCommand;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+import jp.sourceforge.expression_computer.util.Validator;
+
+/**
+ * <p>
+ * FloatingPointLiteralを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class FloatingPointLiteralNode extends AbstractNode implements OperandNode {
+
+    private String value;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param value
+     *            値。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。<br>
+     *            小数点値の形式ではない場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public FloatingPointLiteralNode(String value) {
+        if (value == null) {
+            throw new NullPointerException("valueがnullです。");
+        }
+        if (!Validator.isFloatingPointLiteral(value)) {
+            throw new IllegalArgumentException("valueが小数点値の形式ではありません。");
+        }
+        this.value = value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        double value = Double.parseDouble(this.value);
+
+        context.getCommandList().add(new PushStackCommand(new FloatingPointLiteral(value)));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[0];
+    }
+
+    /**
+     * <p>
+     * 値を返します。
+     * </p>
+     * 
+     * @return 値。
+     */
+    public String getValue() {
+        return this.value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + "[" + this.value + "]";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/FunctionExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/FunctionExpressionNode.java
new file mode 100644 (file)
index 0000000..9133108
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.FunctionCallCommand;
+
+/**
+ * <p>
+ * FunctionExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class FunctionExpressionNode extends AbstractNode implements OperandNode {
+
+    private FunctionExpressionNode.FunctionNameNode functionName;
+
+    private FunctionExpressionNode.LeftBracketNode  leftBracket;
+
+    private OperandNode[]                           arguments;
+
+    private FunctionExpressionNode.CommaNode[]      argumentDelimiters;
+
+    private FunctionExpressionNode.RightBracketNode rightBracket;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param functionName
+     *            関数名。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。<br>
+     *            識別子の形式ではない場合、{@link IllegalArgumentException}例外をスローします。
+     * @param arguments
+     *            引数の配列。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。
+     */
+    public FunctionExpressionNode(FunctionExpressionNode.FunctionNameNode functionName, OperandNode[] arguments) {
+        if (functionName == null) {
+            throw new NullPointerException("functionNameがnullです。");
+        }
+        if (arguments == null) {
+            throw new NullPointerException("argumentsがnullです。");
+        }
+        for (int i = 0; i < arguments.length; i++) {
+            if (arguments[i] == null) {
+                throw new NullPointerException("arguments[" + i + "]がnullです。");
+            }
+        }
+        this.functionName = functionName;
+        this.leftBracket = new FunctionExpressionNode.LeftBracketNode();
+        this.arguments = arguments;
+        if (this.arguments.length > 0) {
+            this.argumentDelimiters = new FunctionExpressionNode.CommaNode[this.arguments.length - 1];
+            for (int i = 0; i < this.argumentDelimiters.length; i++) {
+                this.argumentDelimiters[i] = new FunctionExpressionNode.CommaNode();
+            }
+        }
+        this.rightBracket = new FunctionExpressionNode.RightBracketNode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        for (int i = 0; i < this.arguments.length; i++) {
+            this.arguments[i].compile(context);
+        }
+        context.getCommandList().add(new FunctionCallCommand(this.functionName.getName(), this.arguments.length));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        List nodeList = new ArrayList();
+        nodeList.add(this.functionName);
+        nodeList.add(this.leftBracket);
+        for (int i = 0; i < this.arguments.length; i++) {
+            if (i == 0) {
+                nodeList.add(this.arguments[i]);
+            } else {
+                nodeList.add(this.argumentDelimiters[i - 1]);
+                nodeList.add(this.arguments[i]);
+            }
+        }
+        nodeList.add(this.rightBracket);
+        return (Node[]) nodeList.toArray(new Node[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * FunctionExpressionの関数名を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class FunctionNameNode extends AbstractNode {
+
+        private String name;
+
+        /**
+         * <p>
+         * インスタンスを初期化します。
+         * </p>
+         * 
+         * @param name
+         *            関数名。nullの場合、{@link NullPointerException}例外をスローします。識別子の形式ではない場合、{@link IllegalArgumentException}例外をスローします。
+         */
+        public FunctionNameNode(String name) {
+            if (name == null) {
+                throw new NullPointerException("nameがnullです。");
+            }
+            if (!Pattern.matches("[\\u0024\\u0041-\\u005a\\u005f\\u0061-\\u007a\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff\\u0100-\\u1fff\\u3040-\\u318f\\u3300-\\u337f\\u3400-\\u3d2d\\u4e00-\\u9fff\\uf900-\\ufaff]([\\u0024\\u0041-\\u005a\\u005f\\u0061-\\u007a\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff\\u0100-\\u1fff\\u3040-\\u318f\\u3300-\\u337f\\u3400-\\u3d2d\\u4e00-\\u9fff\\uf900-\\ufaff]|[\\u0030-\\u0039\\u0660-\\u0669\\u06f0-\\u06f9\\u0966-\\u096f\\u09e6-\\u09ef\\u0a66-\\u0a6f\\u0ae6-\\u0aef\\u0b66-\\u0b6f\\u0be7-\\u0bef\\u0c66-\\u0c6f\\u0ce6-\\u0cef\\u0d66-\\u0d6f\\u0e50-\\u0e59\\u0ed0-\\u0ed9\\u1040-\\u1049])*", name)) {
+                throw new IllegalArgumentException("nameが識別子の形式ではありません。");
+            }
+            this.name = name;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * <p>
+         * 関数名を返します。
+         * </p>
+         * 
+         * @return 関数名。
+         */
+        public String getName() {
+            return this.name;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName() + "[" + this.name + "]";
+        }
+
+    }
+
+    /**
+     * <p>
+     * FunctionExpressionの"("演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class LeftBracketNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * FunctionExpressionの")"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class RightBracketNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * FunctionExpressionの","演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class CommaNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/InclusiveOrExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/InclusiveOrExpressionNode.java
new file mode 100644 (file)
index 0000000..63952ec
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.InclusiveOrCommand;
+
+/**
+ * <p>
+ * InclusiveOrExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class InclusiveOrExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            項の配列。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素数が2未満の場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public InclusiveOrExpressionNode(OperandNode[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+        }
+        if (nodes.length < 2) {
+            throw new IllegalArgumentException("nodes.length < 2です。");
+        }
+
+        List nodeList = new ArrayList();
+        for (int i = 0; i < nodes.length; i++) {
+            if (i > 0) {
+                nodeList.add(new InclusiveOrExpressionNode.OperatorNode());
+            }
+            nodeList.add(nodes[i]);
+        }
+
+        this.nodes = (Node[]) nodeList.toArray(new Node[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * InclusiveOrExpressionの"|"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new InclusiveOrCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/IntegerLiteralNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/IntegerLiteralNode.java
new file mode 100644 (file)
index 0000000..56457ac
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.PushStackCommand;
+import jp.sourceforge.expression_computer.type.IntegerLiteral;
+import jp.sourceforge.expression_computer.util.Validator;
+
+/**
+ * <p>
+ * IntegerLiteralを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class IntegerLiteralNode extends AbstractNode implements OperandNode {
+
+    private static final int RADIX_16 = 16;
+
+    private static final int RADIX_8  = 8;
+
+    private String           value;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param value
+     *            値。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。<br>
+     *            整数値の形式ではない場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public IntegerLiteralNode(String value) {
+        if (value == null) {
+            throw new NullPointerException("valueがnullです。");
+        }
+        if (!Validator.isIntegerLiteral(value)) {
+            throw new IllegalArgumentException("valueが整数値の形式ではありません。");
+        }
+        this.value = value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        long value;
+        if (this.value.startsWith("0x")) {
+            value = Long.parseLong(this.value.substring("0x".length()), IntegerLiteralNode.RADIX_16);
+        } else if (this.value.startsWith("0") && this.value.length() > 1) {
+            value = Long.parseLong(this.value.substring("0".length()), IntegerLiteralNode.RADIX_8);
+        } else {
+            value = Long.parseLong(this.value);
+        }
+
+        context.getCommandList().add(new PushStackCommand(new IntegerLiteral(value)));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[0];
+    }
+
+    /**
+     * <p>
+     * 値を返します。
+     * </p>
+     * 
+     * @return 値。
+     */
+    public String getValue() {
+        return this.value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + "[" + this.value + "]";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/MultiplicativeExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/MultiplicativeExpressionNode.java
new file mode 100644 (file)
index 0000000..ffcb9bc
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.DivideCommand;
+import jp.sourceforge.expression_computer.command.MultiplyCommand;
+import jp.sourceforge.expression_computer.command.SurplusCommand;
+
+/**
+ * <p>
+ * MultiplicativeExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class MultiplicativeExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            式の要素。"項 (演算子 項)+"という順序で並んでいる必要があります。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素の並び順が間違えている場合、配列の要素数が3未満の場合、配列の要素数が奇数ではない場合、{@link IllegalArgumentException}例外をスローします。<br>
+     */
+    public MultiplicativeExpressionNode(Node[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+            if ((i % 2 == 0) && !(nodes[i] instanceof OperandNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が項ではありません。");
+            } else if ((i % 2 == 1) && !(nodes[i] instanceof MultiplicativeExpressionNode.OperatorNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が演算子ではありません。");
+            }
+        }
+        if (nodes.length < 3) {
+            throw new IllegalArgumentException("nodes.length < 3です。");
+        }
+        if ((nodes.length % 2) != 1) {
+            throw new IllegalArgumentException("nodes.lengthが奇数ではありません。");
+        }
+
+        this.nodes = (Node[]) nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * MultiplicativeExpressionNodeの演算子を表す抽象基底ノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+
+    }
+
+    /**
+     * <p>
+     * MultiplicativeExpressionNodeの"*"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class MultiplyNode extends MultiplicativeExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new MultiplyCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * MultiplicativeExpressionNodeの"/"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class DivideNode extends MultiplicativeExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new DivideCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * MultiplicativeExpressionNodeの"%"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class SurplusNode extends MultiplicativeExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new SurplusCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/OperandNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/OperandNode.java
new file mode 100644 (file)
index 0000000..9986c17
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.Node;
+
+/**
+ * <p>
+ * オペランドであることを表すマーカー インターフェイスです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public interface OperandNode extends Node {
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PostDecrementExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PostDecrementExpressionNode.java
new file mode 100644 (file)
index 0000000..f403afa
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.PostDecrementCommand;
+
+/**
+ * <p>
+ * PostDecrementExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PostDecrementExpressionNode extends AbstractNode implements OperandNode {
+
+    private VariableNode                             operand;
+
+    private PostDecrementExpressionNode.OperatorNode operator;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operand
+     *            項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public PostDecrementExpressionNode(VariableNode operand) {
+        if (operand == null) {
+            throw new NullPointerException("operandがnullです。");
+        }
+        this.operand = operand;
+        this.operator = new PostDecrementExpressionNode.OperatorNode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand.compile(context);
+        this.operator.compile(context);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operand, this.operator };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * PostDecrementExpressionNodeの"--"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new PostDecrementCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PostIncrementExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PostIncrementExpressionNode.java
new file mode 100644 (file)
index 0000000..5a3e054
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.PostIncrementCommand;
+
+/**
+ * <p>
+ * PostIncrementExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PostIncrementExpressionNode extends AbstractNode implements OperandNode {
+
+    private VariableNode                             operand;
+
+    private PostIncrementExpressionNode.OperatorNode operator;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operand
+     *            項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public PostIncrementExpressionNode(VariableNode operand) {
+        if (operand == null) {
+            throw new NullPointerException("operandがnullです。");
+        }
+        this.operand = operand;
+        this.operator = new PostIncrementExpressionNode.OperatorNode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand.compile(context);
+        this.operator.compile(context);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operand, this.operator };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * PostIncrementExpressionNodeの"++"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new PostIncrementCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PreDecrementExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PreDecrementExpressionNode.java
new file mode 100644 (file)
index 0000000..fb7eff0
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.PreDecrementCommand;
+
+/**
+ * <p>
+ * PreDecrementExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PreDecrementExpressionNode extends AbstractNode implements OperandNode {
+
+    private PreDecrementExpressionNode.OperatorNode operator;
+
+    private VariableNode                            operand;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operand
+     *            項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public PreDecrementExpressionNode(VariableNode operand) {
+        if (operand == null) {
+            throw new NullPointerException("operandがnullです。");
+        }
+        this.operator = new PreDecrementExpressionNode.OperatorNode();
+        this.operand = operand;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand.compile(context);
+        this.operator.compile(context);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operator, this.operand };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * PreDecrementExpressionNodeの"--"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new PreDecrementCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PreIncrementExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/PreIncrementExpressionNode.java
new file mode 100644 (file)
index 0000000..aa033cd
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.PreIncrementCommand;
+
+/**
+ * <p>
+ * PreIncrementExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class PreIncrementExpressionNode extends AbstractNode implements OperandNode {
+
+    private PreIncrementExpressionNode.OperatorNode operator;
+
+    private VariableNode                            operand;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operand
+     *            項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public PreIncrementExpressionNode(VariableNode operand) {
+        if (operand == null) {
+            throw new NullPointerException("operandがnullです。");
+        }
+        this.operator = new PreIncrementExpressionNode.OperatorNode();
+        this.operand = operand;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand.compile(context);
+        this.operator.compile(context);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operator, this.operand };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * PreIncrementExpressionNodeの"++"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new PreIncrementCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Node[] getChildren() {
+            return new Node[0];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/RelationalExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/RelationalExpressionNode.java
new file mode 100644 (file)
index 0000000..565ab98
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.GreaterThanCommand;
+import jp.sourceforge.expression_computer.command.GreaterThanEqualCommand;
+import jp.sourceforge.expression_computer.command.LessThanCommand;
+import jp.sourceforge.expression_computer.command.LessThanEqualCommand;
+
+/**
+ * <p>
+ * Relational Expressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class RelationalExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            式の要素。"項 (演算子 項)+"という順序で並んでいる必要があります。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素の並び順が間違えている場合、配列の要素数が3未満の場合、配列の要素数が奇数ではない場合、{@link IllegalArgumentException}例外をスローします。<br>
+     */
+    public RelationalExpressionNode(Node[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+            if ((i % 2 == 0) && !(nodes[i] instanceof OperandNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が項ではありません。");
+            } else if ((i % 2 == 1) && !(nodes[i] instanceof RelationalExpressionNode.OperatorNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が演算子ではありません。");
+            }
+        }
+        if (nodes.length < 3) {
+            throw new IllegalArgumentException("nodes.length < 3です。");
+        }
+        if ((nodes.length % 2) != 1) {
+            throw new IllegalArgumentException("nodes.lengthが奇数ではありません。");
+        }
+
+        this.nodes = (Node[]) nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * RelationalExpressionNodeの演算子を表す抽象基底ノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+
+    }
+
+    /**
+     * <p>
+     * RelationalExpressionNodeの">"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class GreaterThanNode extends RelationalExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new GreaterThanCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * RelationalExpressionNodeの"<"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class LessThanNode extends RelationalExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new LessThanCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * RelationalExpressionNodeの">="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class GreaterThanEqualNode extends RelationalExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new GreaterThanEqualCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * RelationalExpressionNodeの"<="演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class LessThanEqualNode extends RelationalExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new LessThanEqualCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ShiftExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/ShiftExpressionNode.java
new file mode 100644 (file)
index 0000000..8730e09
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.ArithmeticRightShiftCommand;
+import jp.sourceforge.expression_computer.command.LeftShiftCommand;
+import jp.sourceforge.expression_computer.command.LogicalRightShiftCommand;
+
+/**
+ * <p>
+ * ShiftExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class ShiftExpressionNode extends AbstractNode implements OperandNode {
+
+    private Node[] nodes;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param nodes
+     *            式の要素。"項 (演算子 項)+"という順序で並んでいる必要があります。<br>
+     *            nullの場合、配列にnullがある場合、{@link NullPointerException}例外をスローします。<br>
+     *            配列の要素の並び順が間違えている場合、配列の要素数が3未満の場合、配列の要素数が奇数ではない場合、{@link IllegalArgumentException}例外をスローします。<br>
+     */
+    public ShiftExpressionNode(Node[] nodes) {
+        if (nodes == null) {
+            throw new NullPointerException("nodesがnullです。");
+        }
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i] == null) {
+                throw new NullPointerException("nodes[" + i + "]がnullです。");
+            }
+            if ((i % 2 == 0) && !(nodes[i] instanceof OperandNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が項ではありません。");
+            } else if ((i % 2 == 1) && !(nodes[i] instanceof ShiftExpressionNode.OperatorNode)) {
+                throw new IllegalArgumentException("nodes[" + i + "]が演算子ではありません。");
+            }
+        }
+        if (nodes.length < 3) {
+            throw new IllegalArgumentException("nodes.length < 3です。");
+        }
+        if ((nodes.length % 2) != 1) {
+            throw new IllegalArgumentException("nodes.lengthが奇数ではありません。");
+        }
+
+        this.nodes = (Node[]) nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.nodes[0].compile(context);
+        for (int i = 2; i < this.nodes.length; i += 2) {
+            this.nodes[i].compile(context);
+            this.nodes[i - 1].compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return (Node[]) this.nodes.clone();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * ShiftExpressionNodeの演算子を表す抽象基底ノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+
+    }
+
+    /**
+     * <p>
+     * ShiftExpressionNodeの"<<"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class LeftShiftNode extends ShiftExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new LeftShiftCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * ShiftExpressionNodeの">>"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class ArithmeticRightShiftNode extends ShiftExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new ArithmeticRightShiftCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * ShiftExpressionNodeの">>>"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class LogicalRightShiftNode extends ShiftExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new LogicalRightShiftCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/UnaryExpressionNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/UnaryExpressionNode.java
new file mode 100644 (file)
index 0000000..abd264a
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.SignReversingCommand;
+
+/**
+ * <p>
+ * UnaryExpressionを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class UnaryExpressionNode extends AbstractNode implements OperandNode {
+
+    private UnaryExpressionNode.OperatorNode operator;
+
+    private OperandNode                      operand;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operator
+     *            演算子。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @param operand
+     *            項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public UnaryExpressionNode(UnaryExpressionNode.OperatorNode operator, OperandNode operand) {
+        if (operator == null) {
+            throw new NullPointerException("operatorがnullです。");
+        }
+        if (operand == null) {
+            throw new NullPointerException("operandがnullです。");
+        }
+        this.operator = operator;
+        this.operand = operand;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand.compile(context);
+        if (this.operator != null) {
+            this.operator.compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operator, this.operand };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * UnaryExpressionNodeの演算子を表す抽象基底ノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+
+    }
+
+    /**
+     * <p>
+     * UnaryExpressionNodeの"+"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class PlusSignNode extends UnaryExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            // 何もしません。
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * UnaryExpressionNodeの"-"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class MinusSignNode extends UnaryExpressionNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new SignReversingCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/UnaryExpressionNotPlusMinusNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/UnaryExpressionNotPlusMinusNode.java
new file mode 100644 (file)
index 0000000..6c319fa
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.BitReversingCommand;
+import jp.sourceforge.expression_computer.command.NotCommand;
+
+/**
+ * <p>
+ * UnaryExpressionNotPlusMinusを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class UnaryExpressionNotPlusMinusNode extends AbstractNode implements OperandNode {
+
+    private UnaryExpressionNotPlusMinusNode.OperatorNode operator;
+
+    private OperandNode                                  operand;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param operator
+     *            演算子。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     * @param operand
+     *            項。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。
+     */
+    public UnaryExpressionNotPlusMinusNode(UnaryExpressionNotPlusMinusNode.OperatorNode operator, OperandNode operand) {
+        if (operator == null) {
+            throw new NullPointerException("operatorがnullです。");
+        }
+        if (operand == null) {
+            throw new NullPointerException("operandがnullです。");
+        }
+        this.operator = operator;
+        this.operand = operand;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        this.operand.compile(context);
+        if (this.operator != null) {
+            this.operator.compile(context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[] { this.operator, this.operand };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + this.toChildrenString();
+    }
+
+    /**
+     * <p>
+     * UnaryExpressionNotPlusMinusNodeの演算子を表す抽象基底ノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public abstract static class OperatorNode extends AbstractNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public final Node[] getChildren() {
+            return new Node[0];
+        }
+
+    }
+
+    /**
+     * <p>
+     * UnaryExpressionNotPlusMinusNodeの"~"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class BitReversingNode extends UnaryExpressionNotPlusMinusNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new BitReversingCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+    /**
+     * <p>
+     * UnaryExpressionNotPlusMinusNodeの"!"演算子を表すノードです。
+     * </p>
+     * 
+     * @author uguu@users.sourceforge.jp
+     */
+    public static final class NotNode extends UnaryExpressionNotPlusMinusNode.OperatorNode {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void compile(CompileContext context) {
+            context.getCommandList().add(new NotCommand());
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String toString() {
+            return this.getClass().getName();
+        }
+
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/VariableNode.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/VariableNode.java
new file mode 100644 (file)
index 0000000..c0fbd86
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.node;
+
+import jp.sourceforge.expression_computer.CompileContext;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.command.PushStackCommand;
+import jp.sourceforge.expression_computer.type.Variable;
+import jp.sourceforge.expression_computer.util.Validator;
+
+/**
+ * <p>
+ * Variableを表すノードです。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class VariableNode extends AbstractNode implements OperandNode {
+
+    private String name;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param name
+     *            変数名。<br>
+     *            nullの場合、{@link NullPointerException}例外をスローします。<br>
+     *            識別子の形式ではない場合、{@link IllegalArgumentException}例外をスローします。
+     */
+    public VariableNode(String name) {
+        if (name == null) {
+            throw new NullPointerException("nameがnullです。");
+        }
+        if (!Validator.isIdentifier(name)) {
+            throw new IllegalArgumentException("nameが識別子の形式ではありません。");
+        }
+        this.name = name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void compile(CompileContext context) {
+        context.getCommandList().add(new PushStackCommand(new Variable(this.name)));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node[] getChildren() {
+        return new Node[0];
+    }
+
+    /**
+     * <p>
+     * 変数名を返します。
+     * </p>
+     * 
+     * @return 変数名。
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + "[" + this.name + "]";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/package.html b/expression-computer/src/main/java/jp/sourceforge/expression_computer/node/package.html
new file mode 100644 (file)
index 0000000..5416363
--- /dev/null
@@ -0,0 +1,3 @@
+<body>
+       <p>抽象構文木のノードを格納しています。</p>
+</body>
\ No newline at end of file
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/package.html b/expression-computer/src/main/java/jp/sourceforge/expression_computer/package.html
new file mode 100644 (file)
index 0000000..13cc622
--- /dev/null
@@ -0,0 +1,3 @@
+<body>
+    <p>数式の解析、計算を行う機能を持ちます。</p>
+</body>
\ No newline at end of file
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/type/FloatingPointLiteral.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/type/FloatingPointLiteral.java
new file mode 100644 (file)
index 0000000..040efd6
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.type;
+
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeException;
+import jp.sourceforge.expression_computer.ComputeObject;
+
+/**
+ * <p>
+ * 浮動小数点値を表します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class FloatingPointLiteral implements ComputeObject {
+
+    private double value;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param value
+     *            値。
+     */
+    public FloatingPointLiteral(double value) {
+        this.value = value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double getValue(ComputeContext context) {
+        return this.value;
+    }
+
+    /**
+     * <p>
+     * 浮動小数点値の値を変更する事はできません。常に{@link ComputeException}例外をスローします。
+     * </p>
+     * 
+     * @param value
+     *            値。
+     * @param context
+     *            計算コンテキスト。
+     */
+    public void setValue(double value, ComputeContext context) {
+        throw new ComputeException("浮動小数点値に値を設定する事はできません。");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + "[" + this.value + "]";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/type/IntegerLiteral.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/type/IntegerLiteral.java
new file mode 100644 (file)
index 0000000..85bdc8b
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.type;
+
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeException;
+import jp.sourceforge.expression_computer.ComputeObject;
+
+/**
+ * <p>
+ * 整数値を表します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class IntegerLiteral implements ComputeObject {
+
+    private long value;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param value
+     *            値。
+     */
+    public IntegerLiteral(long value) {
+        this.value = value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double getValue(ComputeContext context) {
+        return this.value;
+    }
+
+    /**
+     * <p>
+     * 整数値の値を変更する事はできません。常に{@link ComputeException}例外をスローします。
+     * </p>
+     * 
+     * @param value
+     *            値。
+     * @param context
+     *            計算コンテキスト。
+     */
+    public void setValue(double value, ComputeContext context) {
+        throw new ComputeException("整数値に値を設定する事はできません。");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + "[" + this.value + "]";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/type/Variable.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/type/Variable.java
new file mode 100644 (file)
index 0000000..572c99b
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.type;
+
+import jp.sourceforge.expression_computer.ComputeContext;
+import jp.sourceforge.expression_computer.ComputeObject;
+import jp.sourceforge.expression_computer.util.Validator;
+
+/**
+ * <p>
+ * 変数を表します。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class Variable implements ComputeObject {
+
+    private String name;
+
+    /**
+     * <p>
+     * インスタンスを初期化します。
+     * </p>
+     * 
+     * @param name
+     *            変数名。
+     */
+    public Variable(String name) {
+        if (name == null) {
+            throw new NullPointerException("nameがnullです。");
+        }
+        if (!Validator.isIdentifier(name)) {
+            throw new IllegalArgumentException("nameが変数名の形式ではありません。");
+        }
+        this.name = name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double getValue(ComputeContext context) {
+        return context.getVariable(this.name);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValue(double value, ComputeContext context) {
+        context.setVariable(this.name, value);
+    }
+
+    /**
+     * <p>
+     * 変数名を返します。
+     * </p>
+     * 
+     * @return 変数名。
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return this.getClass().getName() + "[" + this.name + "]";
+    }
+
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/type/package.html b/expression-computer/src/main/java/jp/sourceforge/expression_computer/type/package.html
new file mode 100644 (file)
index 0000000..d7d5388
--- /dev/null
@@ -0,0 +1,3 @@
+<body>
+       <p>計算オブジェクトの定義を格納しています。</p>
+</body>
\ No newline at end of file
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/util/Validator.java b/expression-computer/src/main/java/jp/sourceforge/expression_computer/util/Validator.java
new file mode 100644 (file)
index 0000000..b40aa38
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2006 uguu@users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jp.sourceforge.expression_computer.util;
+
+import java.util.regex.Pattern;
+
+/**
+ * <p>
+ * 文字列の形式を検証する機能を持ちます。
+ * </p>
+ * 
+ * @author uguu@users.sourceforge.jp
+ */
+public final class Validator {
+
+    private Validator() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * <p>
+     * 文字列の形式が小数点値の形式かどうかを検証します。
+     * </p>
+     * 
+     * @param text
+     *            検証する文字列。
+     * @return 文字列が小数点値の形式の場合はtrue、そうでない場合はfalse。
+     */
+    public static boolean isFloatingPointLiteral(String text) {
+        return Pattern.matches("[0-9]*\\.[0-9]+", text);
+    }
+
+    /**
+     * <p>
+     * 文字列の形式が整数値の形式かどうかを検証します。
+     * </p>
+     * 
+     * @param text
+     *            検証する文字列。
+     * @return 文字列が整数値の形式の場合はtrue、そうでない場合はfalse。
+     */
+    public static boolean isIntegerLiteral(String text) {
+        return Pattern.matches("[1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]+|0", text);
+    }
+
+    /**
+     * <p>
+     * 文字列の形式が識別子の形式かどうかを検証します。
+     * </p>
+     * 
+     * @param text
+     *            検証する文字列。
+     * @return 文字列が識別子の形式の場合はtrue、そうでない場合はfalse。
+     */
+    public static boolean isIdentifier(String text) {
+        return Pattern.matches("[\\u0024\\u0041-\\u005a\\u005f\\u0061-\\u007a\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff\\u0100-\\u1fff\\u3040-\\u318f\\u3300-\\u337f\\u3400-\\u3d2d\\u4e00-\\u9fff\\uf900-\\ufaff]([\\u0024\\u0041-\\u005a\\u005f\\u0061-\\u007a\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff\\u0100-\\u1fff\\u3040-\\u318f\\u3300-\\u337f\\u3400-\\u3d2d\\u4e00-\\u9fff\\uf900-\\ufaff]|[\\u0030-\\u0039\\u0660-\\u0669\\u06f0-\\u06f9\\u0966-\\u096f\\u09e6-\\u09ef\\u0a66-\\u0a6f\\u0ae6-\\u0aef\\u0b66-\\u0b6f\\u0be7-\\u0bef\\u0c66-\\u0c6f\\u0ce6-\\u0cef\\u0d66-\\u0d6f\\u0e50-\\u0e59\\u0ed0-\\u0ed9\\u1040-\\u1049])*", text);
+    }
+}
diff --git a/expression-computer/src/main/java/jp/sourceforge/expression_computer/util/package.html b/expression-computer/src/main/java/jp/sourceforge/expression_computer/util/package.html
new file mode 100644 (file)
index 0000000..a89b663
--- /dev/null
@@ -0,0 +1,3 @@
+<body>
+       <p>ユーティリティを格納しています。</p>
+</body>
\ No newline at end of file
diff --git a/expression-computer/src/main/java/overview.html b/expression-computer/src/main/java/overview.html
new file mode 100644 (file)
index 0000000..066fd5a
--- /dev/null
@@ -0,0 +1,8 @@
+<body>
+    <p>数式計算機は、数式の解析、計算を行う機能を持ちます。数式には、四則演算や括弧を含む各種演算子、変数、関数を使用することができます。また、実行する前の状態である命令列を外部ファイルに保存したり、それを読み込んで実行する事ができます。</p>
+    <p>以下のように、Computerクラスで数式を計算する事ができます。</p>
+    <pre>
+Computer comp = new Computer();
+double value = comp.compute("1 + 2"); // value == 3
+    </pre>
+</body>
\ No newline at end of file
diff --git a/expression-computer/src/site/xdoc/downloads.xml b/expression-computer/src/site/xdoc/downloads.xml
new file mode 100644 (file)
index 0000000..a3366d1
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<document>
+    <properties>
+        <author email="uguu@users.sourceforge.jp">uguu</author>
+        <title>Download</title>
+    </properties>
+    <body>
+        <section name="ダウンロード">
+            <table>
+                <tr>
+                    <th>Version</th>
+                    <th>Type</th>
+                </tr>
+                <tr>
+                    <td>0.1.0</td>
+                    <td>
+                        <a href="http://prdownloads.sourceforge.jp/rpolishcomop/21835/expression-computer-0.1.0.zip">expression-computer-0.1.0.zip</a><br/>
+                        <a href="http://prdownloads.sourceforge.jp/rpolishcomop/21835/expression-computer-0.1.0.tar.gz">expression-computer-0.1.0.tar.gz</a><br/>
+                        <a href="http://prdownloads.sourceforge.jp/rpolishcomop/21835/expression-computer-0.1.0-src.zip">expression-computer-0.1.0-src.zip</a><br/>
+                        <a href="http://prdownloads.sourceforge.jp/rpolishcomop/21835/expression-computer-0.1.0-src.tar.gz">expression-computer-0.1.0-src.tar.gz</a>
+                    </td>
+                </tr>
+                <tr>
+                    <td>1.0.0-beta-1</td>
+                    <td>
+                        <a href="http://prdownloads.sourceforge.jp/rpolishcomop/22449/expression-computer-1.0.0-beta-1.zip">expression-computer-1.0.0-beta-1.zip</a><br/>
+                        <a href="http://prdownloads.sourceforge.jp/rpolishcomop/22449/expression-computer-1.0.0-beta-1.tar.gz">expression-computer-1.0.0-beta-1.tar.gz</a><br/>
+                        <a href="http://prdownloads.sourceforge.jp/rpolishcomop/22449/expression-computer-1.0.0-beta-1-src.zip">expression-computer-1.0.0-beta-1-src.zip</a><br/>
+                        <a href="http://prdownloads.sourceforge.jp/rpolishcomop/22449/expression-computer-1.0.0-beta-1-src.tar.gz">expression-computer-1.0.0-beta-1-src.tar.gz</a>
+                    </td>
+                </tr>
+            </table>
+        </section>
+    </body>
+</document>
diff --git a/expression-computer/src/site/xdoc/environment.xml b/expression-computer/src/site/xdoc/environment.xml
new file mode 100644 (file)
index 0000000..66b04b2
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<document>
+    <properties>
+        <author email="uguu@users.sourceforge.jp">uguu</author>
+        <title>Environment</title>
+    </properties>
+    <body>
+        <section name="開発環境">
+            <p>数式計算機は、以下のツールを使用して開発を行っています。</p>
+            <ul>
+                <li>Java 2 SDK, Standard Edition 1.4.2_12</li>
+                <li>Eclipse 3.1.2
+                    <ul>
+                        <li>Checkstyle Plug-in 4.1.1</li>
+                    </ul>
+                </li>
+                <li>Maven 1.0.2
+                    <ul>
+                        <li>maven-checkstyle-plugin 3.0.1</li>
+                    </ul>
+                </li>
+            </ul>
+        </section>
+    </body>
+</document>
diff --git a/expression-computer/src/site/xdoc/index.xml b/expression-computer/src/site/xdoc/index.xml
new file mode 100644 (file)
index 0000000..262aa93
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<document>
+    <properties>
+        <author email="uguu@users.sourceforge.jp">uguu</author>
+        <title>Overview</title>
+    </properties>
+    <body>
+        <section name="数式計算機 - 概要">
+            <p>数式計算機は、数式の解析、計算を行う機能を持ちます。数式には、四則演算や括弧を含む各種演算子、変数、関数を使用することができます。また、実行する前の状態である命令列を外部ファイルに保存したり、それを読み込んで実行する事ができます。</p>
+            <p>以下のように、Computerクラスで数式を計算する事ができます。</p>
+            <source>
+Computer comp = new Computer();
+double value = comp.compute("1 + 2"); // value == 3
+            </source>
+        </section>
+    </body>
+</document>
diff --git a/expression-computer/src/site/xdoc/navigation.xml b/expression-computer/src/site/xdoc/navigation.xml
new file mode 100644 (file)
index 0000000..92a2328
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project name="RPN Computer">
+    <title>数式計算機</title>
+    <body>
+        <breadcrumbs>
+            <item
+                name="SourceForge.jp Site"
+                href="http://sourceforge.jp/projects/rpolishcomop/"
+            />
+        </breadcrumbs>
+        <links>
+            <item
+                name="SourceForge.jp Site"
+                href="http://sourceforge.jp/projects/rpolishcomop/"
+            />
+        </links>
+        <menu name="数式計算機">
+            <item name="概要" href="index.html"/>
+            <item name="使い方" href="tutorial.html"/>
+            <item name="ダウンロード" href="downloads.html"/>
+            <item name="JavaDoc" href="apidocs/index.html" target="_blank"/>
+            <item name="ライセンス" href="license.html"/>
+            <item name="開発環境" href="environment.html"/>
+        </menu>
+    </body>
+</project>
diff --git a/expression-computer/src/site/xdoc/tutorial.xml b/expression-computer/src/site/xdoc/tutorial.xml
new file mode 100644 (file)
index 0000000..71dcd8d
--- /dev/null
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<document>
+    <properties>
+        <author email="uguu@users.sourceforge.jp">uguu</author>
+        <title>Tutorial</title>
+    </properties>
+    <body>
+        <section name="使い方">
+            <p>数式の解析、計算は、以下の段階を経て行われます。</p>
+            <ol>
+                <li>構文解析器による、文字列で表された通常の数式から抽象構文木の構築(構文解析)。</li>
+                <li>コンパイラーによる、抽象構文木から命令列への変換(コンパイル)。</li>
+                <li>計算機による、命令列の実行(計算)。</li>
+            </ol>
+            <subsection name="構文解析">
+                <p>構文解析はParserクラスによって行われます。Parserクラスは、文字列を読み込み、構文規則に従って抽象構文木を構築します。</p>
+                <source>
+Parser parser = new Parser();
+Node Node = parser.parse("1 + 2"); // top level node
+                </source>
+                <p>得られたNodeインスタンスが、抽象構文木の最上位ノードです。全てのノードはNodeクラスで表されます。実際は各構文規則に対応するノードのクラスが有り、それらのインスタンスで構成されています。</p>
+                <p>抽象構文木は、組替えたり(TODO: 0.1.xでは難しい。簡単にできるようにする)、自分で構築する事ができます。</p>
+                <source>
+IntegerLiteralNode value1 = new IntegerLiteralNode("1");
+IntegerLiteralNode value2 = new IntegerLiteralNode("2");
+AdditiveExpressionNode.OperatorNode addOpe = new AdditiveExpressionNode.AddNode();
+AdditiveExpressionNode addExp = new AdditiveExpressionNode(value1, addOpe, value2);
+
+Node expNode = new ExpressionStatementNode(addExp); // top level node
+                </source>
+                <p>構文規則は以下の通りです(TODO: JavaCC構文規則を記載する)。</p>
+            </subsection>
+            <subsection name="コンパイル">
+                <p>コンパイルはCompilerクラスによって行われます。Compilerクラスは、Nodeインスタンスを読み込み、命令列へ変換します。</p>
+                <source>
+Compiler compiler = new Compiler();
+CommandList cl = compiler.compile(node); // command list
+                </source>
+                <p>得られたCommandListインスタンスが、命令列を表します。CommandListインスタンスはCommandインスタンスのコンテナであり、Commandクラスは1つの命令を表します。</p>
+                <p>命令列は、組替えたり、自分で構築する事ができます(TODO: イミュータブルじゃないし、ちゃんとListを実装する)。</p>
+                <source>
+Command[] commands = new Command[3];
+commands[0] = new PushStackCommand(1);
+commands[1] = new PushStackCommand(2);
+commands[2] = new AddCommand();
+
+CommandList cl = new CommandList(commands);
+                </source>
+            </subsection>
+            <subsection name="計算">
+                <p>計算はComputerクラスによって行われます。Computerクラスは、命令列を読み込み、実行します。</p>
+                <source>
+Computer comp = new Computer();
+double value = comp.compute(cl);
+                </source>
+                <p>命令列ではなく文字列を読み込ませることで、構文解析、コンパイル、計算を一度にすることができます。</p>
+                <source>
+Computer comp = new Computer();
+double value = comp.compute("1 + 2");
+                </source>
+                <p>得られたdouble値が計算結果です。計算は、全てdouble型で行われます。</p>
+            </subsection>
+            <subsection name="変数">
+                <p>数式中で変数を使用することができます。以下のように使用します。</p>
+                <source>
+Computer comp = new Computer();
+comp.setVariable("x", 10);
+comp.setVariable("y", 0);
+
+double result = comp.compute("y = x * 2 + 1"); // 11
+double xValue = comp.getVariable("x"); // 10
+double yValue = comp.getVariable("y"); // 11
+                </source>
+                <p>数式中で使用する変数は、計算前に定義する必要があります。変数の定義はsetVariable()メソッドで行います。今回の数式で使用されたxのようにあらかじめ値を設定します。yのように数式中で設定される場合は、適当な値で構いません。変数の値は、計算前でも後でも、getVariable()メソッドで取得することが出来ます。計算後ならば、計算中で代入された値に変更されています。</p>
+            </subsection>
+            <subsection name="関数">
+                <p>数式中で関数を呼び出すことが出来ます。以下のように使用します。</p>
+                <source>
+class SinFunction implements Function {
+    double call(double[] arguments) {
+        return Math.sin(arguments[0]);
+    }
+}
+                </source>
+                <source>
+Computer comp = new Computer();
+comp.addFunction("sin", new SinFunction());
+comp.setVariable("PI", Math.PI);
+
+double result = comp.compute("sin(0.5 * PI)"); // about 1
+                </source>
+                <p>数式中で使用する関数は、計算前に定義する必要があります。定義は、Functionインターフェイスを実装し、そのインスタンスをaddFunction()メソッドに指定します。call()メソッドは、数式中で指定された引数がargumentsに渡されるので、それらを計算し、返します。</p>
+            </subsection>
+            <subsection name="演算子">
+                <p>以下の演算子をサポートします。</p>
+                <dl>
+                    <dt>+, -, *, /, %</dt>
+                    <dd>加算、減算、乗算、除算、剰余算演算子。</dd>
+                    <dt>&gt;, &lt;, &gt;=, &lt;=, ==, !=</dt>
+                    <dd>比較演算子。真の場合は1、偽の場合は0を返します。</dd>
+                    <dt>++, --</dt>
+                    <dd>前置、後置インクリメント、デクリメント。</dd>
+                    <dt>&amp;, |, ^</dt>
+                    <dd>論理積、論理和、排他的論理和。</dd>
+                    <dt>&amp;&amp;, ||</dt>
+                    <dd>条件論理積、条件論理和。</dd>
+                    <dt>&lt;&lt;, &gt;&gt;, &gt;&gt;&gt;</dt>
+                    <dd>シフト演算子。</dd>
+                    <dt>?:</dt>
+                    <dd>条件演算子。</dd>
+                    <dt>=, +=, -=, *=, /=, %=, &amp;=, |=, ^=, &lt;=, &gt;&gt;=, &gt;&gt;&gt;=</dt>
+                    <dd>代入演算子。</dd>
+                </dl>
+            </subsection>
+        </section>
+    </body>
+</document>
diff --git a/expression-computer/src/test/java/jp/sourceforge/expression_computer/test/CompilerTest.java b/expression-computer/src/test/java/jp/sourceforge/expression_computer/test/CompilerTest.java
new file mode 100644 (file)
index 0000000..b6c3c97
--- /dev/null
@@ -0,0 +1,1665 @@
+
+package jp.sourceforge.expression_computer.test;
+
+import jp.sourceforge.expression_computer.Command;
+import jp.sourceforge.expression_computer.CommandList;
+import jp.sourceforge.expression_computer.Compiler;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.Parser;
+import jp.sourceforge.expression_computer.command.AddCommand;
+import jp.sourceforge.expression_computer.command.AndCommand;
+import jp.sourceforge.expression_computer.command.ArithmeticRightShiftCommand;
+import jp.sourceforge.expression_computer.command.BitReversingCommand;
+import jp.sourceforge.expression_computer.command.ConditionCommand;
+import jp.sourceforge.expression_computer.command.ConditionalAndCommand;
+import jp.sourceforge.expression_computer.command.ConditionalOrCommand;
+import jp.sourceforge.expression_computer.command.DivideCommand;
+import jp.sourceforge.expression_computer.command.EqualCommand;
+import jp.sourceforge.expression_computer.command.ExclusiveOrCommand;
+import jp.sourceforge.expression_computer.command.FunctionCallCommand;
+import jp.sourceforge.expression_computer.command.GreaterThanCommand;
+import jp.sourceforge.expression_computer.command.GreaterThanEqualCommand;
+import jp.sourceforge.expression_computer.command.InclusiveOrCommand;
+import jp.sourceforge.expression_computer.command.LeftShiftCommand;
+import jp.sourceforge.expression_computer.command.LessThanCommand;
+import jp.sourceforge.expression_computer.command.LessThanEqualCommand;
+import jp.sourceforge.expression_computer.command.LogicalRightShiftCommand;
+import jp.sourceforge.expression_computer.command.MultiplyCommand;
+import jp.sourceforge.expression_computer.command.NotCommand;
+import jp.sourceforge.expression_computer.command.NotEqualCommand;
+import jp.sourceforge.expression_computer.command.PostDecrementCommand;
+import jp.sourceforge.expression_computer.command.PostIncrementCommand;
+import jp.sourceforge.expression_computer.command.PreDecrementCommand;
+import jp.sourceforge.expression_computer.command.PreIncrementCommand;
+import jp.sourceforge.expression_computer.command.PushStackCommand;
+import jp.sourceforge.expression_computer.command.SetVariableCommand;
+import jp.sourceforge.expression_computer.command.SignReversingCommand;
+import jp.sourceforge.expression_computer.command.SubtractCommand;
+import jp.sourceforge.expression_computer.command.SurplusCommand;
+import jp.sourceforge.expression_computer.type.FloatingPointLiteral;
+import jp.sourceforge.expression_computer.type.IntegerLiteral;
+import jp.sourceforge.expression_computer.type.Variable;
+import junit.framework.TestCase;
+
+public class CompilerTest extends TestCase {
+
+    public CompilerTest(String name) {
+        super(name);
+    }
+
+    public void testFail_null1() {
+        Compiler compiler = new Compiler();
+        try {
+            compiler.compile(null);
+            fail();
+        } catch (NullPointerException e) {
+            assertEquals("nodeがnullです。", e.getMessage());
+        }
+    }
+
+    public void testNormal_IntegerLiteral1() {
+        String exp = "1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+    }
+
+    public void testNormal_IntegerLiteral2() {
+        String exp = "123456789";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123456789, c);
+    }
+
+    public void testNormal_IntegerLiteral3() {
+        String exp = "0xfFff";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(65535, c);
+    }
+
+    public void testNormal_IntegerLiteral4() {
+        String exp = "07777";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(4095, c);
+    }
+
+    public void testNormal_IntegerLiteral5() {
+        String exp = "0";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+    }
+
+    public void testNormal_FloatingPointLiteral1() {
+        String exp = "123.456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFloatingPointLiteral(123.456, c);
+    }
+
+    public void testNormal_FloatingPointLiteral2() {
+        String exp = "0.123456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFloatingPointLiteral(0.123456, c);
+    }
+
+    public void testNormal_FloatingPointLiteral3() {
+        String exp = ".123456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFloatingPointLiteral(0.123456, c);
+    }
+
+    public void testNormal_FloatingPointLiteral4() {
+        String exp = "0.0";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFloatingPointLiteral(0, c);
+    }
+
+    public void testNormal_FloatingPointLiteral5() {
+        String exp = ".0";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFloatingPointLiteral(0, c);
+    }
+
+    public void testNormal_FunctionExpression1() {
+        String exp = "foo()";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFunctionCall("foo", 0, c);
+    }
+
+    public void testNormal_FunctionExpression2() {
+        String exp = "foo(1, 2)";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertFunctionCall("foo", 2, c);
+    }
+
+    public void testNormal_FunctionExpression3() {
+        String exp = "foo(1 + 2)";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(4, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof AddCommand);
+
+        c = cl.getCommand(3);
+        assertFunctionCall("foo", 1, c);
+    }
+
+    public void testNormal_FunctionExpression4() {
+        String exp = "foo() + bar()";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFunctionCall("foo", 0, c);
+
+        c = cl.getCommand(1);
+        assertFunctionCall("bar", 0, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof AddCommand);
+    }
+
+    public void testNormal_Variable1() {
+        String exp = "x";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+    }
+
+    public void testNormal_Variable2() {
+        String exp = "abc123_";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("abc123_", c);
+    }
+
+    public void testNormal_Variable3() {
+        String exp = "_abc";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("_abc", c);
+    }
+
+    public void testNormal_Variable4() {
+        String exp = "ほげ";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("ほげ", c);
+    }
+
+    public void testNormal_ParenthesesExpression1() {
+        String exp = "(1 + 2)";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof AddCommand);
+    }
+
+    public void testNormal_ParenthesesExpression2() {
+        String exp = "(1 + (2 - 3))";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof SubtractCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof AddCommand);
+    }
+
+    public void testNormal_PreIncrementExpression1() {
+        String exp = "++x";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(2, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof PreIncrementCommand);
+    }
+
+    public void testNormal_PostIncrementExpression1() {
+        String exp = "x++";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(2, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof PostIncrementCommand);
+    }
+
+    public void testNormal_PreDecrementExpression1() {
+        String exp = "--x";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(2, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof PreDecrementCommand);
+    }
+
+    public void testNormal_PostDecrementExpression1() {
+        String exp = "x--";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(2, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof PostDecrementCommand);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus1() {
+        String exp = "~1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(2, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof BitReversingCommand);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus2() {
+        String exp = "~(~1)";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof BitReversingCommand);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof BitReversingCommand);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus3() {
+        String exp = "!0";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(2, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof NotCommand);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus4() {
+        String exp = "!(!9)";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(9, c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof NotCommand);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof NotCommand);
+    }
+
+    public void testNormal_UnaryExpression1() {
+        String exp = "+0";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+    }
+
+    public void testNormal_UnaryExpression2() {
+        String exp = "+(+999)";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(1, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(999, c);
+    }
+
+    public void testNormal_UnaryExpression3() {
+        String exp = "-0";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(2, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof SignReversingCommand);
+    }
+
+    public void testNormal_UnaryExpression4() {
+        String exp = "-(-999)";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(999, c);
+
+        c = cl.getCommand(1);
+        assertTrue(c instanceof SignReversingCommand);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof SignReversingCommand);
+    }
+
+    public void testNormal_MultiplicativeExpression1() {
+        String exp = "2 * 3";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof MultiplyCommand);
+    }
+
+    public void testNormal_MultiplicativeExpression2() {
+        String exp = "4 / 2";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(4, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof DivideCommand);
+    }
+
+    public void testNormal_MultiplicativeExpression3() {
+        String exp = "10 % 3";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(10, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof SurplusCommand);
+    }
+
+    public void testNormal_MultiplicativeExpression4() {
+        String exp = "2 * 6 / 3 % 3";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(7, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(6, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof MultiplyCommand);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof DivideCommand);
+
+        c = cl.getCommand(5);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(6);
+        assertTrue(c instanceof SurplusCommand);
+    }
+
+    public void testNormal_AdditiveExpression1() {
+        String exp = "1 + 2";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof AddCommand);
+    }
+
+    public void testNormal_AdditiveExpression2() {
+        String exp = "1 - 2";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof SubtractCommand);
+    }
+
+    public void testNormal_AdditiveExpression3() {
+        String exp = "1 - 2 + 3";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof SubtractCommand);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof AddCommand);
+    }
+
+    public void testNormal_ShiftExpression1() {
+        String exp = "0 << 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof LeftShiftCommand);
+    }
+
+    public void testNormal_ShiftExpression2() {
+        String exp = "0 >> 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof ArithmeticRightShiftCommand);
+    }
+
+    public void testNormal_ShiftExpression3() {
+        String exp = "0 >>> 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof LogicalRightShiftCommand);
+    }
+
+    public void testNormal_ShiftExpression4() {
+        String exp = "1 << 2 << 3";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof LeftShiftCommand);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof LeftShiftCommand);
+    }
+
+    public void testNormal_RelationalExpression1() {
+        String exp = "123 > 122";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(122, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof GreaterThanCommand);
+    }
+
+    public void testNormal_RelationalExpression2() {
+        String exp = "122 < 123";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(122, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof LessThanCommand);
+    }
+
+    public void testNormal_RelationalExpression3() {
+        String exp = "123 >= 122";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(122, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof GreaterThanEqualCommand);
+    }
+
+    public void testNormal_RelationalExpression4() {
+        String exp = "122 <= 123";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(122, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof LessThanEqualCommand);
+    }
+
+    public void testNormal_RelationalExpression5() {
+        String exp = "0 > 0 > 0";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof GreaterThanCommand);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof GreaterThanCommand);
+    }
+
+    public void testNormal_EqualityExpression1() {
+        String exp = "123.456 == 123.456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFloatingPointLiteral(123.456, c);
+
+        c = cl.getCommand(1);
+        assertFloatingPointLiteral(123.456, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof EqualCommand);
+    }
+
+    public void testNormal_EqualityExpression2() {
+        String exp = "123.456 != 123.456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertFloatingPointLiteral(123.456, c);
+
+        c = cl.getCommand(1);
+        assertFloatingPointLiteral(123.456, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof NotEqualCommand);
+    }
+
+    public void testNormal_EqualityExpression3() {
+        String exp = "0 == 0 == 0";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof EqualCommand);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof EqualCommand);
+    }
+
+    public void testNormal_AndExpression1() {
+        String exp = "123 & 456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(456, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof AndCommand);
+    }
+
+    public void testNormal_AndExpression2() {
+        String exp = "123 & 456 & 789";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(456, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof AndCommand);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(789, c);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof AndCommand);
+    }
+
+    public void testNormal_ExclusiveOrExpression1() {
+        String exp = "123 ^ 456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(456, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof ExclusiveOrCommand);
+    }
+
+    public void testNormal_ExclusiveOrExpression2() {
+        String exp = "123 ^ 456 ^ 789";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(456, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof ExclusiveOrCommand);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(789, c);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof ExclusiveOrCommand);
+    }
+
+    public void testNormal_InclusiveOrExpression1() {
+        String exp = "123 | 456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(456, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof InclusiveOrCommand);
+    }
+
+    public void testNormal_InclusiveOrExpression2() {
+        String exp = "123 | 456 | 789";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(456, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof InclusiveOrCommand);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(789, c);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof InclusiveOrCommand);
+    }
+
+    public void testNormal_ConditionalAndExpression1() {
+        String exp = "0 && 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof ConditionalAndCommand);
+    }
+
+    public void testNormal_ConditionalOrExpression1() {
+        String exp = "0 || 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof ConditionalOrCommand);
+    }
+
+    public void testNormal_ConditionalExpression1() {
+        String exp = "0 ? 123 : 456";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(4, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(456, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof ConditionCommand);
+    }
+
+    public void testNormal_ConditionalExpression2() {
+        String exp = "0 ? 1 : 2 ? 3 : 4";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(7, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertIntegerLiteral(0, c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(3);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(4);
+        assertIntegerLiteral(4, c);
+
+        c = cl.getCommand(5);
+        assertTrue(c instanceof ConditionCommand);
+
+        c = cl.getCommand(6);
+        assertTrue(c instanceof ConditionCommand);
+    }
+
+    public void testNormal_AssignmentExpression1() {
+        String exp = "x = 123";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(3, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertIntegerLiteral(123, c);
+
+        c = cl.getCommand(2);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression2() {
+        String exp = "x += 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof AddCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression3() {
+        String exp = "x -= 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof SubtractCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression4() {
+        String exp = "x *= 2";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(2, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof MultiplyCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression5() {
+        String exp = "x /= 3";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(3, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof DivideCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression6() {
+        String exp = "x %= 4";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(4, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof SurplusCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression7() {
+        String exp = "x &= 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof AndCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression8() {
+        String exp = "x ^= 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof ExclusiveOrCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression9() {
+        String exp = "x |= 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof InclusiveOrCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression10() {
+        String exp = "x <<= 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof LeftShiftCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression11() {
+        String exp = "x >>= 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof ArithmeticRightShiftCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression12() {
+        String exp = "x >>>= 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("x", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof LogicalRightShiftCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    public void testNormal_AssignmentExpression13() {
+        String exp = "x = y = 1";
+
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        assertEquals(5, cl.size());
+
+        Command c = cl.getCommand(0);
+        assertVariable("x", c);
+
+        c = cl.getCommand(1);
+        assertVariable("y", c);
+
+        c = cl.getCommand(2);
+        assertIntegerLiteral(1, c);
+
+        c = cl.getCommand(3);
+        assertTrue(c instanceof SetVariableCommand);
+
+        c = cl.getCommand(4);
+        assertTrue(c instanceof SetVariableCommand);
+    }
+
+    private void assertIntegerLiteral(double value, Command c) {
+        PushStackCommand pushStack = (PushStackCommand) c;
+        IntegerLiteral integerLiteral = (IntegerLiteral) pushStack.getValue();
+        assertEquals(value, integerLiteral.getValue(null), 0);
+    }
+
+    private void assertFloatingPointLiteral(double value, Command c) {
+        PushStackCommand pushStack = (PushStackCommand) c;
+        FloatingPointLiteral floatLiteral = (FloatingPointLiteral) pushStack.getValue();
+        assertEquals(value, floatLiteral.getValue(null), 0);
+    }
+
+    private void assertVariable(String variableName, Command c) {
+        PushStackCommand pushStack = (PushStackCommand) c;
+        Variable variable = (Variable) pushStack.getValue();
+        assertEquals(variableName, variable.getName());
+    }
+
+    private void assertFunctionCall(String functionName, int argumentNumber, Command c) {
+        FunctionCallCommand funcCall = (FunctionCallCommand) c;
+        assertEquals(functionName, funcCall.getName());
+        assertEquals(argumentNumber, funcCall.getArgumentNumber());
+    }
+
+}
diff --git a/expression-computer/src/test/java/jp/sourceforge/expression_computer/test/ComputerTest.java b/expression-computer/src/test/java/jp/sourceforge/expression_computer/test/ComputerTest.java
new file mode 100644 (file)
index 0000000..0ead5a4
--- /dev/null
@@ -0,0 +1,1808 @@
+
+package jp.sourceforge.expression_computer.test;
+
+import jp.sourceforge.expression_computer.CommandList;
+import jp.sourceforge.expression_computer.ComputeException;
+import jp.sourceforge.expression_computer.Computer;
+import jp.sourceforge.expression_computer.Function;
+import jp.sourceforge.expression_computer.ParseException;
+import junit.framework.TestCase;
+
+public class ComputerTest extends TestCase {
+
+    public ComputerTest(String name) {
+        super(name);
+    }
+
+    public void testFail_null1() {
+        String exp = null;
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (NullPointerException e) {
+            assertEquals("expressionがnullです。", e.getMessage());
+        }
+    }
+
+    public void testFail_null2() {
+        CommandList cl = null;
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(cl);
+            fail();
+        } catch (NullPointerException e) {
+            assertEquals("commandListがnullです。", e.getMessage());
+        }
+    }
+
+    public void testFail_EmptyStatement() {
+        String exp = "";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_IntegerLiteral1() {
+        String exp = "1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_IntegerLiteral2() {
+        String exp = "123456789";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(123456789, v, 0);
+    }
+
+    public void testNormal_IntegerLiteral3() {
+        String exp = "0xfFff";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(65535, v, 0);
+    }
+
+    public void testNormal_IntegerLiteral4() {
+        String exp = "07777";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(4095, v, 0);
+    }
+
+    public void testNormal_IntegerLiteral5() {
+        String exp = "0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testFail_IntegerLiteral1() {
+        String exp = "123456789123456789123456789";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    public void testFail_IntegerLiteral2() {
+        String exp = "123,456,789";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_FloatingPointLiteral1() {
+        String exp = "123.456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(123.456, v, 0);
+    }
+
+    public void testNormal_FloatingPointLiteral2() {
+        String exp = "0.123456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0.123456, v, 0);
+    }
+
+    public void testNormal_FloatingPointLiteral3() {
+        String exp = ".123456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0.123456, v, 0);
+    }
+
+    public void testNormal_FloatingPointLiteral4() {
+        String exp = "0.0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_FloatingPointLiteral5() {
+        String exp = ".0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testFail_FloatingPointLiteral1() {
+        String exp = "123.456.789";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_FunctionExpression1() {
+        String exp = "foo()";
+
+        Function func = new Function() {
+
+            public double call(double[] arguments) {
+                return 1;
+            }
+
+        };
+
+        Computer comp = new Computer();
+        comp.addFunction("foo", func);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_FunctionExpression2() {
+        String exp = "foo(1, 2)";
+
+        Function func = new Function() {
+
+            public double call(double[] arguments) {
+                return arguments[0] + arguments[1];
+            }
+
+        };
+
+        Computer comp = new Computer();
+        comp.addFunction("foo", func);
+        double v = comp.compute(exp);
+
+        assertEquals(3, v, 0);
+    }
+
+    public void testNormal_FunctionExpression3() {
+        String exp = "foo(1 + 2)";
+
+        Function func = new Function() {
+
+            public double call(double[] arguments) {
+                return arguments[0] * 10;
+            }
+
+        };
+
+        Computer comp = new Computer();
+        comp.addFunction("foo", func);
+        double v = comp.compute(exp);
+
+        assertEquals(30, v, 0);
+    }
+
+    public void testNormal_FunctionExpression4() {
+        String exp = "foo() + bar()";
+
+        Function fooFunc = new Function() {
+
+            public double call(double[] arguments) {
+                return 1;
+            }
+
+        };
+        Function barFunc = new Function() {
+
+            public double call(double[] arguments) {
+                return 2;
+            }
+
+        };
+
+        Computer comp = new Computer();
+        comp.addFunction("foo", fooFunc);
+        comp.addFunction("bar", barFunc);
+        double v = comp.compute(exp);
+
+        assertEquals(3, v, 0);
+    }
+
+    public void testFail_FunctionExpression1() {
+        String exp = "foo()";
+
+        Function func = new Function() {
+
+            public double call(double[] arguments) {
+                return 1;
+            }
+
+        };
+
+        Computer comp = new Computer();
+        comp.addFunction("bar", func);
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ComputeException e) {
+            assertEquals("関数{foo}は定義されていません。", e.getMessage());
+        }
+    }
+
+    public void testFail_FunctionExpression3() {
+        String exp = "foo(10, )";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_FunctionExpression4() {
+        String exp = "foo(";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_FunctionExpression5() {
+        String exp = "foo)";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_FunctionExpression6() {
+        String exp = "foo(10 10)";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_Variable1() {
+        String exp = "x";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_Variable2() {
+        String exp = "abc123_";
+
+        Computer comp = new Computer();
+        comp.setVariable("abc123_", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_Variable3() {
+        String exp = "_abc";
+
+        Computer comp = new Computer();
+        comp.setVariable("_abc", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_Variable4() {
+        String exp = "ほげ";
+
+        Computer comp = new Computer();
+        comp.setVariable("ほげ", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testFail_Variable1() {
+        String exp = "123abc";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ParenthesesExpression1() {
+        String exp = "(1 + 2)";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(3, v, 0);
+    }
+
+    public void testNormal_ParenthesesExpression2() {
+        String exp = "(1 + (2 - 3))";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testFail_ParenthesesExpression1() {
+        String exp = "()";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ParenthesesExpression2() {
+        String exp = "(1 + 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ParenthesesExpression3() {
+        String exp = "1 + 2)";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_PreIncrementExpression1() {
+        String exp = "++x";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(2, v, 0);
+        assertEquals(2, comp.getVariable("x"), 0);
+    }
+
+    public void testFail_PreIncrementExpression1() {
+        String exp = "++1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PreIncrementExpression2() {
+        String exp = "++++x";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PreIncrementExpression3() {
+        String exp = "++(++x)";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_PostIncrementExpression1() {
+        String exp = "x++";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+        assertEquals(2, comp.getVariable("x"), 0);
+    }
+
+    public void testFail_PostIncrementExpression1() {
+        String exp = "1++";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PostIncrementExpression2() {
+        String exp = "x++++";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PostIncrementExpression3() {
+        String exp = "(x++)++";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_PreDecrementExpression1() {
+        String exp = "--x";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+        assertEquals(0, comp.getVariable("x"), 0);
+    }
+
+    public void testFail_PreDecrementExpression1() {
+        String exp = "--1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PreDecrementExpression2() {
+        String exp = "----x";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PreDecrementExpression3() {
+        String exp = "--(--x)";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_PostDecrementExpression1() {
+        String exp = "x--";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+        assertEquals(0, comp.getVariable("x"), 0);
+    }
+
+    public void testFail_PostDecrementExpression1() {
+        String exp = "1--";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PostDecrementExpression2() {
+        String exp = "x----";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PostDecrementExpression3() {
+        String exp = "(x--)--";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus1() {
+        String exp = "~1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(-2, v, 0);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus2() {
+        String exp = "~x";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 10);
+        double v = comp.compute(exp);
+
+        assertEquals(-11, v, 0);
+        assertEquals(10, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus3() {
+        String exp = "~(~1)";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus4() {
+        String exp = "!0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus5() {
+        String exp = "!1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus6() {
+        String exp = "!0.1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus7() {
+        String exp = "!(!9)";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testFail_UnaryExpressionNotPlusMinus1() {
+        String exp = "~~1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_UnaryExpressionNotPlusMinus2() {
+        String exp = "!!1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_UnaryExpression1() {
+        String exp = "+0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_UnaryExpression2() {
+        String exp = "+999";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(999, v, 0);
+    }
+
+    public void testNormal_UnaryExpression3() {
+        String exp = "+(+999)";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(999, v, 0);
+    }
+
+    public void testNormal_UnaryExpression4() {
+        String exp = "+(+x)";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 999);
+        double v = comp.compute(exp);
+
+        assertEquals(999, v, 0);
+    }
+
+    public void testNormal_UnaryExpression5() {
+        String exp = "-0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_UnaryExpression6() {
+        String exp = "-999";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(-999, v, 0);
+    }
+
+    public void testNormal_UnaryExpression7() {
+        String exp = "-(-999)";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(999, v, 0);
+    }
+
+    public void testNormal_UnaryExpression8() {
+        String exp = "-(-x)";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 999);
+        double v = comp.compute(exp);
+
+        assertEquals(999, v, 0);
+    }
+
+    public void testFail_UnaryExpression1() {
+        String exp = "+++1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_UnaryExpression2() {
+        String exp = "---1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_MultiplicativeExpression1() {
+        String exp = "2 * 3";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(6, v, 0);
+    }
+
+    public void testNormal_MultiplicativeExpression2() {
+        String exp = "4 / 2";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(2, v, 0);
+    }
+
+    public void testNormal_MultiplicativeExpression3() {
+        String exp = "10 % 3";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_MultiplicativeExpression4() {
+        String exp = "2 * 6 / 3 % 3";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_MultiplicativeExpression5() {
+        String exp = "1 / 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertTrue(Double.isInfinite(v));
+    }
+
+    public void testNormal_MultiplicativeExpression6() {
+        String exp = "0 / 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertTrue(Double.isNaN(v));
+    }
+
+    public void testFail_MultiplicativeExpression1() {
+        String exp = "2 * * 3";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_MultiplicativeExpression2() {
+        String exp = "2 / / 3";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_MultiplicativeExpression3() {
+        String exp = "2 % % 3";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_MultiplicativeExpression4() {
+        String exp = "2 *";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_AdditiveExpression1() {
+        String exp = "1 + 2";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(3, v, 0);
+    }
+
+    public void testNormal_AdditiveExpression2() {
+        String exp = "1 - 2";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(-1, v, 0);
+    }
+
+    public void testNormal_AdditiveExpression3() {
+        String exp = "1 - 2 + 3";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(2, v, 0);
+    }
+
+    public void testFail_AdditiveExpression1() {
+        String exp = "1 + + + 1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_AdditiveExpression2() {
+        String exp = "1 - - - 1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_AdditiveExpression3() {
+        String exp = "1 +";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ShiftExpression1() {
+        String exp = "0 << 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ShiftExpression2() {
+        String exp = "123 << 3";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(984, v, 0);
+    }
+
+    public void testNormal_ShiftExpression3() {
+        String exp = "0 >> 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ShiftExpression4() {
+        String exp = "123 >> 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(61, v, 0);
+    }
+
+    public void testNormal_ShiftExpression5() {
+        String exp = "-123 >> 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(-62, v, 0);
+    }
+
+    public void testNormal_ShiftExpression6() {
+        String exp = "0 >>> 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ShiftExpression7() {
+        String exp = "123 >>> 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(61, v, 0);
+    }
+
+    public void testNormal_ShiftExpression8() {
+        String exp = "-123 >>> 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(9.223372036854776E18, v, 0);
+    }
+
+    public void testNormal_ShiftExpression9() {
+        String exp = "123.456 << 3.456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(984, v, 0);
+    }
+
+    public void testNormal_ShiftExpression10() {
+        String exp = "1 << 2 << 3";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(32, v, 0);
+    }
+
+    public void testFail_ShiftExpression1() {
+        String exp = "1 << << 1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ShiftExpression2() {
+        String exp = "1 >> >> 1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ShiftExpression3() {
+        String exp = "1 >>> >>> 1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ShiftExpression4() {
+        String exp = "1 <<<< 1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_RelationalExpression1() {
+        String exp = "123 > 122";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_RelationalExpression2() {
+        String exp = "123.1 > 123.2";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_RelationalExpression3() {
+        String exp = "123.1 > 123.1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_RelationalExpression4() {
+        String exp = "122 < 123";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_RelationalExpression5() {
+        String exp = "123.2 < 123.1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_RelationalExpression6() {
+        String exp = "123.2 < 123.2";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_RelationalExpression7() {
+        String exp = "123 >= 122";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_RelationalExpression8() {
+        String exp = "123.1 >= 123.2";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_RelationalExpression9() {
+        String exp = "123.1 >= 123.1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_RelationalExpression10() {
+        String exp = "122 <= 123";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_RelationalExpression11() {
+        String exp = "123.2 <= 123.1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_RelationalExpression12() {
+        String exp = "123.1 <= 123.1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_RelationalExpression13() {
+        String exp = "0 > 0 > 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testFail_RelationalExpression1() {
+        String exp = "1 > > 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_RelationalExpression2() {
+        String exp = "1 < < 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_RelationalExpression3() {
+        String exp = "1 >= >= 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_RelationalExpression4() {
+        String exp = "1 <= <= 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_EqualityExpression1() {
+        String exp = "123.456 == 123.456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_EqualityExpression2() {
+        String exp = "123.456 == 123.4567";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_EqualityExpression3() {
+        String exp = "123.456 != 123.456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_EqualityExpression4() {
+        String exp = "123.456 != 123.4567";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_EqualityExpression5() {
+        String exp = "NaN == NaN";
+
+        Computer comp = new Computer();
+        comp.setVariable("NaN", Double.NaN);
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_EqualityExpression6() {
+        String exp = "NaN != NaN";
+
+        Computer comp = new Computer();
+        comp.setVariable("NaN", Double.NaN);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_EqualityExpression7() {
+        String exp = "0 == 0 == 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testFail_EqualityExpression1() {
+        String exp = "1 == == 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_EqualityExpression2() {
+        String exp = "1 != != 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_AndExpression1() {
+        String exp = "123 & 456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(72, v, 0);
+    }
+
+    public void testNormal_AndExpression2() {
+        String exp = "123.456 & 456.789";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(72, v, 0);
+    }
+
+    public void testNormal_AndExpression3() {
+        String exp = "123 & 456 & 789";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testFail_AndExpression1() {
+        String exp = "123 & & 456";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ExclusiveOrExpression1() {
+        String exp = "123 ^ 456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(435, v, 0);
+    }
+
+    public void testNormal_ExclusiveOrExpression2() {
+        String exp = "123.456 ^ 456.789";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(435, v, 0);
+    }
+
+    public void testNormal_ExclusiveOrExpression3() {
+        String exp = "123 ^ 456 ^ 789";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(678, v, 0);
+    }
+
+    public void testFail_ExclusiveOrExpression1() {
+        String exp = "123 ^ ^ 456";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_InclusiveOrExpression1() {
+        String exp = "123 | 456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(507, v, 0);
+    }
+
+    public void testNormal_InclusiveOrExpression2() {
+        String exp = "123.456 | 456.789";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(507, v, 0);
+    }
+
+    public void testNormal_InclusiveOrExpression3() {
+        String exp = "123 | 456 | 789";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1023, v, 0);
+    }
+
+    public void testFail_InclusiveOrExpression1() {
+        String exp = "123 | | 456";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ConditionalAndExpression1() {
+        String exp = "0 && 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ConditionalAndExpression2() {
+        String exp = "0 && 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ConditionalAndExpression3() {
+        String exp = "0 && 123.456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ConditionalAndExpression4() {
+        String exp = "1 && 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ConditionalAndExpression5() {
+        String exp = "123.456 && 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ConditionalAndExpression6() {
+        String exp = "1 && 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_ConditionalAndExpression7() {
+        String exp = "123.456 && 123.456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testFail_ConditionalAndExpression1() {
+        String exp = "0 && && 0";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ConditionalOrExpression1() {
+        String exp = "0 || 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(0, v, 0);
+    }
+
+    public void testNormal_ConditionalOrExpression2() {
+        String exp = "0 || 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_ConditionalOrExpression3() {
+        String exp = "0 || 123.456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_ConditionalOrExpression4() {
+        String exp = "1 || 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_ConditionalOrExpression5() {
+        String exp = "123.456 || 0";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_ConditionalOrExpression6() {
+        String exp = "1 || 1";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testNormal_ConditionalOrExpression7() {
+        String exp = "123.456 || 123.456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+    }
+
+    public void testFail_ConditionalOrExpression1() {
+        String exp = "0 || || 0";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ConditionalExpression1() {
+        String exp = "0 ? 123 : 456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(456, v, 0);
+    }
+
+    public void testNormal_ConditionalExpression2() {
+        String exp = "1 ? 123 : 456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(123, v, 0);
+    }
+
+    public void testNormal_ConditionalExpression3() {
+        String exp = "789 ? 123 : 456";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(123, v, 0);
+    }
+
+    public void testNormal_ConditionalExpression4() {
+        String exp = "0 ? 1 : 2 ? 3 : 4";
+
+        Computer comp = new Computer();
+        double v = comp.compute(exp);
+
+        assertEquals(3, v, 0);
+    }
+
+    public void testFail_ConditionalExpression2() {
+        String exp = "0 ? 1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ConditionalExpression3() {
+        String exp = "1 : 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ConditionalExpression4() {
+        String exp = "0 ? 1 ? 2";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_AssignmentExpression1() {
+        String exp = "x = 123";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 1);
+        double v = comp.compute(exp);
+
+        assertEquals(123, v, 0);
+        assertEquals(123, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression2() {
+        String exp = "x += 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(124, v, 0);
+        assertEquals(124, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression3() {
+        String exp = "x -= 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(122, v, 0);
+        assertEquals(122, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression4() {
+        String exp = "x *= 2";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(246, v, 0);
+        assertEquals(246, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression5() {
+        String exp = "x /= 3";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(41, v, 0);
+        assertEquals(41, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression6() {
+        String exp = "x %= 4";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(3, v, 0);
+        assertEquals(3, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression7() {
+        String exp = "x &= 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+        assertEquals(1, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression8() {
+        String exp = "x ^= 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(122, v, 0);
+        assertEquals(122, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression9() {
+        String exp = "x |= 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(123, v, 0);
+        assertEquals(123, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression10() {
+        String exp = "x <<= 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(246, v, 0);
+        assertEquals(246, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression11() {
+        String exp = "x >>= 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(61, v, 0);
+        assertEquals(61, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression12() {
+        String exp = "x >>>= 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        double v = comp.compute(exp);
+
+        assertEquals(61, v, 0);
+        assertEquals(61, comp.getVariable("x"), 0);
+    }
+
+    public void testNormal_AssignmentExpression13() {
+        String exp = "x = y = 1";
+
+        Computer comp = new Computer();
+        comp.setVariable("x", 123);
+        comp.setVariable("y", 456);
+        double v = comp.compute(exp);
+
+        assertEquals(1, v, 0);
+        assertEquals(1, comp.getVariable("x"), 0);
+        assertEquals(1, comp.getVariable("y"), 0);
+    }
+
+    public void testFail_AssignmentExpression1() {
+        String exp = "x = = 1";
+
+        Computer comp = new Computer();
+        try {
+            comp.compute(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+}
diff --git a/expression-computer/src/test/java/jp/sourceforge/expression_computer/test/RpnParserTest.jav_ b/expression-computer/src/test/java/jp/sourceforge/expression_computer/test/RpnParserTest.jav_
new file mode 100644 (file)
index 0000000..08e39ee
--- /dev/null
@@ -0,0 +1,1526 @@
+
+package jp.sourceforge.rpn_computer.test;
+
+import jp.sourceforge.rpn_computer.ParseException;
+import jp.sourceforge.rpn_computer.RpnNode;
+import jp.sourceforge.rpn_computer.RpnParser;
+import jp.sourceforge.rpn_computer.node.ExpressionStatementNode;
+import jp.sourceforge.rpn_computer.node.FloatingPointLiteralNode;
+import jp.sourceforge.rpn_computer.node.FunctionExpressionNode;
+import jp.sourceforge.rpn_computer.node.IntegerLiteralNode;
+import junit.framework.TestCase;
+
+public class RpnParserTest extends TestCase {
+
+    public RpnParserTest(String name) {
+        super(name);
+    }
+
+    public void testFail_null1() {
+        String exp = null;
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (NullPointerException e) {
+            assertEquals("expressionがnullです。", e.getMessage());
+        }
+    }
+
+    public void testFail_EmptyStatement() {
+        String exp = "";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_IntegerLiteral1() {
+        String exp = "1";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode integerLiteral = expression.getChildren()[0];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("1", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+    }
+
+    public void testNormal_IntegerLiteral2() {
+        String exp = "123456789";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode integerLiteral = expression.getChildren()[0];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("123456789", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+    }
+
+    public void testNormal_IntegerLiteral3() {
+        String exp = "0xfFff";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode integerLiteral = expression.getChildren()[0];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("0xfFff", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+    }
+
+    public void testNormal_IntegerLiteral4() {
+        String exp = "07777";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode integerLiteral = expression.getChildren()[0];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("07777", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+    }
+
+    public void testNormal_IntegerLiteral5() {
+        String exp = "0";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode integerLiteral = expression.getChildren()[0];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("0", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+    }
+
+    public void testFail_IntegerLiteral1() {
+        String exp = "123456789123456789123456789";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_IntegerLiteral2() {
+        String exp = "123,456,789";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_FloatingPointLiteral1() {
+        String exp = "123.456";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode floatingPointLiteral = expression.getChildren()[0];
+        assertTrue(floatingPointLiteral instanceof FloatingPointLiteralNode);
+        assertEquals("123.456", ((FloatingPointLiteralNode) floatingPointLiteral).getValue());
+        assertEquals(0, floatingPointLiteral.getChildren().length);
+    }
+
+    public void testNormal_FloatingPointLiteral2() {
+        String exp = "0.123456";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode floatingPointLiteral = expression.getChildren()[0];
+        assertTrue(floatingPointLiteral instanceof FloatingPointLiteralNode);
+        assertEquals("0.123456", ((FloatingPointLiteralNode) floatingPointLiteral).getValue());
+        assertEquals(0, floatingPointLiteral.getChildren().length);
+    }
+
+    public void testNormal_FloatingPointLiteral3() {
+        String exp = ".123456";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode floatingPointLiteral = expression.getChildren()[0];
+        assertTrue(floatingPointLiteral instanceof FloatingPointLiteralNode);
+        assertEquals(".123456", ((FloatingPointLiteralNode) floatingPointLiteral).getValue());
+        assertEquals(0, floatingPointLiteral.getChildren().length);
+    }
+
+    public void testNormal_FloatingPointLiteral4() {
+        String exp = "0.0";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode floatingPointLiteral = expression.getChildren()[0];
+        assertTrue(floatingPointLiteral instanceof FloatingPointLiteralNode);
+        assertEquals("0.0", ((FloatingPointLiteralNode) floatingPointLiteral).getValue());
+        assertEquals(0, floatingPointLiteral.getChildren().length);
+    }
+
+    public void testNormal_FloatingPointLiteral5() {
+        String exp = ".0";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode floatingPointLiteral = expression.getChildren()[0];
+        assertTrue(floatingPointLiteral instanceof FloatingPointLiteralNode);
+        assertEquals(".0", ((FloatingPointLiteralNode) floatingPointLiteral).getValue());
+        assertEquals(0, floatingPointLiteral.getChildren().length);
+    }
+
+    public void testFail_FloatingPointLiteral1() {
+        String exp = "123.456.789";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_FunctionExpression1() {
+        String exp = "foo()";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode function = expression.getChildren()[0];
+        assertTrue(function instanceof FunctionExpressionNode);
+        assertEquals(3, function.getChildren().length);
+
+        RpnNode functionName = function.getChildren()[0];
+        assertTrue(functionName instanceof FunctionExpressionNode.FunctionNameNode);
+        assertEquals("foo", ((FunctionExpressionNode.FunctionNameNode) functionName).getName());
+        assertEquals(0, functionName.getChildren().length);
+
+        RpnNode leftBracket = function.getChildren()[1];
+        assertTrue(leftBracket instanceof FunctionExpressionNode.LeftBracketNode);
+        assertEquals(0, leftBracket.getChildren().length);
+
+        RpnNode rightBracket = function.getChildren()[2];
+        assertTrue(rightBracket instanceof FunctionExpressionNode.RightBracketNode);
+        assertEquals(0, rightBracket.getChildren().length);
+    }
+
+    public void testNormal_FunctionExpression2() {
+        String exp = "foo(1, 2)";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode function = expression.getChildren()[0];
+        assertTrue(function instanceof FunctionExpressionNode);
+        assertEquals(6, function.getChildren().length);
+
+        RpnNode functionName = function.getChildren()[0];
+        assertTrue(functionName instanceof FunctionExpressionNode.FunctionNameNode);
+        assertEquals("foo", ((FunctionExpressionNode.FunctionNameNode) functionName).getName());
+        assertEquals(0, functionName.getChildren().length);
+
+        RpnNode leftBracket = function.getChildren()[1];
+        assertTrue(leftBracket instanceof FunctionExpressionNode.LeftBracketNode);
+        assertEquals(0, leftBracket.getChildren().length);
+
+        RpnNode integerLiteral = function.getChildren()[2];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("1", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+
+        RpnNode comma = function.getChildren()[3];
+        assertTrue(comma instanceof FunctionExpressionNode.CommaNode);
+        assertEquals(0, comma.getChildren().length);
+
+        integerLiteral = function.getChildren()[4];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("2", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+
+        RpnNode rightBracket = function.getChildren()[5];
+        assertTrue(rightBracket instanceof FunctionExpressionNode.RightBracketNode);
+        assertEquals(0, rightBracket.getChildren().length);
+    }
+
+    public void testNormal_FunctionExpression3() {
+        String exp = "foo(1 + 2)";
+
+        RpnParser parser = new RpnParser();
+        RpnNode expression = parser.parse(exp);
+
+        assertTrue(expression instanceof ExpressionStatementNode);
+        assertEquals(1, expression.getChildren().length);
+
+        RpnNode function = expression.getChildren()[0];
+        assertTrue(function instanceof FunctionExpressionNode);
+        assertEquals(6, function.getChildren().length);
+
+        RpnNode functionName = function.getChildren()[0];
+        assertTrue(functionName instanceof FunctionExpressionNode.FunctionNameNode);
+        assertEquals("foo", ((FunctionExpressionNode.FunctionNameNode) functionName).getName());
+        assertEquals(0, functionName.getChildren().length);
+
+        RpnNode leftBracket = function.getChildren()[1];
+        assertTrue(leftBracket instanceof FunctionExpressionNode.LeftBracketNode);
+        assertEquals(0, leftBracket.getChildren().length);
+
+        RpnNode integerLiteral = function.getChildren()[2];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("1", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+
+        RpnNode comma = function.getChildren()[3];
+        assertTrue(comma instanceof FunctionExpressionNode.CommaNode);
+        assertEquals(0, comma.getChildren().length);
+
+        integerLiteral = function.getChildren()[4];
+        assertTrue(integerLiteral instanceof IntegerLiteralNode);
+        assertEquals("2", ((IntegerLiteralNode) integerLiteral).getValue());
+        assertEquals(0, integerLiteral.getChildren().length);
+
+        RpnNode rightBracket = function.getChildren()[5];
+        assertTrue(rightBracket instanceof FunctionExpressionNode.RightBracketNode);
+        assertEquals(0, rightBracket.getChildren().length);
+    }
+
+    public void testNormal_FunctionExpression4() {
+        String exp = "foo() + bar()";
+
+        fail();
+    }
+
+    public void testFail_FunctionExpression1() {
+        String exp = "foo()";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_FunctionExpression3() {
+        String exp = "foo(10, )";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_FunctionExpression4() {
+        String exp = "foo(";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_FunctionExpression5() {
+        String exp = "foo)";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_FunctionExpression6() {
+        String exp = "foo(10 10)";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_Variable1() {
+        String exp = "x";
+
+        fail();
+    }
+
+    public void testNormal_Variable2() {
+        String exp = "abc123_";
+
+        fail();
+    }
+
+    public void testNormal_Variable3() {
+        String exp = "_abc";
+
+        fail();
+    }
+
+    public void testNormal_Variable4() {
+        String exp = "ほげ";
+
+        fail();
+    }
+
+    public void testFail_Variable1() {
+        String exp = "123abc";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ParenthesesExpression1() {
+        String exp = "(1 + 2)";
+
+        fail();
+    }
+
+    public void testNormal_ParenthesesExpression2() {
+        String exp = "(1 + (2 - 3))";
+
+        fail();
+    }
+
+    public void testFail_ParenthesesExpression1() {
+        String exp = "()";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ParenthesesExpression2() {
+        String exp = "(1 + 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ParenthesesExpression3() {
+        String exp = "1 + 2)";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_PreIncrementExpression1() {
+        String exp = "++x";
+
+        fail();
+    }
+
+    public void testFail_PreIncrementExpression1() {
+        String exp = "++1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PreIncrementExpression2() {
+        String exp = "++++x";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PreIncrementExpression3() {
+        String exp = "++(++x)";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_PostIncrementExpression1() {
+        String exp = "x++";
+
+        fail();
+    }
+
+    public void testFail_PostIncrementExpression1() {
+        String exp = "1++";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PostIncrementExpression2() {
+        String exp = "x++++";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PostIncrementExpression3() {
+        String exp = "(x++)++";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_PreDecrementExpression1() {
+        String exp = "--x";
+
+        fail();
+    }
+
+    public void testFail_PreDecrementExpression1() {
+        String exp = "--1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PreDecrementExpression2() {
+        String exp = "----x";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PreDecrementExpression3() {
+        String exp = "--(--x)";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_PostDecrementExpression1() {
+        String exp = "x--";
+
+        fail();
+    }
+
+    public void testFail_PostDecrementExpression1() {
+        String exp = "1--";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PostDecrementExpression2() {
+        String exp = "x----";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_PostDecrementExpression3() {
+        String exp = "(x--)--";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus1() {
+        String exp = "~1";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus2() {
+        String exp = "~x";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus3() {
+        String exp = "~(~1)";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus4() {
+        String exp = "!0";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus5() {
+        String exp = "!1";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus6() {
+        String exp = "!0.1";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus7() {
+        String exp = "!(!9)";
+
+        fail();
+    }
+
+    public void testFail_UnaryExpressionNotPlusMinus1() {
+        String exp = "~~1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_UnaryExpressionNotPlusMinus2() {
+        String exp = "!!1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_UnaryExpression1() {
+        String exp = "+0";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpression2() {
+        String exp = "+999";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpression3() {
+        String exp = "+(+999)";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpression4() {
+        String exp = "+(+x)";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpression5() {
+        String exp = "-0";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpression6() {
+        String exp = "-999";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpression7() {
+        String exp = "-(-999)";
+
+        fail();
+    }
+
+    public void testNormal_UnaryExpression8() {
+        String exp = "-(-x)";
+
+        fail();
+    }
+
+    public void testFail_UnaryExpression1() {
+        String exp = "+++1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_UnaryExpression2() {
+        String exp = "---1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_MultiplicativeExpression1() {
+        String exp = "2 * 3";
+
+        fail();
+    }
+
+    public void testNormal_MultiplicativeExpression2() {
+        String exp = "4 / 2";
+
+        fail();
+    }
+
+    public void testNormal_MultiplicativeExpression3() {
+        String exp = "10 % 3";
+
+        fail();
+    }
+
+    public void testNormal_MultiplicativeExpression4() {
+        String exp = "2 * 6 / 3 % 3";
+
+        fail();
+    }
+
+    public void testNormal_MultiplicativeExpression5() {
+        String exp = "1 / 0";
+
+        fail();
+    }
+
+    public void testNormal_MultiplicativeExpression6() {
+        String exp = "0 / 0";
+
+        fail();
+    }
+
+    public void testFail_MultiplicativeExpression1() {
+        String exp = "2 * * 3";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_MultiplicativeExpression2() {
+        String exp = "2 / / 3";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_MultiplicativeExpression3() {
+        String exp = "2 % % 3";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_MultiplicativeExpression4() {
+        String exp = "2 *";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_AdditiveExpression1() {
+        String exp = "1 + 2";
+
+        fail();
+    }
+
+    public void testNormal_AdditiveExpression2() {
+        String exp = "1 - 2";
+
+        fail();
+    }
+
+    public void testNormal_AdditiveExpression3() {
+        String exp = "1 - 2 + 3";
+
+        fail();
+    }
+
+    public void testFail_AdditiveExpression1() {
+        String exp = "1 + + + 1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_AdditiveExpression2() {
+        String exp = "1 - - - 1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_AdditiveExpression3() {
+        String exp = "1 +";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ShiftExpression1() {
+        String exp = "0 << 1";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression2() {
+        String exp = "123 << 3";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression3() {
+        String exp = "0 >> 1";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression4() {
+        String exp = "123 >> 1";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression5() {
+        String exp = "-123 >> 1";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression6() {
+        String exp = "0 >>> 1";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression7() {
+        String exp = "123 >>> 1";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression8() {
+        String exp = "-123 >>> 1";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression9() {
+        String exp = "123.456 << 3.456";
+
+        fail();
+    }
+
+    public void testNormal_ShiftExpression10() {
+        String exp = "1 << 2 << 3";
+
+        fail();
+    }
+
+    public void testFail_ShiftExpression1() {
+        String exp = "1 << << 1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ShiftExpression2() {
+        String exp = "1 >> >> 1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ShiftExpression3() {
+        String exp = "1 >>> >>> 1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ShiftExpression4() {
+        String exp = "1 <<<< 1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_RelationalExpression1() {
+        String exp = "123 > 122";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression2() {
+        String exp = "123.1 > 123.2";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression3() {
+        String exp = "123.1 > 123.1";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression4() {
+        String exp = "122 < 123";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression5() {
+        String exp = "123.2 < 123.1";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression6() {
+        String exp = "123.2 < 123.2";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression7() {
+        String exp = "123 >= 122";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression8() {
+        String exp = "123.1 >= 123.2";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression9() {
+        String exp = "123.1 >= 123.1";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression10() {
+        String exp = "122 <= 123";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression11() {
+        String exp = "123.2 <= 123.1";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression12() {
+        String exp = "123.1 <= 123.1";
+
+        fail();
+    }
+
+    public void testNormal_RelationalExpression13() {
+        String exp = "0 > 0 > 0";
+
+        fail();
+    }
+
+    public void testFail_RelationalExpression1() {
+        String exp = "1 > > 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_RelationalExpression2() {
+        String exp = "1 < < 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_RelationalExpression3() {
+        String exp = "1 >= >= 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_RelationalExpression4() {
+        String exp = "1 <= <= 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_EqualityExpression1() {
+        String exp = "123.456 == 123.456";
+
+        fail();
+    }
+
+    public void testNormal_EqualityExpression2() {
+        String exp = "123.456 == 123.4567";
+
+        fail();
+    }
+
+    public void testNormal_EqualityExpression3() {
+        String exp = "123.456 != 123.456";
+
+        fail();
+    }
+
+    public void testNormal_EqualityExpression4() {
+        String exp = "123.456 != 123.4567";
+
+        fail();
+    }
+
+    public void testNormal_EqualityExpression5() {
+        String exp = "NaN == NaN";
+
+        fail();
+    }
+
+    public void testNormal_EqualityExpression6() {
+        String exp = "NaN != NaN";
+
+        fail();
+    }
+
+    public void testNormal_EqualityExpression7() {
+        String exp = "0 == 0 == 0";
+
+        fail();
+    }
+
+    public void testFail_EqualityExpression1() {
+        String exp = "1 == == 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_EqualityExpression2() {
+        String exp = "1 != != 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_AndExpression1() {
+        String exp = "123 & 456";
+
+        fail();
+    }
+
+    public void testNormal_AndExpression2() {
+        String exp = "123.456 & 456.789";
+
+        fail();
+    }
+
+    public void testNormal_AndExpression3() {
+        String exp = "123 & 456 & 789";
+
+        fail();
+    }
+
+    public void testFail_AndExpression1() {
+        String exp = "123 & & 456";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+
+    }
+
+    public void testNormal_ExclusiveOrExpression1() {
+        String exp = "123 ^ 456";
+
+        fail();
+    }
+
+    public void testNormal_ExclusiveOrExpression2() {
+        String exp = "123.456 ^ 456.789";
+
+        fail();
+    }
+
+    public void testNormal_ExclusiveOrExpression3() {
+        String exp = "123 ^ 456 ^ 789";
+
+        fail();
+    }
+
+    public void testFail_ExclusiveOrExpression1() {
+        String exp = "123 ^ ^ 456";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_InclusiveOrExpression1() {
+        String exp = "123 | 456";
+
+        fail();
+    }
+
+    public void testNormal_InclusiveOrExpression2() {
+        String exp = "123.456 | 456.789";
+
+        fail();
+    }
+
+    public void testNormal_InclusiveOrExpression3() {
+        String exp = "123 | 456 | 789";
+
+        fail();
+    }
+
+    public void testFail_InclusiveOrExpression1() {
+        String exp = "123 | | 456";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ConditionalAndExpression1() {
+        String exp = "0 && 0";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalAndExpression2() {
+        String exp = "0 && 1";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalAndExpression3() {
+        String exp = "0 && 123.456";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalAndExpression4() {
+        String exp = "1 && 0";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalAndExpression5() {
+        String exp = "123.456 && 0";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalAndExpression6() {
+        String exp = "1 && 1";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalAndExpression7() {
+        String exp = "123.456 && 123.456";
+
+        fail();
+    }
+
+    public void testFail_ConditionalAndExpression1() {
+        String exp = "0 && && 0";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ConditionalOrExpression1() {
+        String exp = "0 || 0";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalOrExpression2() {
+        String exp = "0 || 1";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalOrExpression3() {
+        String exp = "0 || 123.456";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalOrExpression4() {
+        String exp = "1 || 0";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalOrExpression5() {
+        String exp = "123.456 || 0";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalOrExpression6() {
+        String exp = "1 || 1";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalOrExpression7() {
+        String exp = "123.456 || 123.456";
+
+        fail();
+    }
+
+    public void testFail_ConditionalOrExpression1() {
+        String exp = "0 || || 0";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_ConditionalExpression1() {
+        String exp = "0 ? 123 : 456";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalExpression2() {
+        String exp = "1 ? 123 : 456";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalExpression3() {
+        String exp = "789 ? 123 : 456";
+
+        fail();
+    }
+
+    public void testNormal_ConditionalExpression4() {
+        String exp = "0 ? 1 : 2 ? 3 : 4";
+
+        fail();
+    }
+
+    public void testFail_ConditionalExpression2() {
+        String exp = "0 ? 1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ConditionalExpression3() {
+        String exp = "1 : 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testFail_ConditionalExpression4() {
+        String exp = "0 ? 1 ? 2";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+    public void testNormal_AssignmentExpression1() {
+        String exp = "x = 123";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression2() {
+        String exp = "x += 1";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression3() {
+        String exp = "x -= 1";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression4() {
+        String exp = "x *= 2";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression5() {
+        String exp = "x /= 3";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression6() {
+        String exp = "x %= 4";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression7() {
+        String exp = "x &= 1";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression8() {
+        String exp = "x ^= 1";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression9() {
+        String exp = "x |= 1";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression10() {
+        String exp = "x <<= 1";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression11() {
+        String exp = "x >>= 1";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression12() {
+        String exp = "x >>>= 1";
+
+        fail();
+    }
+
+    public void testNormal_AssignmentExpression13() {
+        String exp = "x = y = 1";
+
+        fail();
+    }
+
+    public void testFail_AssignmentExpression1() {
+        String exp = "x = = 1";
+
+        RpnParser parser = new RpnParser();
+        try {
+            parser.parse(exp);
+            fail();
+        } catch (ParseException e) {
+        }
+    }
+
+}
diff --git a/expression-computer/src/test/java/jp/sourceforge/expression_computer/test/SerializerTest.java b/expression-computer/src/test/java/jp/sourceforge/expression_computer/test/SerializerTest.java
new file mode 100644 (file)
index 0000000..78a23f5
--- /dev/null
@@ -0,0 +1,2061 @@
+
+package jp.sourceforge.expression_computer.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import jp.sourceforge.expression_computer.CommandList;
+import jp.sourceforge.expression_computer.Compiler;
+import jp.sourceforge.expression_computer.Node;
+import jp.sourceforge.expression_computer.Parser;
+import jp.sourceforge.expression_computer.Serializer;
+import junit.framework.TestCase;
+
+public class SerializerTest extends TestCase {
+
+    public SerializerTest(String name) {
+        super(name);
+    }
+
+    public void testFail_null() throws Exception {
+        Serializer serializer = new Serializer();
+        try {
+            serializer.serialize(null);
+            fail();
+        } catch (NullPointerException e) {
+            assertEquals("commandListがnullです。", e.getMessage());
+        }
+    }
+
+    public void testNormal_IntegerLiteral1() throws Exception {
+        String exp = "1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_IntegerLiteral2() throws Exception {
+        String exp = "123456789";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123456789);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_IntegerLiteral3() throws Exception {
+        String exp = "0xfFff";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(65535);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_IntegerLiteral4() throws Exception {
+        String exp = "07777";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(4095);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_IntegerLiteral5() throws Exception {
+        String exp = "0";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FloatingPointLiteral6() throws Exception {
+        String exp = "123.456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(123.456);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FloatingPointLiteral2() throws Exception {
+        String exp = "0.123456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(0.123456);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FloatingPointLiteral3() throws Exception {
+        String exp = ".123456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(0.123456);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FloatingPointLiteral4() throws Exception {
+        String exp = "0.0";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FloatingPointLiteral5() throws Exception {
+        String exp = ".0";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(0.0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FunctionExpression1() throws Exception {
+        String exp = "foo()";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(10);
+                objOut.writeUTF("foo");
+                objOut.writeInt(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FunctionExpression2() throws Exception {
+        String exp = "foo(1, 2)";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(10);
+                objOut.writeUTF("foo");
+                objOut.writeInt(2);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FunctionExpression3() throws Exception {
+        String exp = "foo(1 + 2)";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(0);
+                objOut.writeByte(10);
+                objOut.writeUTF("foo");
+                objOut.writeInt(1);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_FunctionExpression4() throws Exception {
+        String exp = "foo() + bar()";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(10);
+                objOut.writeUTF("foo");
+                objOut.writeInt(0);
+                objOut.writeByte(10);
+                objOut.writeUTF("bar");
+                objOut.writeInt(0);
+                objOut.writeByte(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_Variable1() throws Exception {
+        String exp = "x";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_Variable2() throws Exception {
+        String exp = "abc123_";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("abc123_");
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_Variable3() throws Exception {
+        String exp = "_abc";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("_abc");
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_Variable4() throws Exception {
+        String exp = "ほげ";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("ほげ");
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ParenthesesExpression1() throws Exception {
+        String exp = "(1 + 2)";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ParenthesesExpression2() throws Exception {
+        String exp = "(1 + (2 - 3))";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(3);
+                objOut.writeByte(28);
+                objOut.writeByte(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_PreIncrementExpression1() throws Exception {
+        String exp = "++x";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(24);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_PreDecrementExpression1() throws Exception {
+        String exp = "--x";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(23);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_PostIncrementExpression1() throws Exception {
+        String exp = "x++";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(22);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_PostDecrementExpression1() throws Exception {
+        String exp = "x--";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(21);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus1() throws Exception {
+        String exp = "~1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(3);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus2() throws Exception {
+        String exp = "~(~1)";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(3);
+                objOut.writeByte(3);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus3() throws Exception {
+        String exp = "!0";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(19);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_UnaryExpressionNotPlusMinus4() throws Exception {
+        String exp = "!(!9)";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(9);
+                objOut.writeByte(19);
+                objOut.writeByte(19);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_UnaryExpression1() throws Exception {
+        String exp = "+0";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNotmal_UnaryExpression2() throws Exception {
+        String exp = "+(+999)";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(999);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_UnaryExpression3() throws Exception {
+        String exp = "-0";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(27);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_UnaryExpression4() throws Exception {
+        String exp = "-(-999)";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(999);
+                objOut.writeByte(27);
+                objOut.writeByte(27);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_MultiplicativeExpression1() throws Exception {
+        String exp = "2 * 3";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(3);
+                objOut.writeByte(18);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_MultiplicativeExpression2() throws Exception {
+        String exp = "4 / 2";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(4);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(7);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_MultiplicativeExpression3() throws Exception {
+        String exp = "10 % 3";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(10);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(3);
+                objOut.writeByte(29);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_MultiplicativeExpression4() throws Exception {
+        String exp = "2 * 6 / 3 % 3";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(6);
+                objOut.writeByte(18);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(3);
+                objOut.writeByte(7);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(3);
+                objOut.writeByte(29);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AdditiveExpression1() throws Exception {
+        String exp = "1 + 2";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AdditiveExpression2() throws Exception {
+        String exp = "1 - 2";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(28);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AdditiveExpression3() throws Exception {
+        String exp = "1 - 2 + 3";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(28);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(3);
+                objOut.writeByte(0);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ShiftExpression1() throws Exception {
+        String exp = "0 << 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(14);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ShiftExpression2() throws Exception {
+        String exp = "0 >> 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(2);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ShiftExpression3() throws Exception {
+        String exp = "0 >>> 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(17);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ShiftExpression4() throws Exception {
+        String exp = "1 << 2 << 3";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(14);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(3);
+                objOut.writeByte(14);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_RelationalExpression1() throws Exception {
+        String exp = "123 > 122";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(122);
+                objOut.writeByte(11);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_RelationalExpression2() throws Exception {
+        String exp = "122 < 123";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(122);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(15);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_RelationalExpression3() throws Exception {
+        String exp = "123 >= 122";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(122);
+                objOut.writeByte(12);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_RelationalExpression4() throws Exception {
+        String exp = "122 <= 123";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(122);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(16);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_RelationalExpression5() throws Exception {
+        String exp = "0 > 0 > 0";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(11);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(11);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_EqualityExpression1() throws Exception {
+        String exp = "123.456 == 123.456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(123.456);
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(123.456);
+                objOut.writeByte(8);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_EqualityExpression2() throws Exception {
+        String exp = "123.456 != 123.456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(123.456);
+                objOut.writeByte(25);
+                objOut.writeByte(0);
+                objOut.writeDouble(123.456);
+                objOut.writeByte(20);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_EqualityExpression3() throws Exception {
+        String exp = "0 == 0 == 0";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(8);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(8);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AndExpression1() throws Exception {
+        String exp = "123 & 456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(456);
+                objOut.writeByte(1);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AndExpression2() throws Exception {
+        String exp = "123 & 456 & 789";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(456);
+                objOut.writeByte(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(789);
+                objOut.writeByte(1);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ExclusiveOrExpression1() throws Exception {
+        String exp = "123 ^ 456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(456);
+                objOut.writeByte(9);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ExclusiveOrExpression2() throws Exception {
+        String exp = "123 ^ 456 ^ 789";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(456);
+                objOut.writeByte(9);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(789);
+                objOut.writeByte(9);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_InclusiveOrExpression1() throws Exception {
+        String exp = "123 | 456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(456);
+                objOut.writeByte(13);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_InclusiveOrExpression2() throws Exception {
+        String exp = "123 | 456 | 789";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(456);
+                objOut.writeByte(13);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(789);
+                objOut.writeByte(13);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ConditionalAndExpression1() throws Exception {
+        String exp = "0 && 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(4);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ConditionalOrExpression1() throws Exception {
+        String exp = "0 || 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(5);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ConditionalExpression1() throws Exception {
+        String exp = "0 ? 123 : 456";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(456);
+                objOut.writeByte(6);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_ConditionalExpression2() throws Exception {
+        String exp = "0 ? 1 : 2 ? 3 : 4";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(0);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(2);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(3);
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(4);
+                objOut.writeByte(6);
+                objOut.writeByte(6);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression1() throws Exception {
+        String exp = "x = 123";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(123);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression2() throws Exception {
+        String exp = "x += 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(0);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression3() throws Exception {
+        String exp = "x -= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(28);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression4() throws Exception {
+        String exp = "x *= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(18);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression5() throws Exception {
+        String exp = "x /= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(7);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression6() throws Exception {
+        String exp = "x %= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(29);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression7() throws Exception {
+        String exp = "x &= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(1);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression8() throws Exception {
+        String exp = "x ^= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(9);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression9() throws Exception {
+        String exp = "x |= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(13);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression10() throws Exception {
+        String exp = "x <<= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(14);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression11() throws Exception {
+        String exp = "x >>= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(2);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression12() throws Exception {
+        String exp = "x >>>= 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(17);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    public void testNormal_AssignmentExpression13() throws Exception {
+        String exp = "x = y = 1";
+        byte[] actual = serialize(exp);
+
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
+            try {
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("x");
+                objOut.writeByte(25);
+                objOut.writeByte(2);
+                objOut.writeUTF("y");
+                objOut.writeByte(25);
+                objOut.writeByte(1);
+                objOut.writeLong(1);
+                objOut.writeByte(26);
+                objOut.writeByte(26);
+                objOut.writeByte(Byte.MAX_VALUE);
+            } finally {
+                objOut.close();
+            }
+        } finally {
+            byteOut.close();
+        }
+        byte[] expected = byteOut.toByteArray();
+
+        assertByteArray(expected, actual);
+    }
+
+    private byte[] serialize(String exp) throws IOException {
+        Parser parser = new Parser();
+        Node node = parser.parse(exp);
+
+        Compiler compiler = new Compiler();
+        CommandList cl = compiler.compile(node);
+
+        Serializer serializer = new Serializer();
+        byte[] data = serializer.serialize(cl);
+
+        return data;
+    }
+
+    private void assertByteArray(byte[] expected, byte[] actual) {
+        assertEquals("expected length=" + expected.length + ", actual length=" + actual.length, expected.length, actual.length);
+
+        for (int i = 0; i < expected.length; i++) {
+            assertEquals("expected[" + i + "]=" + expected[i] + ", actual[" + i + "]=" + actual[i], expected[i], actual[i]);
+        }
+    }
+
+}
diff --git a/expression-computer/uguu.checkstyle.xml b/expression-computer/uguu.checkstyle.xml
new file mode 100644 (file)
index 0000000..a3f5074
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+       This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+Checkstyle-Configuration: Uguu Checks
+Description:
+
+-->
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
+<module name="Checker">
+    <property name="severity" value="warning"/>
+    <module name="TreeWalker">
+        <property name="tabWidth" value="4"/>
+        <module name="JavadocVariable">
+            <property name="scope" value="package"/>
+        </module>
+        <module name="JavadocStyle">
+            <property name="severity" value="ignore"/>
+        </module>
+        <module name="ConstantName"/>
+        <module name="LocalFinalVariableName"/>
+        <module name="LocalVariableName"/>
+        <module name="MemberName"/>
+        <module name="MethodName"/>
+        <module name="PackageName"/>
+        <module name="ParameterName"/>
+        <module name="StaticVariableName"/>
+        <module name="TypeName"/>
+        <module name="AvoidStarImport"/>
+        <module name="IllegalImport"/>
+        <module name="RedundantImport"/>
+        <module name="UnusedImports"/>
+        <module name="EmptyForIteratorPad"/>
+        <module name="MethodParamPad"/>
+        <module name="NoWhitespaceAfter">
+            <property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+        </module>
+        <module name="NoWhitespaceBefore"/>
+        <module name="OperatorWrap"/>
+        <module name="ParenPad"/>
+        <module name="TypecastParenPad"/>
+        <module name="TabCharacter"/>
+        <module name="WhitespaceAfter"/>
+        <module name="WhitespaceAround"/>
+        <module name="ModifierOrder"/>
+        <module name="RedundantModifier"/>
+        <module name="AvoidNestedBlocks"/>
+        <module name="EmptyBlock"/>
+        <module name="LeftCurly"/>
+        <module name="NeedBraces"/>
+        <module name="RightCurly"/>
+        <module name="AvoidInlineConditionals"/>
+        <module name="DoubleCheckedLocking"/>
+        <module name="EmptyStatement"/>
+        <module name="EqualsHashCode"/>
+        <module name="IllegalInstantiation"/>
+        <module name="InnerAssignment"/>
+        <module name="MagicNumber">
+            <property name="severity" value="ignore"/>
+        </module>
+        <module name="MissingSwitchDefault"/>
+        <module name="RedundantThrows"/>
+        <module name="SimplifyBooleanExpression"/>
+        <module name="SimplifyBooleanReturn"/>
+        <module name="DesignForExtension"/>
+        <module name="HideUtilityClassConstructor"/>
+        <module name="InterfaceIsType"/>
+        <module name="VisibilityModifier"/>
+        <module name="ArrayTypeStyle"/>
+        <module name="GenericIllegalRegexp">
+            <property name="format" value="\s+$"/>
+            <property name="ignoreComments" value="true"/>
+            <property name="message" value="Line has trailing spaces."/>
+        </module>
+        <module name="TodoComment"/>
+        <module name="UpperEll"/>
+        <module name="JavadocMethod">
+            <property name="scope" value="package"/>
+        </module>
+        <module name="JavadocType">
+            <property name="scope" value="package"/>
+            <property name="authorFormat" value="uguu@users\.sourceforge\.jp"/>
+        </module>
+        <module name="ImportOrder"/>
+        <module name="DefaultComesLast"/>
+        <module name="FallThrough"/>
+        <module name="IllegalCatch"/>
+        <module name="IllegalThrows"/>
+        <module name="ModifiedControlVariable"/>
+        <module name="RequireThis"/>
+        <module name="StringLiteralEquality"/>
+        <module name="FinalClass"/>
+        <module name="Indentation"/>
+        <module name="TrailingComment"/>
+    </module>
+    <module name="PackageHtml"/>
+    <module name="NewlineAtEndOfFile">
+        <property name="lineSeparator" value="lf"/>
+    </module>
+    <module name="Translation"/>
+</module>