General tidy up, removal of dead code, and bring back to Java 7 level.
This commit is contained in:
		
							parent
							
								
									a876cb6d1b
								
							
						
					
					
						commit
						27efd21089
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | /build/ | ||||||
|  | /dist/ | ||||||
|  | @ -54,43 +54,6 @@ is divided into following sections: | ||||||
|         <property file="nbproject/project.properties"/> |         <property file="nbproject/project.properties"/> | ||||||
|     </target> |     </target> | ||||||
|     <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init"> |     <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init"> | ||||||
|         <j2seproject1:property name="platform.home" value="platforms.${platform.active}.home"/> |  | ||||||
|         <j2seproject1:property name="platform.bootcp" value="platforms.${platform.active}.bootclasspath"/> |  | ||||||
|         <j2seproject1:property name="platform.compiler" value="platforms.${platform.active}.compile"/> |  | ||||||
|         <j2seproject1:property name="platform.javac.tmp" value="platforms.${platform.active}.javac"/> |  | ||||||
|         <condition property="platform.javac" value="${platform.home}/bin/javac"> |  | ||||||
|             <equals arg1="${platform.javac.tmp}" arg2="$${platforms.${platform.active}.javac}"/> |  | ||||||
|         </condition> |  | ||||||
|         <property name="platform.javac" value="${platform.javac.tmp}"/> |  | ||||||
|         <j2seproject1:property name="platform.java.tmp" value="platforms.${platform.active}.java"/> |  | ||||||
|         <condition property="platform.java" value="${platform.home}/bin/java"> |  | ||||||
|             <equals arg1="${platform.java.tmp}" arg2="$${platforms.${platform.active}.java}"/> |  | ||||||
|         </condition> |  | ||||||
|         <property name="platform.java" value="${platform.java.tmp}"/> |  | ||||||
|         <j2seproject1:property name="platform.javadoc.tmp" value="platforms.${platform.active}.javadoc"/> |  | ||||||
|         <condition property="platform.javadoc" value="${platform.home}/bin/javadoc"> |  | ||||||
|             <equals arg1="${platform.javadoc.tmp}" arg2="$${platforms.${platform.active}.javadoc}"/> |  | ||||||
|         </condition> |  | ||||||
|         <property name="platform.javadoc" value="${platform.javadoc.tmp}"/> |  | ||||||
|         <condition property="platform.invalid" value="true"> |  | ||||||
|             <or> |  | ||||||
|                 <contains string="${platform.javac}" substring="$${platforms."/> |  | ||||||
|                 <contains string="${platform.java}" substring="$${platforms."/> |  | ||||||
|                 <contains string="${platform.javadoc}" substring="$${platforms."/> |  | ||||||
|             </or> |  | ||||||
|         </condition> |  | ||||||
|         <fail unless="platform.home">Must set platform.home</fail> |  | ||||||
|         <fail unless="platform.bootcp">Must set platform.bootcp</fail> |  | ||||||
|         <fail unless="platform.java">Must set platform.java</fail> |  | ||||||
|         <fail unless="platform.javac">Must set platform.javac</fail> |  | ||||||
|         <fail if="platform.invalid"> |  | ||||||
|  The J2SE Platform is not correctly set up. |  | ||||||
|  Your active platform is: ${platform.active}, but the corresponding property "platforms.${platform.active}.home" is not found in the project's properties files.  |  | ||||||
|  Either open the project in the IDE and setup the Platform with the same name or add it manually. |  | ||||||
|  For example like this: |  | ||||||
|      ant -Duser.properties.file=<path_to_property_file> jar (where you put the property "platforms.${platform.active}.home" in a .properties file) |  | ||||||
|   or ant -Dplatforms.${platform.active}.home=<path_to_JDK_home> jar (where no properties file is used)  |  | ||||||
|   </fail> |  | ||||||
|         <available file="${manifest.file}" property="manifest.available"/> |         <available file="${manifest.file}" property="manifest.available"/> | ||||||
|         <condition property="splashscreen.available"> |         <condition property="splashscreen.available"> | ||||||
|             <and> |             <and> | ||||||
|  | @ -225,6 +188,15 @@ is divided into following sections: | ||||||
|         <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'"> |         <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'"> | ||||||
|             <length length="0" string="${endorsed.classpath}" when="greater"/> |             <length length="0" string="${endorsed.classpath}" when="greater"/> | ||||||
|         </condition> |         </condition> | ||||||
|  |         <condition else="false" property="jdkBug6558476"> | ||||||
|  |             <and> | ||||||
|  |                 <matches pattern="1\.[56]" string="${java.specification.version}"/> | ||||||
|  |                 <not> | ||||||
|  |                     <os family="unix"/> | ||||||
|  |                 </not> | ||||||
|  |             </and> | ||||||
|  |         </condition> | ||||||
|  |         <property name="javac.fork" value="${jdkBug6558476}"/> | ||||||
|         <property name="jar.index" value="false"/> |         <property name="jar.index" value="false"/> | ||||||
|         <property name="jar.index.metainf" value="${jar.index}"/> |         <property name="jar.index.metainf" value="${jar.index}"/> | ||||||
|         <property name="copylibs.rebase" value="true"/> |         <property name="copylibs.rebase" value="true"/> | ||||||
|  | @ -293,7 +265,7 @@ is divided into following sections: | ||||||
|                 <property location="${build.dir}/empty" name="empty.dir"/> |                 <property location="${build.dir}/empty" name="empty.dir"/> | ||||||
|                 <mkdir dir="${empty.dir}"/> |                 <mkdir dir="${empty.dir}"/> | ||||||
|                 <mkdir dir="@{apgeneratedsrcdir}"/> |                 <mkdir dir="@{apgeneratedsrcdir}"/> | ||||||
|                 <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" executable="${platform.javac}" fork="yes" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}"> |                 <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}"> | ||||||
|                     <src> |                     <src> | ||||||
|                         <dirset dir="@{gensrcdir}" erroronmissingdir="false"> |                         <dirset dir="@{gensrcdir}" erroronmissingdir="false"> | ||||||
|                             <include name="*"/> |                             <include name="*"/> | ||||||
|  | @ -332,7 +304,7 @@ is divided into following sections: | ||||||
|             <sequential> |             <sequential> | ||||||
|                 <property location="${build.dir}/empty" name="empty.dir"/> |                 <property location="${build.dir}/empty" name="empty.dir"/> | ||||||
|                 <mkdir dir="${empty.dir}"/> |                 <mkdir dir="${empty.dir}"/> | ||||||
|                 <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" executable="${platform.javac}" fork="yes" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}"> |                 <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}"> | ||||||
|                     <src> |                     <src> | ||||||
|                         <dirset dir="@{gensrcdir}" erroronmissingdir="false"> |                         <dirset dir="@{gensrcdir}" erroronmissingdir="false"> | ||||||
|                             <include name="*"/> |                             <include name="*"/> | ||||||
|  | @ -412,7 +384,7 @@ is divided into following sections: | ||||||
|             <element name="customize" optional="true"/> |             <element name="customize" optional="true"/> | ||||||
|             <sequential> |             <sequential> | ||||||
|                 <property name="junit.forkmode" value="perTest"/> |                 <property name="junit.forkmode" value="perTest"/> | ||||||
|                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}"> |                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}"> | ||||||
|                     <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/> |                     <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/> | ||||||
|                     <syspropertyset> |                     <syspropertyset> | ||||||
|                         <propertyref prefix="test-sys-prop."/> |                         <propertyref prefix="test-sys-prop."/> | ||||||
|  | @ -435,7 +407,7 @@ is divided into following sections: | ||||||
|             <element name="customize" optional="true"/> |             <element name="customize" optional="true"/> | ||||||
|             <sequential> |             <sequential> | ||||||
|                 <property name="junit.forkmode" value="perTest"/> |                 <property name="junit.forkmode" value="perTest"/> | ||||||
|                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}"> |                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}"> | ||||||
|                     <batchtest todir="${build.test.results.dir}"> |                     <batchtest todir="${build.test.results.dir}"> | ||||||
|                         <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}"> |                         <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}"> | ||||||
|                             <filename name="@{testincludes}"/> |                             <filename name="@{testincludes}"/> | ||||||
|  | @ -474,7 +446,7 @@ is divided into following sections: | ||||||
|                     </fileset> |                     </fileset> | ||||||
|                 </union> |                 </union> | ||||||
|                 <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/> |                 <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/> | ||||||
|                 <testng classfilesetref="test.set" failureProperty="tests.failed" jvm="${platform.java}" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="milkwood" testname="TestNG tests" workingDir="${work.dir}"> |                 <testng classfilesetref="test.set" failureProperty="tests.failed" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="milkwood" testname="TestNG tests" workingDir="${work.dir}"> | ||||||
|                     <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/> |                     <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/> | ||||||
|                     <propertyset> |                     <propertyset> | ||||||
|                         <propertyref prefix="test-sys-prop."/> |                         <propertyref prefix="test-sys-prop."/> | ||||||
|  | @ -554,7 +526,7 @@ is divided into following sections: | ||||||
|             <element name="customize" optional="true"/> |             <element name="customize" optional="true"/> | ||||||
|             <sequential> |             <sequential> | ||||||
|                 <property name="junit.forkmode" value="perTest"/> |                 <property name="junit.forkmode" value="perTest"/> | ||||||
|                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}"> |                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}"> | ||||||
|                     <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/> |                     <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/> | ||||||
|                     <syspropertyset> |                     <syspropertyset> | ||||||
|                         <propertyref prefix="test-sys-prop."/> |                         <propertyref prefix="test-sys-prop."/> | ||||||
|  | @ -579,7 +551,7 @@ is divided into following sections: | ||||||
|             <element name="customize" optional="true"/> |             <element name="customize" optional="true"/> | ||||||
|             <sequential> |             <sequential> | ||||||
|                 <property name="junit.forkmode" value="perTest"/> |                 <property name="junit.forkmode" value="perTest"/> | ||||||
|                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}"> |                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}"> | ||||||
|                     <batchtest todir="${build.test.results.dir}"> |                     <batchtest todir="${build.test.results.dir}"> | ||||||
|                         <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}"> |                         <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}"> | ||||||
|                             <filename name="@{testincludes}"/> |                             <filename name="@{testincludes}"/> | ||||||
|  | @ -759,9 +731,6 @@ is divided into following sections: | ||||||
|                     <classpath> |                     <classpath> | ||||||
|                         <path path="@{classpath}"/> |                         <path path="@{classpath}"/> | ||||||
|                     </classpath> |                     </classpath> | ||||||
|                     <bootclasspath> |  | ||||||
|                         <path path="${platform.bootcp}"/> |  | ||||||
|                     </bootclasspath> |  | ||||||
|                 </nbjpdastart> |                 </nbjpdastart> | ||||||
|             </sequential> |             </sequential> | ||||||
|         </macrodef> |         </macrodef> | ||||||
|  | @ -777,9 +746,7 @@ is divided into following sections: | ||||||
|         </macrodef> |         </macrodef> | ||||||
|     </target> |     </target> | ||||||
|     <target name="-init-debug-args"> |     <target name="-init-debug-args"> | ||||||
|         <exec executable="${platform.java}" outputproperty="version-output"> |         <property name="version-output" value="java version "${ant.java.version}"/> | ||||||
|             <arg value="-version"/> |  | ||||||
|         </exec> |  | ||||||
|         <condition property="have-jdk-older-than-1.4"> |         <condition property="have-jdk-older-than-1.4"> | ||||||
|             <or> |             <or> | ||||||
|                 <contains string="${version-output}" substring="java version "1.0"/> |                 <contains string="${version-output}" substring="java version "1.0"/> | ||||||
|  | @ -804,7 +771,7 @@ is divided into following sections: | ||||||
|             <attribute default="${debug.classpath}" name="classpath"/> |             <attribute default="${debug.classpath}" name="classpath"/> | ||||||
|             <element name="customize" optional="true"/> |             <element name="customize" optional="true"/> | ||||||
|             <sequential> |             <sequential> | ||||||
|                 <java classname="@{classname}" dir="${work.dir}" fork="true" jvm="${platform.java}"> |                 <java classname="@{classname}" dir="${work.dir}" fork="true"> | ||||||
|                     <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> |                     <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> | ||||||
|                     <jvmarg line="${debug-args-line}"/> |                     <jvmarg line="${debug-args-line}"/> | ||||||
|                     <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/> |                     <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/> | ||||||
|  | @ -831,7 +798,7 @@ is divided into following sections: | ||||||
|             <attribute default="jvm" name="jvm"/> |             <attribute default="jvm" name="jvm"/> | ||||||
|             <element name="customize" optional="true"/> |             <element name="customize" optional="true"/> | ||||||
|             <sequential> |             <sequential> | ||||||
|                 <java classname="@{classname}" dir="${work.dir}" fork="true" jvm="${platform.java}"> |                 <java classname="@{classname}" dir="${work.dir}" fork="true"> | ||||||
|                     <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> |                     <jvmarg line="${endorsed.classpath.cmd.line.arg}"/> | ||||||
|                     <jvmarg value="-Dfile.encoding=${runtime.encoding}"/> |                     <jvmarg value="-Dfile.encoding=${runtime.encoding}"/> | ||||||
|                     <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/> |                     <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/> | ||||||
|  | @ -1018,7 +985,7 @@ is divided into following sections: | ||||||
|             <path path="${run.classpath}"/> |             <path path="${run.classpath}"/> | ||||||
|             <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/> |             <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/> | ||||||
|         </pathconvert> |         </pathconvert> | ||||||
|         <echo level="info">${platform.java} -cp "${run.classpath.with.dist.jar}" ${main.class}</echo> |         <echo level="info">java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo> | ||||||
|     </target> |     </target> | ||||||
|     <target depends="init" if="do.archive" name="-do-jar-with-libraries-create-manifest" unless="manifest.available"> |     <target depends="init" if="do.archive" name="-do-jar-with-libraries-create-manifest" unless="manifest.available"> | ||||||
|         <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/> |         <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/> | ||||||
|  | @ -1045,7 +1012,7 @@ is divided into following sections: | ||||||
|         <j2seproject3:copylibs manifest="${tmp.manifest.file}"/> |         <j2seproject3:copylibs manifest="${tmp.manifest.file}"/> | ||||||
|         <echo level="info">To run this application from the command line without Ant, try:</echo> |         <echo level="info">To run this application from the command line without Ant, try:</echo> | ||||||
|         <property location="${dist.jar}" name="dist.jar.resolved"/> |         <property location="${dist.jar}" name="dist.jar.resolved"/> | ||||||
|         <echo level="info">${platform.java} -jar "${dist.jar.resolved}"</echo> |         <echo level="info">java -jar "${dist.jar.resolved}"</echo> | ||||||
|     </target> |     </target> | ||||||
|     <target depends="-do-jar-with-libraries-pack" if="do.archive" name="-do-jar-with-libraries-delete-manifest"> |     <target depends="-do-jar-with-libraries-pack" if="do.archive" name="-do-jar-with-libraries-delete-manifest"> | ||||||
|         <delete> |         <delete> | ||||||
|  | @ -1236,7 +1203,7 @@ is divided into following sections: | ||||||
|                 </not> |                 </not> | ||||||
|             </and> |             </and> | ||||||
|         </condition> |         </condition> | ||||||
|         <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" executable="${platform.javadoc}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}"> |         <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}"> | ||||||
|             <classpath> |             <classpath> | ||||||
|                 <path path="${javac.classpath}"/> |                 <path path="${javac.classpath}"/> | ||||||
|             </classpath> |             </classpath> | ||||||
|  |  | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| build.xml.data.CRC32=d35b316e | build.xml.data.CRC32=31018a52 | ||||||
| build.xml.script.CRC32=cd5c02b3 | build.xml.script.CRC32=cd5c02b3 | ||||||
| build.xml.stylesheet.CRC32=28e38971@1.56.1.46 | build.xml.stylesheet.CRC32=28e38971@1.56.1.46 | ||||||
| # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. | ||||||
| # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. | ||||||
| nbproject/build-impl.xml.data.CRC32=d35b316e | nbproject/build-impl.xml.data.CRC32=31018a52 | ||||||
| nbproject/build-impl.xml.script.CRC32=0441a68e | nbproject/build-impl.xml.script.CRC32=fe6e4d15 | ||||||
| nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46 | nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46 | ||||||
|  |  | ||||||
|  | @ -1,2 +1,6 @@ | ||||||
| compile.on.save=true | compile.on.save=true | ||||||
|  | do.depend=false | ||||||
|  | do.jar=true | ||||||
|  | javac.debug=true | ||||||
|  | javadoc.preview=true | ||||||
| user.properties.file=/home/simon/.jmonkeyplatform/3.0/build.properties | user.properties.file=/home/simon/.jmonkeyplatform/3.0/build.properties | ||||||
|  |  | ||||||
|  | @ -1,9 +1,10 @@ | ||||||
| annotation.processing.enabled=true | annotation.processing.enabled=true | ||||||
| annotation.processing.enabled.in.editor=false | annotation.processing.enabled.in.editor=false | ||||||
| annotation.processing.processor.options= |  | ||||||
| annotation.processing.processors.list= | annotation.processing.processors.list= | ||||||
| annotation.processing.run.all.processors=true | annotation.processing.run.all.processors=true | ||||||
| annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output | ||||||
|  | application.title=milkwood | ||||||
|  | application.vendor=simon | ||||||
| build.classes.dir=${build.dir}/classes | build.classes.dir=${build.dir}/classes | ||||||
| build.classes.excludes=**/*.java,**/*.form | build.classes.excludes=**/*.java,**/*.form | ||||||
| # This directory is removed when the project is cleaned: | # This directory is removed when the project is cleaned: | ||||||
|  | @ -24,6 +25,7 @@ debug.test.classpath=\ | ||||||
| dist.dir=dist | dist.dir=dist | ||||||
| dist.jar=${dist.dir}/milkwood.jar | dist.jar=${dist.dir}/milkwood.jar | ||||||
| dist.javadoc.dir=${dist.dir}/javadoc | dist.javadoc.dir=${dist.dir}/javadoc | ||||||
|  | endorsed.classpath= | ||||||
| excludes= | excludes= | ||||||
| includes=** | includes=** | ||||||
| jar.compress=false | jar.compress=false | ||||||
|  | @ -33,8 +35,8 @@ javac.compilerargs= | ||||||
| javac.deprecation=false | javac.deprecation=false | ||||||
| javac.processorpath=\ | javac.processorpath=\ | ||||||
|     ${javac.classpath} |     ${javac.classpath} | ||||||
| javac.source=1.6 | javac.source=1.7 | ||||||
| javac.target=1.6 | javac.target=1.7 | ||||||
| javac.test.classpath=\ | javac.test.classpath=\ | ||||||
|     ${javac.classpath}:\ |     ${javac.classpath}:\ | ||||||
|     ${build.classes.dir} |     ${build.classes.dir} | ||||||
|  | @ -55,7 +57,8 @@ main.class=cc.journeyman.milkwood.Milkwood | ||||||
| manifest.file=manifest.mf | manifest.file=manifest.mf | ||||||
| meta.inf.dir=${src.dir}/META-INF | meta.inf.dir=${src.dir}/META-INF | ||||||
| mkdist.disabled=false | mkdist.disabled=false | ||||||
| platform.active=JDK_1.6 | obfuscate.options=-keep public class * extends com.jme3.app.Application{public *;}\n-keep public class * extends com.jme3.system.JmeSystemDelegate{public *;}\n-keep public class * implements com.jme3.renderer.Renderer{public *;}\n-keep public class * implements com.jme3.asset.AssetLoader{public *;}\n-keep public class * implements com.jme3.asset.AssetLocator{public *;}\n-keep public class * implements de.lessvoid.nifty.screen.ScreenController{public *;}\n-dontwarn\n-dontnote\n | ||||||
|  | platform.active=default_platform | ||||||
| platforms.JDK_1.6.home=/usr/lib/jvm/java-6-openjdk-amd64/ | platforms.JDK_1.6.home=/usr/lib/jvm/java-6-openjdk-amd64/ | ||||||
| run.classpath=\ | run.classpath=\ | ||||||
|     ${javac.classpath}:\ |     ${javac.classpath}:\ | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ | ||||||
|     <configuration> |     <configuration> | ||||||
|         <data xmlns="http://www.netbeans.org/ns/j2se-project/3"> |         <data xmlns="http://www.netbeans.org/ns/j2se-project/3"> | ||||||
|             <name>milkwood</name> |             <name>milkwood</name> | ||||||
|             <explicit-platform explicit-source-supported="true"/> |  | ||||||
|             <source-roots> |             <source-roots> | ||||||
|                 <root id="src.dir"/> |                 <root id="src.dir"/> | ||||||
|             </source-roots> |             </source-roots> | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| package cc.journeyman.milkwood; | package cc.journeyman.milkwood; | ||||||
| 
 | 
 | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.Collections; |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Composes text output based on a rule tree. |  * Composes text output based on a rule tree. | ||||||
|  | @ -10,130 +9,126 @@ import java.util.Collections; | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| public class Composer { | public class Composer { | ||||||
| 	/** |  | ||||||
| 	 * Whether or not I am in debugging mode. |  | ||||||
| 	 */ |  | ||||||
| 	private final boolean debug; |  | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 *  |      * Whether or not I am in debugging mode. | ||||||
| 	 * @param debug |      */ | ||||||
| 	 *            Whether or not I am in debugging mode. |     private final boolean debug; | ||||||
| 	 */ |  | ||||||
| 	public Composer(boolean debug) { |  | ||||||
| 		this.debug = debug; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * Recursive, backtracking, output generator. |      * | ||||||
| 	 *  |      * @param debug Whether or not I am in debugging mode. | ||||||
| 	 * @param rules the rule set we're working to. |      */ | ||||||
| 	 * @param length the number of tokens still to be output. |     public Composer(boolean debug) { | ||||||
| 	 * @return if a successful path forward is found, that path, else null. |         this.debug = debug; | ||||||
| 	 */ |     } | ||||||
| 	public WordSequence compose(RuleTreeNode rules, int length) { |  | ||||||
| 		WordStack preamble = composePreamble(rules); |  | ||||||
| 		WordSequence result = new WordSequence(); |  | ||||||
| 
 | 
 | ||||||
| 		// composing the preamble will have ended with *ROOT* on top of the |     /** | ||||||
| 		// stack; |      * Recursive, backtracking, output generator. | ||||||
| 		// get rid of it. |      * | ||||||
| 		preamble.pop(); |      * @param rules the rule set we're working to. | ||||||
|  |      * @param length the number of tokens still to be output. | ||||||
|  |      * @return if a successful path forward is found, that path, else null. | ||||||
|  |      */ | ||||||
|  |     protected WordSequence compose(RuleTreeNode rules, int length) { | ||||||
|  |         Window preamble = composePreamble(rules); | ||||||
|  |         WordSequence result = new WordSequence(); | ||||||
| 
 | 
 | ||||||
| 		if (debug) { |         // composing the preamble will have ended with *ROOT* on top of the | ||||||
| 			System.err.println( "Preamble: " + preamble); |         // stack; | ||||||
| 		} |         // get rid of it. | ||||||
|  |         preamble.pop(); | ||||||
| 
 | 
 | ||||||
| 		result.addAll(preamble); |         if (debug) { | ||||||
|  |             System.err.println("Preamble: " + preamble); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
| 		WordStack body = this.compose(preamble, rules, length); |         result.addAll(preamble); | ||||||
| 		Collections.reverse(body); |  | ||||||
| 		result.addAll(body); |  | ||||||
| 
 | 
 | ||||||
| 		return result; |         result.addAll(this.compose(preamble, rules, length)); | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/** |         return result; | ||||||
| 	 * Recursively attempt to find sequences in the ruleset to append to what's |     } | ||||||
| 	 * been composed so far. |  | ||||||
| 	 *  |  | ||||||
| 	 * @param glanceBack the last few words output. |  | ||||||
| 	 * @param rules the rule set we're working to. |  | ||||||
| 	 * @param length the number of tokens still to be output. |  | ||||||
| 	 * @return if a successful path forward is found, that path, else null. |  | ||||||
| 	 */ |  | ||||||
| 	private WordStack compose(WordStack glanceBack, RuleTreeNode rules, |  | ||||||
| 			int length) { |  | ||||||
| 		final WordStack result; |  | ||||||
| 
 | 
 | ||||||
| 		if ( debug) { |     /** | ||||||
| 			System.err.println( String.format( "%d: %s", length, glanceBack)); |      * Recursively attempt to find sequences in the ruleset to append to what's | ||||||
| 		} |      * been composed so far. | ||||||
|  |      * | ||||||
|  |      * @param glanceBack the last few words output. | ||||||
|  |      * @param rules the rule set we're working to. | ||||||
|  |      * @param length the number of tokens still to be output. | ||||||
|  |      * @return if a successful path forward is found, that path, else null. | ||||||
|  |      */ | ||||||
|  |     private WordSequence compose(Window glanceBack, RuleTreeNode rules, | ||||||
|  |             int length) { | ||||||
|  |         final WordSequence result; | ||||||
| 
 | 
 | ||||||
| 		/* are we there yet? */ |         if (debug) { | ||||||
| 		if (length == 0) { |             System.err.println(String.format("%d: %s", length, glanceBack)); | ||||||
| 			result = new WordStack();  |         } | ||||||
| 		} else { |  | ||||||
| 			/* |  | ||||||
| 			 * are there any rules in this ruleset which matches the current |  | ||||||
| 			 * sliding window? if so, then recurse; if not, then fail. |  | ||||||
| 			 */ |  | ||||||
| 			Collection<String> words = rules.match(glanceBack.duplicate()); |  | ||||||
| 
 | 
 | ||||||
| 			if (words.isEmpty()) { |         /* are we there yet? */ | ||||||
| 				/* backtrack */ |         if (length == 0) { | ||||||
| 				result = null; |             result = new WordSequence(); | ||||||
| 			} else { |         } else { | ||||||
| 				result = tryOptions(words, glanceBack, rules, length); |             /* | ||||||
| 			} |              * are there any rules in this ruleset which matches the current | ||||||
| 		} |              * sliding window? if so, then recurse; if not, then fail. | ||||||
| 		return result; |              */ | ||||||
| 	} |             Collection<String> words = rules.match(glanceBack.duplicate()); | ||||||
| 
 | 
 | ||||||
| 	/** |             if (words.isEmpty()) { | ||||||
| 	 * Try each of these candidates in turn, attempting to recurse. |                 /* backtrack */ | ||||||
| 	 * @param candidates words which could potentially be added to the output. |                 result = null; | ||||||
| 	 * @param glanceBack the last few words output. |             } else { | ||||||
| 	 * @param allRules the rule set we're working to. |                 result = tryOptions(words, glanceBack, rules, length); | ||||||
| 	 * @param length the number of tokens still to be output. |             } | ||||||
| 	 * @return if a successful path forward is found, that path, else null. |         } | ||||||
| 	 */ |         return result; | ||||||
| 	private WordStack tryOptions(Collection<String> candidates, |     } | ||||||
| 			WordStack glanceBack, RuleTreeNode allRules, int length) { |  | ||||||
| 		WordStack result = null; |  | ||||||
| 
 | 
 | ||||||
| 		for ( String candidate : candidates) { |     /** | ||||||
| 			result = compose( new WordStack(glanceBack, candidate), allRules, length - 1); |      * Try each of these candidates in turn, attempting to recurse. | ||||||
| 			if ( result != null) { |      * | ||||||
| 				/* by Jove, I think she's got it! */ |      * @param candidates words which could potentially be added to the output. | ||||||
| 				result.push(candidate); |      * @param glanceBack the last few words output. | ||||||
| 				break; |      * @param allRules the rule set we're working to. | ||||||
| 			} |      * @param length the number of tokens still to be output. | ||||||
| 		} |      * @return if a successful path forward is found, that path, else null. | ||||||
|  |      */ | ||||||
|  |     private WordSequence tryOptions(Collection<String> candidates, | ||||||
|  |             Window glanceBack, RuleTreeNode allRules, int length) { | ||||||
|  |         WordSequence result = null; | ||||||
| 
 | 
 | ||||||
| 		return result; |         for (String candidate : candidates) { | ||||||
| 	} |             result = compose(new Window(glanceBack, candidate), allRules, length - 1); | ||||||
|  |             if (result != null) { | ||||||
|  |                 /* by Jove, I think she's got it! */ | ||||||
|  |                 result.push(candidate); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * Random walk of the rule tree to extract (from the root) a legal sequence |      * Random walk of the rule tree to extract (from the root) a legal sequence | ||||||
| 	 * of words the length of our tuple. |      * of words the length of our tuple. | ||||||
| 	 *  |      * | ||||||
| 	 * @param rules |      * @param rules the rule tree (fragment) to walk. | ||||||
| 	 *            the rule tree (fragment) to walk. |      * @return a sequence of words. | ||||||
| 	 * @return a sequence of words. |      */ | ||||||
| 	 */ |     private Window composePreamble(RuleTreeNode rules) { | ||||||
| 	private WordStack composePreamble(RuleTreeNode rules) { |         final Window result; | ||||||
| 		final WordStack result; |         final RuleTreeNode successor = rules.getRule(); | ||||||
| 		final RuleTreeNode successor = rules.getRule(); |  | ||||||
| 
 |  | ||||||
| 		if (successor == null) { |  | ||||||
| 			result = new WordStack(); |  | ||||||
| 		} else { |  | ||||||
| 			result = this.composePreamble(successor); |  | ||||||
| 			result.push(rules.getWord()); |  | ||||||
| 		} |  | ||||||
| 		return result; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  |         if (successor == null) { | ||||||
|  |             result = new Window(); | ||||||
|  |         } else { | ||||||
|  |             result = this.composePreamble(successor); | ||||||
|  |             result.push(rules.getWord()); | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -20,41 +20,39 @@ import java.util.Queue; | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| public class Digester { | public class Digester { | ||||||
| 	/** |  | ||||||
| 	 * Read tokens from the input stream, and compile them into the rule tree |  | ||||||
| 	 * below this root. |  | ||||||
| 	 *  |  | ||||||
| 	 * @param in |  | ||||||
| 	 *            the input stream from which I read. |  | ||||||
| 	 * @param tupleLength |  | ||||||
| 	 *            the length of the tuples I read. |  | ||||||
| 	 * @param root |  | ||||||
| 	 *            the ruleset to which I shall add. |  | ||||||
| 	 * @return the number of tokens read. |  | ||||||
| 	 * @throws IOException if can't read from file system. |  | ||||||
| 	 */ |  | ||||||
| 	protected int read(final InputStream in, final int tupleLength, |  | ||||||
| 			final RuleTreeNode root) throws IOException { |  | ||||||
| 		int result = 0; |  | ||||||
| 		final Queue<WordSequence> openTuples = new LinkedList<WordSequence>(); |  | ||||||
| 		final Tokeniser tok = new Tokeniser(in); |  | ||||||
| 
 | 
 | ||||||
| 		for (int type = tok.nextToken(); type != StreamTokenizer.TT_EOF; type = tok |     /** | ||||||
| 				.nextToken()) { |      * Read tokens from the input stream, and compile them into the rule tree | ||||||
| 			result++; |      * below this root. | ||||||
| 			final WordSequence newTuple = new WordSequence(); |      * | ||||||
| 			String token = tok.readBareToken(); |      * @param in the input stream from which I read. | ||||||
|  |      * @param tupleLength the length of the tuples I read. | ||||||
|  |      * @param root the ruleset to which I shall add. | ||||||
|  |      * @return the number of tokens read. | ||||||
|  |      * @throws IOException if can't read from file system. | ||||||
|  |      */ | ||||||
|  |     protected int digest(final InputStream in, final int tupleLength, | ||||||
|  |             final RuleTreeNode root) throws IOException { | ||||||
|  |         int result = 0; | ||||||
|  |         final Queue<WordSequence> openTuples = new LinkedList<>(); | ||||||
|  |         final Tokeniser tok = new Tokeniser(in); | ||||||
| 
 | 
 | ||||||
| 			openTuples.add(newTuple); |         for (int type = tok.nextToken(); type != StreamTokenizer.TT_EOF; type = tok | ||||||
| 			for (WordSequence tuple : openTuples) { |                 .nextToken()) { | ||||||
| 				tuple.add(token); |             result++; | ||||||
| 			} |             final WordSequence newTuple = new WordSequence(); | ||||||
|  |             String token = tok.readBareToken(); | ||||||
| 
 | 
 | ||||||
| 			if (openTuples.size() > tupleLength) { |             openTuples.add(newTuple); | ||||||
| 				root.addSequence(openTuples.remove()); |             for (WordSequence tuple : openTuples) { | ||||||
| 			} |                 tuple.add(token); | ||||||
| 		} |             } | ||||||
| 
 | 
 | ||||||
| 		return result; |             if (openTuples.size() > tupleLength) { | ||||||
| 	} |                 root.addSequence(openTuples.remove()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,3 +1,9 @@ | ||||||
|  | /* | ||||||
|  |  * Proprietary unpublished source code property of  | ||||||
|  |  * Simon Brooke <simon@journeyman.cc>. | ||||||
|  |  *  | ||||||
|  |  * Copyright (c) 2013 Simon Brooke <simon@journeyman.cc> | ||||||
|  |  */ | ||||||
| package cc.journeyman.milkwood; | package cc.journeyman.milkwood; | ||||||
| 
 | 
 | ||||||
| import java.io.File; | import java.io.File; | ||||||
|  | @ -8,182 +14,158 @@ import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.OutputStream; | import java.io.OutputStream; | ||||||
| 
 | 
 | ||||||
| /* |  | ||||||
|  * Proprietary unpublished source code property of  |  | ||||||
|  * Simon Brooke <simon@journeyman.cc>. |  | ||||||
|  *  |  | ||||||
|  * Copyright (c) 2013 Simon Brooke <simon@journeyman.cc> |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /** | /** | ||||||
|  |  * Text mangler based on | ||||||
|  |  * http://codekata.pragprog.com/2007/01/kata_fourteen_t.html | ||||||
|  * |  * | ||||||
|  * @author Simon Brooke <simon@journeyman.cc> |  * @author Simon Brooke <simon@journeyman.cc> | ||||||
|  */ |  */ | ||||||
| public class Milkwood { | public class Milkwood { | ||||||
| 	/** |  | ||||||
| 	 * The magic token which is deemed to end sentences. |  | ||||||
| 	 */ |  | ||||||
| 	public static final String PERIOD = "."; |  | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * Parse command line arguments and kick off the process. Expected arguments |      * The magic token which is deemed to end sentences. | ||||||
| 	 * include: |      */ | ||||||
| 	 * <dl> |     public static final String PERIOD = "."; | ||||||
| 	 * <dt>-d, -debug</dt> |  | ||||||
| 	 * <dd>Print debugging output to standard error</dd> |  | ||||||
| 	 * <dt>-i [FILE], -input [FILE]</dt> |  | ||||||
| 	 * <dd>Input file, expected to be an English (or, frankly, other natural |  | ||||||
| 	 * language) text. Defaults to standard in.</dd> |  | ||||||
| 	 * <dt>-l [NN], -length [NN]</dt> |  | ||||||
| 	 * <dd>The length in tuples of the desired output. Defaults to 100. |  | ||||||
| 	 * <dt>-n [NN], -tuple-length [NN]</dt> |  | ||||||
| 	 * <dd>The length of tuples into which the file will be analysed, default 2. |  | ||||||
| 	 * </dd> |  | ||||||
| 	 * <dt>-o [FILE], -output [FILE]</dt> |  | ||||||
| 	 * <dd>Output file, to which generated text will be written. Defaults to |  | ||||||
| 	 * standard out.</dd> |  | ||||||
| 	 * </dl> |  | ||||||
| 	 *  |  | ||||||
| 	 * @param args |  | ||||||
| 	 *            the command line arguments |  | ||||||
| 	 * @exception FileNotFoundException |  | ||||||
| 	 *                if the user specifies a file which isn't available. |  | ||||||
| 	 * @excpetion IOException if could not read from input or write to output. |  | ||||||
| 	 */ |  | ||||||
| 	public static void main(String[] args) throws FileNotFoundException, |  | ||||||
| 			IOException { |  | ||||||
| 		/* defaults */ |  | ||||||
| 		InputStream in = System.in; |  | ||||||
| 		OutputStream out = System.out; |  | ||||||
| 		int tupleLength = 2; |  | ||||||
| 		boolean debug = false; |  | ||||||
| 		int length = 100; |  | ||||||
| 
 | 
 | ||||||
| 		for (int cursor = 0; cursor < args.length; cursor++) { |     /** | ||||||
| 			String arg = args[cursor]; |      * Parse command line arguments and kick off the process. Expected arguments | ||||||
|  |      * include: | ||||||
|  |      * <dl> | ||||||
|  |      * <dt>-d, -debug</dt> | ||||||
|  |      * <dd>Print debugging output to standard error</dd> | ||||||
|  |      * <dt>-i [FILE], -input [FILE]</dt> | ||||||
|  |      * <dd>Input file, expected to be an English (or, frankly, other natural | ||||||
|  |      * language) text. Defaults to standard in.</dd> | ||||||
|  |      * <dt>-l [NN], -length [NN]</dt> | ||||||
|  |      * <dd>The length in tuples of the desired output. Defaults to 100. | ||||||
|  |      * <dt>-n [NN], -tuple-length [NN]</dt> | ||||||
|  |      * <dd>The length of tuples into which the file will be analysed, default 2. | ||||||
|  |      * </dd> | ||||||
|  |      * <dt>-o [FILE], -output [FILE]</dt> | ||||||
|  |      * <dd>Output file, to which generated text will be written. Defaults to | ||||||
|  |      * standard out.</dd> | ||||||
|  |      * </dl> | ||||||
|  |      * | ||||||
|  |      * @param args the command line arguments | ||||||
|  |      * @exception FileNotFoundException if the user specifies a file which isn't | ||||||
|  |      * available. | ||||||
|  |      * @excpetion IOException if could not read from input or write to output. | ||||||
|  |      */ | ||||||
|  |     public static void main(String[] args) throws FileNotFoundException, | ||||||
|  |             IOException { | ||||||
|  |         /* defaults */ | ||||||
|  |         InputStream in = System.in; | ||||||
|  |         OutputStream out = System.out; | ||||||
|  |         int tupleLength = 2; | ||||||
|  |         boolean debug = false; | ||||||
|  |         int length = 100; | ||||||
| 
 | 
 | ||||||
| 			if (arg.startsWith("-") && arg.length() > 1) { |         for (int cursor = 0; cursor < args.length; cursor++) { | ||||||
| 				switch (arg.charAt(1)) { |             String arg = args[cursor]; | ||||||
| 				case 'd': |  | ||||||
| 					debug = true; |  | ||||||
| 					break; |  | ||||||
| 				case 'i': |  | ||||||
| 					// input |  | ||||||
| 					in = new FileInputStream(new File(args[++cursor])); |  | ||||||
| 					break; |  | ||||||
| 				case 'o': // output |  | ||||||
| 					out = new FileOutputStream(new File(args[++cursor])); |  | ||||||
| 					break; |  | ||||||
| 				case 'l': // length |  | ||||||
| 					length = Integer.parseInt(args[++cursor]); |  | ||||||
| 					break; |  | ||||||
| 				case 'n': |  | ||||||
| 				case 't': // tuple length |  | ||||||
| 					tupleLength = Integer.parseInt(args[++cursor]); |  | ||||||
| 					break; |  | ||||||
| 				default: |  | ||||||
| 					throw new IllegalArgumentException(String.format( |  | ||||||
| 							"Unrecognised argument '%s'", arg)); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		try { |  | ||||||
| 			new Milkwood().readAndGenerate(in, out, tupleLength, length, debug); |  | ||||||
| 		} finally { |  | ||||||
| 			out.close(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/** |             if (arg.startsWith("-") && arg.length() > 1) { | ||||||
| 	 * Read tokens from this input and use them to generate text on this output. |                 switch (arg.charAt(1)) { | ||||||
| 	 *  |                     case 'd': | ||||||
| 	 * @param in |                         debug = true; | ||||||
| 	 *            the input stream to read. |                         break; | ||||||
| 	 * @param out |                     case 'i': | ||||||
| 	 *            the output stream to write to. |                         // input | ||||||
| 	 * @param tupleLength |                         in = new FileInputStream(new File(args[++cursor])); | ||||||
| 	 *            the length of tuples to be used in generation. |                         break; | ||||||
| 	 * @param length |                     case 'o': // output | ||||||
| 	 *            the length in tokens of the output to be generated. |                         out = new FileOutputStream(new File(args[++cursor])); | ||||||
| 	 * @param debug |                         break; | ||||||
| 	 *            whether to print debugging output. |                     case 'l': // length | ||||||
| 	 * @throws IOException |                         length = Integer.parseInt(args[++cursor]); | ||||||
| 	 *             if the file system buggers up, which is not, in the cosmic |                         break; | ||||||
| 	 *             scheme of things, very likely. |                     case 'n': | ||||||
| 	 */ |                     case 't': // tuple length | ||||||
| 	void readAndGenerate(final InputStream in, final OutputStream out, |                         tupleLength = Integer.parseInt(args[++cursor]); | ||||||
| 			final int tupleLength, int length, boolean debug) |                         break; | ||||||
| 			throws IOException { |                     default: | ||||||
| 		/* The root of the rule tree I shall build. */ |                         throw new IllegalArgumentException(String.format( | ||||||
| 		RuleTreeNode root = new RuleTreeNode(); |                                 "Unrecognised argument '%s'", arg)); | ||||||
| 		read(in, tupleLength, debug, root); |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         try { | ||||||
|  |             new Milkwood().readAndGenerate(in, out, tupleLength, length, debug); | ||||||
|  |         } finally { | ||||||
|  |             out.close(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| 		WordSequence tokens = compose(tupleLength, debug, root, length); |     /** | ||||||
|  |      * Read tokens from this input and use them to generate text on this output. | ||||||
|  |      * | ||||||
|  |      * @param in the input stream to read. | ||||||
|  |      * @param out the output stream to write to. | ||||||
|  |      * @param tupleLength the length of tuples to be used in generation. | ||||||
|  |      * @param length the length in tokens of the output to be generated. | ||||||
|  |      * @param debug whether to print debugging output. | ||||||
|  |      * @throws IOException if the file system buggers up, which is not, in the | ||||||
|  |      * cosmic scheme of things, very likely. | ||||||
|  |      */ | ||||||
|  |     void readAndGenerate(final InputStream in, final OutputStream out, | ||||||
|  |             final int tupleLength, int length, boolean debug) | ||||||
|  |             throws IOException { | ||||||
|  |         /* The root of the rule tree I shall build. */ | ||||||
|  |         RuleTreeNode root = new RuleTreeNode(); | ||||||
|  |         read(in, tupleLength, debug, root); | ||||||
| 
 | 
 | ||||||
| 		write(out, debug, tokens); |         WordSequence tokens = compose(tupleLength, debug, root, length); | ||||||
| 
 | 
 | ||||||
| 		if ( debug) { |         write(out, debug, tokens); | ||||||
| 			System.err.println( "\n\nCompleted."); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/** |         if (debug) { | ||||||
| 	 * Digest the input into a set of rules. |             System.err.println("\n\nCompleted."); | ||||||
| 	 *  |         } | ||||||
| 	 * @param in |     } | ||||||
| 	 *            the input stream. |  | ||||||
| 	 * @param tupleLength |  | ||||||
| 	 *            the length of tuples we shall consider. |  | ||||||
| 	 * @param debug |  | ||||||
| 	 *            whether or not to print debugging output. |  | ||||||
| 	 * @param root |  | ||||||
| 	 *            the root of the rule tree. |  | ||||||
| 	 * @return the number of tokens read. |  | ||||||
| 	 * @throws IOException |  | ||||||
| 	 *             if the file system buggers up, which is not, in the cosmic |  | ||||||
| 	 *             scheme of things, very likely. |  | ||||||
| 	 */ |  | ||||||
| 	private int read(final InputStream in, final int tupleLength, |  | ||||||
| 			boolean debug, RuleTreeNode root) throws IOException { |  | ||||||
| 		int length = new Digester().read(in, tupleLength, root); |  | ||||||
| 
 | 
 | ||||||
| 		if (debug) { |     /** | ||||||
| 			System.err.println(root.toString()); |      * Digest the input into a set of rules. | ||||||
| 		} |      * | ||||||
| 		return length; |      * @param in the input stream. | ||||||
| 	} |      * @param tupleLength the length of tuples we shall consider. | ||||||
|  |      * @param debug whether or not to print debugging output. | ||||||
|  |      * @param root the root of the rule tree. | ||||||
|  |      * @return the number of tokens read. | ||||||
|  |      * @throws IOException if the file system buggers up, which is not, in the | ||||||
|  |      * cosmic scheme of things, very likely. | ||||||
|  |      */ | ||||||
|  |     private int read(final InputStream in, final int tupleLength, | ||||||
|  |             boolean debug, RuleTreeNode root) throws IOException { | ||||||
|  |         int length = new Digester().digest(in, tupleLength, root); | ||||||
| 
 | 
 | ||||||
| 	private WordSequence compose(final int tupleLength, boolean debug, |         if (debug) { | ||||||
| 			RuleTreeNode root, int length) { |             System.err.println(root.toString()); | ||||||
| 		WordSequence tokens = new Composer(debug).compose(root, length); |         } | ||||||
|  |         return length; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| 		if (tokens.contains(PERIOD)) { |     private WordSequence compose(final int tupleLength, boolean debug, | ||||||
| 			tokens = tokens.truncateAtLastInstance(PERIOD); |             RuleTreeNode root, int length) { | ||||||
| 		} |         WordSequence tokens = new Composer(debug).compose(root, length); | ||||||
| 		return tokens; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/** |         if (tokens.contains(PERIOD)) { | ||||||
| 	 * Write this sequence of tokens to this output. |             tokens = tokens.truncateAtLastInstance(PERIOD); | ||||||
| 	 *  |         } | ||||||
| 	 * @param out |         return tokens; | ||||||
| 	 *            the stream to which to write. |     } | ||||||
| 	 * @param debug |  | ||||||
| 	 *            whether or not to print debugging output. |  | ||||||
| 	 * @param tokens |  | ||||||
| 	 *            the sequence of tokens to write. |  | ||||||
| 	 * @throws IOException |  | ||||||
| 	 *             if the file system buggers up, which is not, in the cosmic |  | ||||||
| 	 *             scheme of things, very likely. |  | ||||||
| 	 */ |  | ||||||
| 	private void write(final OutputStream out, boolean debug, |  | ||||||
| 			WordSequence tokens) throws IOException { |  | ||||||
| 		Writer scrivenor = new Writer(out, debug); |  | ||||||
| 		try { |  | ||||||
| 			scrivenor.writeSequence(tokens); |  | ||||||
| 		} finally { |  | ||||||
| 			scrivenor.close(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Write this sequence of tokens to this output. | ||||||
|  |      * | ||||||
|  |      * @param out the stream to which to write. | ||||||
|  |      * @param debug whether or not to print debugging output. | ||||||
|  |      * @param tokens the sequence of tokens to write. | ||||||
|  |      * @throws IOException if the file system buggers up, which is not, in the | ||||||
|  |      * cosmic scheme of things, very likely. | ||||||
|  |      */ | ||||||
|  |     private void write(final OutputStream out, boolean debug, | ||||||
|  |             WordSequence tokens) throws IOException { | ||||||
|  |         try (Writer scrivenor = new Writer(out, debug)) { | ||||||
|  |             scrivenor.writeSequence(tokens); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,17 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Proprietary unpublished source code property of  |  | ||||||
|  * Simon Brooke <simon@journeyman.cc>. |  | ||||||
|  *  |  | ||||||
|  * Copyright (c) 2013 Simon Brooke <simon@journeyman.cc> |  | ||||||
|  */ |  | ||||||
| package cc.journeyman.milkwood; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * |  | ||||||
|  * @author Simon Brooke <simon@journeyman.cc> |  | ||||||
|  */ |  | ||||||
| class NoSuchPathException extends Exception { |  | ||||||
| 
 |  | ||||||
| 	private static final long serialVersionUID = 1L; |  | ||||||
|      |  | ||||||
| } |  | ||||||
|  | @ -16,17 +16,18 @@ import java.util.Random; | ||||||
| import java.util.Stack; | import java.util.Stack; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Mapping a word to its successor words. This is probably highly  |  * Mapping a word to its successor words. This is probably highly inefficient of | ||||||
|  * inefficient of store, but for the present purposes my withers are unwrung.  |  * store, but for the present purposes my withers are unwrung. Not thread safe | ||||||
|  * Not thread safe in this form because of access to the random number generator. |  * in this form because of access to the random number generator. | ||||||
|  * |  * | ||||||
|  * @author Simon Brooke <simon@journeyman.cc> |  * @author Simon Brooke <simon@journeyman.cc> | ||||||
|  */ |  */ | ||||||
| public class RuleTreeNode { | public class RuleTreeNode { | ||||||
| 	/** | 
 | ||||||
| 	 * The magic token which identifies the root node of a rule tree. |     /** | ||||||
| 	 */ |      * The magic token which identifies the root node of a rule tree. | ||||||
| 	public static final String ROOTMAGICTOKEN = "*ROOT*"; |      */ | ||||||
|  |     public static final String ROOTMAGICTOKEN = "*ROOT*"; | ||||||
|     /** |     /** | ||||||
|      * The line separator on this platform. |      * The line separator on this platform. | ||||||
|      */ |      */ | ||||||
|  | @ -35,63 +36,65 @@ public class RuleTreeNode { | ||||||
|      * A random number generator. |      * A random number generator. | ||||||
|      */ |      */ | ||||||
|     private static Random RANDOM = new Random(); |     private static Random RANDOM = new Random(); | ||||||
|      |  | ||||||
|     /** |     /** | ||||||
|      * The word at this node. |      * The word at this node. | ||||||
|      */ |      */ | ||||||
|     private final String word; |     private final String word; | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Potential successors of this node |      * Potential successors of this node | ||||||
|      */ |      */ | ||||||
|     private Map<String,RuleTreeNode> rules = new HashMap<String,RuleTreeNode>(); |     private Map<String, RuleTreeNode> rules = new HashMap<>(); | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * If no argument passed, generate a root node. |      * If no argument passed, generate a root node. | ||||||
|      */ |      */ | ||||||
|     public RuleTreeNode() { |     public RuleTreeNode() { | ||||||
|     	this( RuleTreeNode.ROOTMAGICTOKEN); |         this(RuleTreeNode.ROOTMAGICTOKEN); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Create me wrapping this word. |      * Create me wrapping this word. | ||||||
|  |      * | ||||||
|      * @param word the word I represent. |      * @param word the word I represent. | ||||||
|      */ |      */ | ||||||
|     public RuleTreeNode(String word) { |     public RuleTreeNode(String word) { | ||||||
|         this.word = word; |         this.word = word; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|      |     /** | ||||||
|  |      * Specialisation: neatly format the rule tree. | ||||||
|  |      * | ||||||
|  |      * @return a neatly formatted representation. | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|     public String toString() { |     public String toString() { | ||||||
|     	StringBuffer buffy = new StringBuffer(); |         StringBuffer buffy = new StringBuffer(); | ||||||
| 
 | 
 | ||||||
|     	this.printToBuffer( buffy, 0); |         this.printToBuffer(buffy, 0); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     	return buffy.toString(); |         return buffy.toString(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|      |  | ||||||
|     private void printToBuffer(StringBuffer buffy, int indent) { |     private void printToBuffer(StringBuffer buffy, int indent) { | ||||||
| 		for (int i = 0; i < indent; i++) { |         for (int i = 0; i < indent; i++) { | ||||||
| 			buffy.append( '\t'); |             buffy.append('\t'); | ||||||
| 		} |         } | ||||||
| 		buffy.append( this.getWord()); |         buffy.append(this.getWord()); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 		if ( this.rules.isEmpty()) { |         if (this.rules.isEmpty()) { | ||||||
| 			buffy.append(NEWLINE); |             buffy.append(NEWLINE); | ||||||
| 		} else { |         } else { | ||||||
| 			buffy.append( " ==>").append(NEWLINE); |             buffy.append(" ==>").append(NEWLINE); | ||||||
| 			for ( String successor : this.getSuccessors()) { |             for (String successor : this.getSuccessors()) { | ||||||
| 				rules.get(successor).printToBuffer(buffy, indent + 1); |                 rules.get(successor).printToBuffer(buffy, indent + 1); | ||||||
| 			} |             } | ||||||
| 			buffy.append(NEWLINE); |             buffy.append(NEWLINE); | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 
 |     /** | ||||||
| 	/** |  | ||||||
|      * |      * | ||||||
|      * @return my word. |      * @return my word. | ||||||
|      */ |      */ | ||||||
|  | @ -104,24 +107,24 @@ public class RuleTreeNode { | ||||||
|      * @return a shuffled list of the words which could follow this one. |      * @return a shuffled list of the words which could follow this one. | ||||||
|      */ |      */ | ||||||
|     public Collection<String> getSuccessors() { |     public Collection<String> getSuccessors() { | ||||||
|         ArrayList<String> result = new ArrayList<String>(); |         ArrayList<String> result = new ArrayList<>(); | ||||||
|         result.addAll(rules.keySet()); |         result.addAll(rules.keySet()); | ||||||
|         Collections.shuffle(result, RANDOM); |         Collections.shuffle(result, RANDOM); | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|      |  | ||||||
|     /** |     /** | ||||||
|      * Compile this sequence of tokens into rule nodes under me. |      * Compile this sequence of tokens into rule nodes under me. | ||||||
|  |      * | ||||||
|      * @param sequence the sequence of tokens to compile. |      * @param sequence the sequence of tokens to compile. | ||||||
|      */ |      */ | ||||||
|     public void addSequence(Queue<String> sequence) { |     public void addSequence(Queue<String> sequence) { | ||||||
|         if (!sequence.isEmpty()) { |         if (!sequence.isEmpty()) { | ||||||
|             String word = sequence.remove(); |             String token = sequence.remove(); | ||||||
|             RuleTreeNode successor = this.getRule(word); |             RuleTreeNode successor = this.getRule(token); | ||||||
|             if (successor == null) { |             if (successor == null) { | ||||||
|                 successor = new RuleTreeNode(word); |                 successor = new RuleTreeNode(token); | ||||||
|                 this.rules.put(word, successor); |                 this.rules.put(token, successor); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             successor.addSequence(sequence); |             successor.addSequence(sequence); | ||||||
|  | @ -133,23 +136,23 @@ public class RuleTreeNode { | ||||||
|      * |      * | ||||||
|      * @return the successor chosen, or null if I have none. |      * @return the successor chosen, or null if I have none. | ||||||
|      */ |      */ | ||||||
| 	protected RuleTreeNode getRule() { |     protected RuleTreeNode getRule() { | ||||||
| 		RuleTreeNode result = null; |         RuleTreeNode result = null; | ||||||
| 
 | 
 | ||||||
| 		if (!rules.isEmpty()) { |         if (!rules.isEmpty()) { | ||||||
| 			int target = RANDOM.nextInt(rules.keySet().size()); |             int target = RANDOM.nextInt(rules.keySet().size()); | ||||||
| 
 | 
 | ||||||
| 			for (String key : rules.keySet()) { |             for (String key : rules.keySet()) { | ||||||
| 				/* |                 /* | ||||||
| 				 * NOTE: decrement after test. |                  * NOTE: decrement after test. | ||||||
| 				 */ |                  */ | ||||||
| 				if (target-- == 0) { |                 if (target-- == 0) { | ||||||
| 					result = rules.get(key); |                     result = rules.get(key); | ||||||
| 				} |                 } | ||||||
| 			} |             } | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		return result; |         return result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -161,10 +164,10 @@ public class RuleTreeNode { | ||||||
|         return rules.get(token); |         return rules.get(token); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected String getWord(Stack<String> path) throws NoSuchPathException { |     protected String getWord(Stack<String> path) { | ||||||
|         final String result; |         final String result; | ||||||
| 
 | 
 | ||||||
|         if ( path.isEmpty()) { |         if (path.isEmpty()) { | ||||||
|             result = this.getWord(); |             result = this.getWord(); | ||||||
|         } else { |         } else { | ||||||
|             final RuleTreeNode successor = this.getRule(path.pop()); |             final RuleTreeNode successor = this.getRule(path.pop()); | ||||||
|  | @ -180,25 +183,27 @@ public class RuleTreeNode { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Find all the terminal strings in the current rule set which would match this path. |      * Find all the terminal strings in the current rule set which would match | ||||||
|  |      * this path. | ||||||
|  |      * | ||||||
|      * @param path the path to match |      * @param path the path to match | ||||||
|      * @return a collection (possibly empty) of potential successors. |      * @return a collection (possibly empty) of potential successors. | ||||||
|      */ |      */ | ||||||
| 	public Collection<String> match(WordStack path) { |     public Collection<String> match(Window path) { | ||||||
| 		final Collection<String> result; |         final Collection<String> result; | ||||||
| 
 | 
 | ||||||
|         if ( path.isEmpty()) { |         if (path.isEmpty()) { | ||||||
|             result = this.getSuccessors(); |             result = this.getSuccessors(); | ||||||
|         } else { |         } else { | ||||||
|             final RuleTreeNode successor = this.getRule(path.pop()); |             final RuleTreeNode successor = this.getRule(path.pop()); | ||||||
| 
 | 
 | ||||||
|             if (successor == null) { |             if (successor == null) { | ||||||
|                 result = new ArrayList<String>(); |                 result = new ArrayList<>(); | ||||||
|             } else { |             } else { | ||||||
|                 result = successor.match(path); |                 result = successor.match(path); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 		return result; |         return result; | ||||||
| 	} |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,60 +22,63 @@ import java.io.StreamTokenizer; | ||||||
|  */ |  */ | ||||||
| public class Tokeniser extends StreamTokenizer { | public class Tokeniser extends StreamTokenizer { | ||||||
| 
 | 
 | ||||||
| 	public Tokeniser(Reader r) { |     /** | ||||||
| 		super(r); |      * Initialise me appropriately wrapping this reader. | ||||||
|  |      * @param r the reader to wrap. | ||||||
|  |      */ | ||||||
|  |     public Tokeniser(Reader r) { | ||||||
|  |         super(r); | ||||||
| 
 | 
 | ||||||
| 		this.resetSyntax(); |         this.resetSyntax(); | ||||||
| 		this.whitespaceChars(8, 15); |         this.whitespaceChars(8, 15); | ||||||
| 		this.whitespaceChars(28, 32); |         this.whitespaceChars(28, 32); | ||||||
| 		/* |         /* | ||||||
| 		 * treat quotemarks as white space. Actually it would be better if quote |          * treat quotemarks as white space. Actually it would be better if quote | ||||||
| 		 * marks were white space only if preceded or followed by whitespace, so |          * marks were white space only if preceded or followed by whitespace, so | ||||||
| 		 * that, e.g., 'don't' and 'can't' appeared as single tokens. But that |          * that, e.g., 'don't' and 'can't' appeared as single tokens. But that | ||||||
| 		 * means really reimplementing the parser and I don't have time. |          * means really reimplementing the parser and I don't have time. | ||||||
| 		 */ |          */ | ||||||
| 		this.whitespaceChars((int) '\"', (int) '\"'); |         this.whitespaceChars((int) '\"', (int) '\"'); | ||||||
| 		this.whitespaceChars((int) '\'', (int) '\''); |         this.whitespaceChars((int) '\'', (int) '\''); | ||||||
| 		/* |         /* | ||||||
| 		 * treat underscore and hyphen as whitespace as well. Again, hyphen with |          * treat underscore and hyphen as whitespace as well. Again, hyphen with | ||||||
| 		 * either leading or trailing non-whitespace probably ought to be |          * either leading or trailing non-whitespace probably ought to be | ||||||
| 		 * treated specially, but... |          * treated specially, but... | ||||||
| 		 */ |          */ | ||||||
| 		this.whitespaceChars((int) '_', (int) '_'); |         this.whitespaceChars((int) '_', (int) '_'); | ||||||
| 		this.whitespaceChars((int) '-', (int) '-'); |         this.whitespaceChars((int) '-', (int) '-'); | ||||||
| 		this.wordChars((int) '0', (int) '9'); |         this.wordChars((int) '0', (int) '9'); | ||||||
| 		this.wordChars((int) 'A', (int) 'Z'); |         this.wordChars((int) 'A', (int) 'Z'); | ||||||
| 		this.wordChars((int) 'a', (int) 'z'); |         this.wordChars((int) 'a', (int) 'z'); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	public Tokeniser(InputStream in) { |     public Tokeniser(InputStream in) { | ||||||
| 		this(new BufferedReader(new InputStreamReader(in))); |         this(new BufferedReader(new InputStreamReader(in))); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * There surely must be a better way to get just the token out of a |      * There surely must be a better way to get just the token out of a | ||||||
| 	 * StreamTokenizer...! |      * StreamTokenizer...! | ||||||
| 	 */ |      */ | ||||||
| 	public String readBareToken() { |     public String readBareToken() { | ||||||
| 		final String token; |         final String token; | ||||||
| 
 |  | ||||||
| 		switch (this.ttype) { |  | ||||||
| 		case StreamTokenizer.TT_EOL: |  | ||||||
| 			token = "FIXME"; // TODO: fix this! |  | ||||||
| 			break; |  | ||||||
| 		case StreamTokenizer.TT_NUMBER: |  | ||||||
| 			token = new Double(this.nval).toString(); |  | ||||||
| 			break; |  | ||||||
| 		case StreamTokenizer.TT_WORD: |  | ||||||
| 			token = this.sval.toLowerCase(); |  | ||||||
| 			break; |  | ||||||
| 		default: |  | ||||||
| 			StringBuffer buffy = new StringBuffer(); |  | ||||||
| 			buffy.append((char) this.ttype); |  | ||||||
| 			token = buffy.toString(); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		return token; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  |         switch (this.ttype) { | ||||||
|  |             case StreamTokenizer.TT_EOL: | ||||||
|  |                 token = "FIXME"; // TODO: fix this! | ||||||
|  |                 break; | ||||||
|  |             case StreamTokenizer.TT_NUMBER: | ||||||
|  |                 token = new Double(this.nval).toString(); | ||||||
|  |                 break; | ||||||
|  |             case StreamTokenizer.TT_WORD: | ||||||
|  |                 token = this.sval.toLowerCase(); | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 StringBuilder bob = new StringBuilder(); | ||||||
|  |                 bob.append((char) this.ttype); | ||||||
|  |                 token = bob.toString(); | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |         return token; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,60 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Proprietary unpublished source code property of  |  | ||||||
|  * Simon Brooke <simon@journeyman.cc>. |  | ||||||
|  *  |  | ||||||
|  * Copyright (c) 2013 Simon Brooke <simon@journeyman.cc> |  | ||||||
|  */ |  | ||||||
| package cc.journeyman.milkwood; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.HashMap; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * |  | ||||||
|  * @author Simon Brooke <simon@journeyman.cc> |  | ||||||
|  */ |  | ||||||
| public class TupleDictionary extends HashMap<String, Collection<WordSequence>> { |  | ||||||
| 
 |  | ||||||
| 	private static final long serialVersionUID = 1L; |  | ||||||
| 
 |  | ||||||
| 	/** |  | ||||||
|      * Specialisation: if there isn't an existing entry, create one. |  | ||||||
|      * |  | ||||||
|      * @param token the token to look up |  | ||||||
|      * @return the collection of possible tuples for that token. |  | ||||||
|      */ |  | ||||||
|     public Collection<WordSequence> get(String token) { |  | ||||||
|         Collection<WordSequence> result = super.get(token); |  | ||||||
| 
 |  | ||||||
|         if (result == null) { |  | ||||||
|             result = new ArrayList<WordSequence>(); |  | ||||||
|             this.put(token, result); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return result; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Add a new, empty sequence to my entry for this token. |  | ||||||
|      * @param token the token |  | ||||||
|      * @return the new sequence which was added. |  | ||||||
|      */ |  | ||||||
|     protected WordSequence addSequence(String token) { |  | ||||||
|         return this.addSequence(token, new WordSequence()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Add this sequence to my entry for this token. |  | ||||||
|      * @param token the token. |  | ||||||
|      * @param sequence the sequence to add. Must not be null! |  | ||||||
|      * @return the sequence which was added. |  | ||||||
|      */ |  | ||||||
|     protected WordSequence addSequence(String token, WordSequence sequence) { |  | ||||||
|         assert (sequence != null) : "invalid sequence argument"; |  | ||||||
| 
 |  | ||||||
|         this.get(token).add(sequence); |  | ||||||
| 
 |  | ||||||
|         return sequence; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										56
									
								
								src/cc/journeyman/milkwood/Window.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/cc/journeyman/milkwood/Window.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | ||||||
|  | package cc.journeyman.milkwood; | ||||||
|  | 
 | ||||||
|  | import java.util.Stack; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Sliding window which rules may match. | ||||||
|  |  * | ||||||
|  |  * @author simon | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class Window extends Stack<String> { | ||||||
|  | 
 | ||||||
|  |     private static final long serialVersionUID = 1L; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Create a new, empty, wordstack. | ||||||
|  |      */ | ||||||
|  |     public Window() { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * create a new window from this window, having this new word as its | ||||||
|  |      * terminal and ommitting the current first word. That is, the new window | ||||||
|  |      * should be as long as the old, with each word shuffled up one place. | ||||||
|  |      * | ||||||
|  |      * @param prototype the window to copy from. | ||||||
|  |      * @param terminal the new terminal word. | ||||||
|  |      */ | ||||||
|  |     public Window(Window prototype, String terminal) { | ||||||
|  |         this(); | ||||||
|  | 
 | ||||||
|  |         Window copy = prototype.duplicate(); | ||||||
|  |         copy.pop(); | ||||||
|  |         this.populate(copy, terminal); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void populate(Window copy, String terminal) { | ||||||
|  |         if (copy.isEmpty()) { | ||||||
|  |             this.push(terminal); | ||||||
|  |         } else { | ||||||
|  |             String token = copy.pop(); | ||||||
|  |             this.populate(copy, terminal); | ||||||
|  |             this.push(token); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * A wrapper round clone which hides all the ugly casting. | ||||||
|  |      * | ||||||
|  |      * @return a duplicate copy of myself. | ||||||
|  |      */ | ||||||
|  |     public Window duplicate() { | ||||||
|  |         return (Window) this.clone(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -12,56 +12,58 @@ import java.util.Queue; | ||||||
| /** | /** | ||||||
|  * An ordered sequence of words. Of course it implements Queue since it is a |  * An ordered sequence of words. Of course it implements Queue since it is a | ||||||
|  * LinkedList and LinkedList implements Queue, but I want to make it explicitly |  * LinkedList and LinkedList implements Queue, but I want to make it explicitly | ||||||
|  * clear that this is a queue and can be used as such. |  * clear that this is a queue and can be used as such. Different from WordStack | ||||||
|  |  * which is a Stack. | ||||||
|  |  * | ||||||
|  |  * @see WordStack | ||||||
|  * |  * | ||||||
|  * @author Simon Brooke <simon@journeyman.cc> |  * @author Simon Brooke <simon@journeyman.cc> | ||||||
|  */ |  */ | ||||||
| class WordSequence extends LinkedList<String> implements Queue<String> { | public class WordSequence extends LinkedList<String> implements Queue<String> { | ||||||
| 
 | 
 | ||||||
| 	private static final long serialVersionUID = 1L; |     private static final long serialVersionUID = 1L; | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 *  |      * | ||||||
| 	 * @param tokens |      * @param tokens a sequence of tokens | ||||||
| 	 *            a sequence of tokens |      * @param marker a marker to terminate after the last occurrance of. | ||||||
| 	 * @param marker |      * @return a copy of tokens, truncated at the last occurrance of the marker. | ||||||
| 	 *            a marker to terminate after the last occurrance of. |      */ | ||||||
| 	 * @return a copy of tokens, truncated at the last occurrance of the marker. |     public WordSequence truncateAtLastInstance(String marker) { | ||||||
| 	 */ |         final WordSequence result = new WordSequence(); | ||||||
| 	public WordSequence truncateAtLastInstance(String marker) { |  | ||||||
| 		final WordSequence result = new WordSequence(); |  | ||||||
| 
 | 
 | ||||||
| 		for (String token : this) { |         for (String token : this) { | ||||||
| 			if (token.endsWith(marker) && !this.contains(marker)) { |             result.add(token); | ||||||
| 				/* |             if (token.endsWith(marker) && !this.contains(marker)) { | ||||||
| 				 * If the token we're looking at ends with the marker, and the |                 /* | ||||||
| 				 * remainder of the tokens does not include a token ending with |                  * If the token we're looking at ends with the marker, and the | ||||||
| 				 * the marker, we're done. Otherwise, we continue. OK? |                  * remainder of the tokens does not include a token ending with | ||||||
| 				 */ |                  * the marker, we're done. Otherwise, we continue. OK? | ||||||
| 				break; |                  */ | ||||||
| 			} |                 break; | ||||||
| 			result.add(token); |             } | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		return result; |         return result; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * Specialisation: Working around the bug that the tokeniser treats PERIOD as a word character. |      * Specialisation: Working around the bug that the tokeniser treats PERIOD | ||||||
| 	 */ |      * as a word character. | ||||||
| 	@Override |      */ | ||||||
| 	public boolean contains(Object target) { |     @Override | ||||||
| 		boolean result = false; |     public boolean contains(Object target) { | ||||||
| 		if (target != null) { |         boolean result = false; | ||||||
| 			String marker = target.toString(); |         if (target != null) { | ||||||
|  |             String marker = target.toString(); | ||||||
| 
 | 
 | ||||||
| 			for (String token : this) { |             for (String token : this) { | ||||||
| 				if (token.endsWith(marker)) { |                 if (token.endsWith(marker)) { | ||||||
| 					result = true; |                     result = true; | ||||||
| 					break; |                     break; | ||||||
| 				} |                 } | ||||||
| 			} |             } | ||||||
| 		} |         } | ||||||
| 		return result; |         return result; | ||||||
| 	} |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,57 +0,0 @@ | ||||||
| package cc.journeyman.milkwood; |  | ||||||
| 
 |  | ||||||
| import java.util.Stack; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Sliding window which rules may match. |  | ||||||
|  *  |  | ||||||
|  * @author simon |  | ||||||
|  *  |  | ||||||
|  */ |  | ||||||
| public class WordStack extends Stack<String> { |  | ||||||
| 
 |  | ||||||
| 	private static final long serialVersionUID = 1L; |  | ||||||
| 
 |  | ||||||
| 	/** |  | ||||||
| 	 * Create a new, empty, wordstack. |  | ||||||
| 	 */ |  | ||||||
| 	public WordStack() { |  | ||||||
| 		super(); |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	/** |  | ||||||
| 	 * create a new window from this window, having this new word as its |  | ||||||
| 	 * terminal and ommitting the current first word. That is, the new window |  | ||||||
| 	 * should be as long as the old, with each word shuffled up one place. |  | ||||||
| 	 *  |  | ||||||
| 	 * @param prototype the window to copy from. |  | ||||||
| 	 * @param terminal the new terminal word. |  | ||||||
| 	 */ |  | ||||||
| 	public WordStack(WordStack prototype, String terminal) { |  | ||||||
| 		this(); |  | ||||||
| 
 |  | ||||||
| 		WordStack copy = prototype.duplicate(); |  | ||||||
| 		copy.pop(); |  | ||||||
| 		this.populate( copy, terminal); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	private void populate(WordStack copy, String terminal) { |  | ||||||
| 		if ( copy.isEmpty()) { |  | ||||||
| 			this.push(terminal); |  | ||||||
| 		} else { |  | ||||||
| 			String token = copy.pop(); |  | ||||||
| 			this.populate(copy, terminal); |  | ||||||
| 			this.push( token); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/** |  | ||||||
| 	 * A wrapper round clone which hides all the ugly casting. |  | ||||||
| 	 *  |  | ||||||
| 	 * @return a duplicate copy of myself. |  | ||||||
| 	 */ |  | ||||||
| 	public WordStack duplicate() { |  | ||||||
| 		return (WordStack) this.clone(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
|  | @ -20,152 +20,137 @@ import java.util.Random; | ||||||
|  * @author Simon Brooke <simon@journeyman.cc> |  * @author Simon Brooke <simon@journeyman.cc> | ||||||
|  */ |  */ | ||||||
| class Writer extends BufferedWriter { | class Writer extends BufferedWriter { | ||||||
| 	/** |  | ||||||
| 	 * The average number of sentences in a paragraph. |  | ||||||
| 	 */ |  | ||||||
| 	public static final int AVSENTENCESPERPARA = 5; |  | ||||||
| 	/** |  | ||||||
| 	 * A random number generator. |  | ||||||
| 	 */ |  | ||||||
| 	private static Random RANDOM = new Random(); |  | ||||||
| 	/** |  | ||||||
| 	 * Dictionary of first-words we know about; each first-word maps onto a |  | ||||||
| 	 * tuple of tuples of word sequences beginning with that word, so 'I' might |  | ||||||
| 	 * map onto [[I, CAME, COMMA],[I, SAW, COMMA],[I CONQUERED COMMA]]. |  | ||||||
| 	 */ |  | ||||||
| 	TupleDictionary dictionary = new TupleDictionary(); |  | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * Whether or not I am in debugging mode. |      * Line separator on this platform. | ||||||
| 	 */ |      */ | ||||||
| 	@SuppressWarnings("unused") |     public static final String NEWLINE = System.getProperty("line.separator"); | ||||||
| 	private final boolean debug; |     /** | ||||||
|  |      * The average number of sentences in a paragraph. | ||||||
|  |      */ | ||||||
|  |     public static final int AVSENTENCESPERPARA = 5; | ||||||
|  |     /** | ||||||
|  |      * A random number generator. | ||||||
|  |      */ | ||||||
|  |     private static Random RANDOM = new Random(); | ||||||
|  |     /** | ||||||
|  |      * Whether or not I am in debugging mode. | ||||||
|  |      */ | ||||||
|  |     @SuppressWarnings("unused") | ||||||
|  |     private final boolean debug; | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * @param out |      * @param out the output stream to which I shall write. | ||||||
| 	 *            the output stream to which I shall write. |      * @param debug Whether or not I am in debugging mode. | ||||||
| 	 * @param debug |      */ | ||||||
| 	 *            Whether or not I am in debugging mode. |     public Writer(OutputStream out, final boolean debug) { | ||||||
| 	 */ |         super(new OutputStreamWriter(out)); | ||||||
| 	public Writer(OutputStream out, final boolean debug) { |         this.debug = debug; | ||||||
| 		super(new OutputStreamWriter(out)); |     } | ||||||
| 		this.debug = debug; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * Write this sequence of tokens on this stream, sorting out minor issues of |      * Write this sequence of tokens on this stream, sorting out minor issues of | ||||||
| 	 * orthography. |      * orthography. | ||||||
| 	 *  |      * | ||||||
| 	 * @param tokens |      * @param tokens the tokens. | ||||||
| 	 *            the tokens. |      * @throws IOException if it is impossible to write (e.g. file system full). | ||||||
| 	 * @throws IOException |      */ | ||||||
| 	 *             if it is impossible to write (e.g. file system full). |     public void writeSequence(WordSequence tokens) throws IOException { | ||||||
| 	 */ |         boolean capitaliseNext = true; | ||||||
| 	public void writeSequence(WordSequence tokens) throws IOException { |  | ||||||
| 		boolean capitaliseNext = true; |  | ||||||
| 
 | 
 | ||||||
| 		try { |         for (String token : tokens) { | ||||||
| 			for (String token : tokens) { |             capitaliseNext = writeToken(capitaliseNext, token); | ||||||
| 				capitaliseNext = writeToken(capitaliseNext, token); |         } | ||||||
| 			} |         this.write(NEWLINE); | ||||||
| 		} finally { |     } | ||||||
| 			this.flush(); |  | ||||||
| 			this.close(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * Deal with end of paragraph, capital after full stop, and other minor |      * Deal with end of paragraph, capital after full stop, and other minor | ||||||
| 	 * orthographic conventions. |      * orthographic conventions. | ||||||
| 	 *  |      * | ||||||
| 	 * @param capitalise |      * @param capitalise whether or not the token should be capitalised | ||||||
| 	 *            whether or not the token should be capitalised |      * @param token the token to write; | ||||||
| 	 * @param token |      * @returnvtrue if the next token to be written should be capitalised. | ||||||
| 	 *            the token to write; |      * @throws IOException | ||||||
| 	 * @returnvtrue if the next token to be written should be capitalised. |      */ | ||||||
| 	 * @throws IOException |     private boolean writeToken(boolean capitalise, String token) | ||||||
| 	 */ |             throws IOException { | ||||||
| 	private boolean writeToken(boolean capitalise, String token) |         if (this.spaceBefore(token)) { | ||||||
| 			throws IOException { |             this.write(" "); | ||||||
| 		if (this.spaceBefore(token)) { |         } | ||||||
| 			this.write(" "); |         if (capitalise) { | ||||||
| 		} |             this.write(token.substring(0, 1).toUpperCase(Locale.getDefault())); | ||||||
| 		if (capitalise) { |             this.write(token.substring(1)); | ||||||
| 			this.write(token.substring(0, 1).toUpperCase(Locale.getDefault())); |         } else { | ||||||
| 			this.write(token.substring(1)); |             this.write(token); | ||||||
| 		} else { |         } | ||||||
| 			this.write(token); |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		this.maybeParagraph(token); |         this.maybeParagraph(token); | ||||||
| 
 | 
 | ||||||
| 		return (token.endsWith(Milkwood.PERIOD)); |         return (token.endsWith(Milkwood.PERIOD)); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	/** |     /** | ||||||
| 	 * Return false if token is punctuation, else true. Wouldn't it be nice if |      * Return false if token is punctuation, else true. Wouldn't it be nice if | ||||||
| 	 * Java provided Character.isPunctuation(char)? However, since it doesn't, I |      * Java provided Character.isPunctuation(char)? However, since it doesn't, I | ||||||
| 	 * can give this slightly special semantics: return true only if this is |      * can give this slightly special semantics: return true only if this is | ||||||
| 	 * punctuation which would not normally be preceded with a space. |      * punctuation which would not normally be preceded with a space. | ||||||
| 	 *  |      * | ||||||
| 	 * @param ch |      * @param ch a character. | ||||||
| 	 *            a character. |      * @return true if the should be preceded by a space, else false. | ||||||
| 	 * @return true if the should be preceded by a space, else false. |      */ | ||||||
| 	 */ |     private boolean spaceBefore(String token) { | ||||||
| 	private boolean spaceBefore(String token) { |         final boolean result; | ||||||
| 		final boolean result; |  | ||||||
| 
 | 
 | ||||||
| 		switch (token.length()) { |         switch (token.length()) { | ||||||
| 		case 0: |             case 0: | ||||||
| 			result = false; |                 result = false; | ||||||
| 			break; |                 break; | ||||||
| 		case 1: |             case 1: | ||||||
| 			switch (token.charAt(0)) { |                 switch (token.charAt(0)) { | ||||||
| 			case '.': |                     case '.': | ||||||
| 			case ',': |                     case ',': | ||||||
| 			case ':': |                     case ':': | ||||||
| 			case ';': |                     case ';': | ||||||
| 			case 's': |                     case 's': | ||||||
| 				/* |                     /* | ||||||
| 				 * an 's' on its own is probably evidence of a possessive with |                      * an 's' on its own is probably evidence of a possessive with | ||||||
| 				 * the apostrophe lost |                      * the apostrophe lost | ||||||
| 				 */ |                      */ | ||||||
| 			case 't': |                     case 't': | ||||||
| 				/* |                         /* | ||||||
| 				 * similar; probably 'doesn't' or 'shouldn't' or other cases of |                          * similar; probably 'doesn't' or 'shouldn't' or other cases of | ||||||
| 				 * 'not' with an elided 'o'. |                          * 'not' with an elided 'o'. | ||||||
| 				 */ |                          */ | ||||||
| 				result = false; |                         result = false; | ||||||
| 				break; |                         break; | ||||||
| 			default: |                     default: | ||||||
| 				result = true; |                         result = true; | ||||||
| 				break; |                         break; | ||||||
| 			} |                 } | ||||||
| 			break; |                 break; | ||||||
| 		default: |             default: | ||||||
| 			result = true; |                 result = true; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		return result; |         return result; | ||||||
| 	} |     } | ||||||
| 
 |  | ||||||
| 	/** |  | ||||||
| 	 * If this token is an end-of-sentence token, then, on one chance in some, |  | ||||||
| 	 * have the writer write two new lines. NOTE: The tokeniser is treating |  | ||||||
| 	 * PERIOD ('.') as a word character, even though it has not been told to. |  | ||||||
| 	 * Token.endsWith( PERIOD) is a hack to get round this problem. TODO: |  | ||||||
| 	 * investigate and fix. |  | ||||||
| 	 *  |  | ||||||
| 	 * @param token |  | ||||||
| 	 *            a token |  | ||||||
| 	 * @throws IOException |  | ||||||
| 	 *             if Mr this has run out of ink |  | ||||||
| 	 */ |  | ||||||
| 	private void maybeParagraph(String token) throws IOException { |  | ||||||
| 		if (token.endsWith(Milkwood.PERIOD) |  | ||||||
| 				&& RANDOM.nextInt(AVSENTENCESPERPARA) == 0) { |  | ||||||
| 			this.write("\n\n"); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * If this token is an end-of-sentence token, then, on one chance in some, | ||||||
|  |      * have the writer write two new lines. NOTE: The tokeniser is treating | ||||||
|  |      * PERIOD ('.') as a word character, even though it has not been told to. | ||||||
|  |      * Token.endsWith( PERIOD) is a hack to get round this problem. TODO: | ||||||
|  |      * investigate and fix. | ||||||
|  |      * | ||||||
|  |      * @param token a token | ||||||
|  |      * @throws IOException if Mr this has run out of ink | ||||||
|  |      */ | ||||||
|  |     private void maybeParagraph(String token) throws IOException { | ||||||
|  |         if (token.endsWith(Milkwood.PERIOD) | ||||||
|  |                 && RANDOM.nextInt(AVSENTENCESPERPARA) == 0) { | ||||||
|  |             this.write(NEWLINE); | ||||||
|  |             this.write(NEWLINE); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue