From 98cdf435d4974f4cca8f7b4eb4026da2c88cbc4c Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sun, 26 Mar 2017 11:30:43 -0400 Subject: Update --- .../java/bjc/utils/examples/cli/FDSExample.java | 37 +++++ .../java/bjc/utils/examples/cli/TestContext.java | 11 ++ .../src/main/java/bjc/utils/cli/CLICommander.java | 6 +- .../src/main/java/bjc/utils/cli/Command.java | 39 +++++ .../main/java/bjc/utils/cli/CommandHandler.java | 24 +++ .../src/main/java/bjc/utils/cli/CommandHelp.java | 27 ++++ .../src/main/java/bjc/utils/cli/CommandMode.java | 72 +++++++++ .../main/java/bjc/utils/cli/DelegatingCommand.java | 12 +- .../main/java/bjc/utils/cli/GenericCommand.java | 14 +- .../java/bjc/utils/cli/GenericCommandMode.java | 26 +-- .../src/main/java/bjc/utils/cli/GenericHelp.java | 2 +- .../src/main/java/bjc/utils/cli/ICommand.java | 39 ----- .../main/java/bjc/utils/cli/ICommandHandler.java | 24 --- .../src/main/java/bjc/utils/cli/ICommandHelp.java | 27 ---- .../src/main/java/bjc/utils/cli/ICommandMode.java | 72 --------- .../src/main/java/bjc/utils/cli/NullHelp.java | 2 +- .../src/main/java/bjc/utils/cli/fds/FDS.java | 69 ++++++++ .../main/java/bjc/utils/cli/fds/FDSCommand.java | 26 +++ .../main/java/bjc/utils/cli/fds/FDSException.java | 32 ++++ .../src/main/java/bjc/utils/cli/fds/FDSMode.java | 94 +++++++++++ .../main/java/bjc/utils/cli/fds/SimpleFDSMode.java | 142 +++++++++++++++++ .../java/bjc/utils/data/internals/BoundLazy.java | 21 +-- .../bjc/utils/data/internals/BoundLazyPair.java | 3 +- .../bjc/utils/data/internals/BoundListHolder.java | 1 + .../utils/data/internals/HalfBoundLazyPair.java | 1 + .../java/bjc/utils/data/internals/WrappedLazy.java | 1 + .../bjc/utils/data/internals/WrappedOption.java | 1 + .../main/java/bjc/utils/esodata/PushdownMap.java | 6 +- .../src/main/java/bjc/utils/esodata/Tape.java | 2 + .../main/java/bjc/utils/funcdata/ExtendedMap.java | 6 +- .../java/bjc/utils/funcdata/FunctionalMap.java | 4 +- .../src/main/java/bjc/utils/funcdata/IMap.java | 174 ++++++++++++--------- .../main/java/bjc/utils/funcdata/SentryList.java | 16 ++ .../bjc/utils/funcdata/TransformedValueMap.java | 6 +- .../main/java/bjc/utils/gen/WeightedGrammar.java | 134 +++++++++------- .../src/main/java/bjc/utils/graph/Graph.java | 2 +- .../bjc/utils/gui/panels/SimpleSpinnerPanel.java | 2 +- .../src/main/java/bjc/utils/ioutils/Block.java | 87 +++++++++++ .../main/java/bjc/utils/ioutils/BlockReader.java | 127 ++++----------- .../bjc/utils/parserutils/delims/RegexCloser.java | 13 +- .../bjc/utils/parserutils/delims/RegexOpener.java | 19 ++- .../pratt/commands/AbstractInitialCommand.java | 21 ++- .../parserutils/pratt/commands/BinaryCommand.java | 28 +++- .../parserutils/pratt/commands/ChainCommand.java | 34 +++- .../pratt/commands/ConstantCommand.java | 23 ++- .../pratt/commands/DefaultNonInitialCommand.java | 2 - .../pratt/commands/InitialInterleaveCommand.java | 29 ---- .../pratt/commands/InterleaveSpecifier.java | 30 ---- 48 files changed, 1074 insertions(+), 516 deletions(-) create mode 100644 BJC-Utils2/src/examples/java/bjc/utils/examples/cli/FDSExample.java create mode 100644 BJC-Utils2/src/examples/java/bjc/utils/examples/cli/TestContext.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/Command.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/CommandHandler.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/CommandHelp.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/CommandMode.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/ICommand.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHelp.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDS.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSCommand.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSException.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSMode.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/SimpleFDSMode.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/ioutils/Block.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InitialInterleaveCommand.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InterleaveSpecifier.java (limited to 'BJC-Utils2') diff --git a/BJC-Utils2/src/examples/java/bjc/utils/examples/cli/FDSExample.java b/BJC-Utils2/src/examples/java/bjc/utils/examples/cli/FDSExample.java new file mode 100644 index 0000000..aab4985 --- /dev/null +++ b/BJC-Utils2/src/examples/java/bjc/utils/examples/cli/FDSExample.java @@ -0,0 +1,37 @@ +package bjc.utils.examples.cli; + +import bjc.utils.cli.fds.FDS; +import bjc.utils.cli.fds.FDSException; +import bjc.utils.cli.fds.FDSMode; +import bjc.utils.cli.fds.SimpleFDSMode; + +/** + * Simple example for FDS. + * + * @author bjculkin + * + */ +public class FDSExample { + /** + * Main method. + * + * @param args + * Unused CLI arguments. + */ + public static void main(String[] args) { + System.out.println("Entering rudimentary FDS"); + System.out.println(); + + FDSMode testMode = new SimpleFDSMode<>(); + TestContext ctx = new TestContext(); + + try { + FDS.runFDS(System.in, System.in, System.out, testMode, ctx); + } catch (FDSException fex) { + fex.printStackTrace(); + } + + System.out.println(); + System.out.println("Exiting FDS"); + } +} diff --git a/BJC-Utils2/src/examples/java/bjc/utils/examples/cli/TestContext.java b/BJC-Utils2/src/examples/java/bjc/utils/examples/cli/TestContext.java new file mode 100644 index 0000000..3d543de --- /dev/null +++ b/BJC-Utils2/src/examples/java/bjc/utils/examples/cli/TestContext.java @@ -0,0 +1,11 @@ +package bjc.utils.examples.cli; + +/** + * Test FDS state type. + * + * @author bjculkin + * + */ +public class TestContext { + +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java b/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java index 719d6ca..56a4be0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java @@ -23,7 +23,7 @@ public class CLICommander { /* * The command mode to start execution in. */ - private ICommandMode initialMode; + private CommandMode initialMode; /** * Create a new CLI interface powered by streams. @@ -69,7 +69,7 @@ public class CLICommander { * * Used to preserve the initial mode. */ - ICommandMode currentMode = initialMode; + CommandMode currentMode = initialMode; /* * Process commands until we're told to stop. @@ -124,7 +124,7 @@ public class CLICommander { * @param initialMode * The initial command mode to use. */ - public void setInitialCommandMode(ICommandMode initialMode) { + public void setInitialCommandMode(CommandMode initialMode) { if(initialMode == null) throw new NullPointerException("Initial mode must be non-zero"); this.initialMode = initialMode; diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/Command.java b/BJC-Utils2/src/main/java/bjc/utils/cli/Command.java new file mode 100644 index 0000000..02bc061 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/Command.java @@ -0,0 +1,39 @@ +package bjc.utils.cli; + +/** + * Represents a command that can be invoked from a {@link CommandMode} + * + * @author ben + * + */ +public interface Command { + /** + * Create a command that serves as an alias to this one + * + * @return A command that serves as an alias to this one + */ + Command aliased(); + + /** + * Get the handler that executes this command + * + * @return The handler that executes this command + */ + CommandHandler getHandler(); + + /** + * Get the help entry for this command + * + * @return The help entry for this command + */ + CommandHelp getHelp(); + + /** + * Check if this command is an alias of another command + * + * @return Whether or not this command is an alias of another + */ + default boolean isAlias() { + return false; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/CommandHandler.java b/BJC-Utils2/src/main/java/bjc/utils/cli/CommandHandler.java new file mode 100644 index 0000000..0a3534f --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/CommandHandler.java @@ -0,0 +1,24 @@ +package bjc.utils.cli; + +import java.util.function.Function; + +/** + * A handler for a command + * + * @author ben + * + */ +@FunctionalInterface +public interface CommandHandler extends Function { + /** + * Execute this command + * + * @param args + * The arguments for this command + * @return The command mode to switch to after this command, or null to + * stop executing commands + */ + default CommandMode handle(String[] args) { + return this.apply(args); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/CommandHelp.java b/BJC-Utils2/src/main/java/bjc/utils/cli/CommandHelp.java new file mode 100644 index 0000000..327fb75 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/CommandHelp.java @@ -0,0 +1,27 @@ +package bjc.utils.cli; + +/** + * Interface for the help entry for a command + * + * @author ben + * + */ +public interface CommandHelp { + /** + * Get the description of a command. + * + * @return The description of a command + */ + String getDescription(); + + /** + * Get the summary line for a command. + * + * A summary line should consist of a string of the following format + * "\t" where anything in angle brackets + * should be filled in. + * + * @return The summary line line for a command + */ + String getSummary(); +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/CommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/CommandMode.java new file mode 100644 index 0000000..d26b176 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/CommandMode.java @@ -0,0 +1,72 @@ +package bjc.utils.cli; + +/** + * A mode for determining the commands that are valid to enter, and then + * handling those commands + * + * @author ben + * + */ +public interface CommandMode extends Comparable { + /** + * Check to see if this mode can handle the specified command + * + * @param command + * The command to check + * @return Whether or not this mode can handle the command. It is + * assumed not by default + */ + default boolean canHandle(String command) { + return false; + }; + + /** + * Get the custom prompt for this mode + * + * @return the custom prompt for this mode + * + * @throws UnsupportedOperationException + * if this mode doesn't support a custom prompt + */ + default String getCustomPrompt() { + throw new UnsupportedOperationException("This mode doesn't support a custom prompt"); + } + + /** + * Get the name of this command mode + * + * @return The name of this command mode, which is the empty string by + * default + */ + public default String getName() { + return ""; + } + + /** + * Check if this mode uses a custom prompt + * + * @return Whether or not this mode uses a custom prompt + */ + default boolean isCustomPromptEnabled() { + return false; + } + + /** + * Process a command in this mode + * + * @param command + * The command to process + * @param args + * A list of arguments to the command + * @return The command mode to use for the next command. Defaults to + * returning this, and doing nothing else + */ + default CommandMode process(String command, String[] args) { + return this; + } + + @Override + default int compareTo(CommandMode o) { + return getName().compareTo(o.getName()); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java index 99d7e43..dbbb047 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java @@ -6,11 +6,11 @@ package bjc.utils.cli; * @author ben * */ -class DelegatingCommand implements ICommand { +class DelegatingCommand implements Command { /* * The command to delegate to. */ - private ICommand delegate; + private Command delegate; /** * Create a new command that delegates to another command. @@ -18,22 +18,22 @@ class DelegatingCommand implements ICommand { * @param delegate * The command to delegate to. */ - public DelegatingCommand(ICommand delegate) { + public DelegatingCommand(Command delegate) { this.delegate = delegate; } @Override - public ICommand aliased() { + public Command aliased() { return new DelegatingCommand(delegate); } @Override - public ICommandHandler getHandler() { + public CommandHandler getHandler() { return delegate.getHandler(); } @Override - public ICommandHelp getHelp() { + public CommandHelp getHelp() { return delegate.getHelp(); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java index ea10108..c49b4b9 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java @@ -6,16 +6,16 @@ package bjc.utils.cli; * @author ben * */ -public class GenericCommand implements ICommand { +public class GenericCommand implements Command { /* * The behavior for invoking the command. */ - private ICommandHandler handler; + private CommandHandler handler; /* * The help for the command. */ - private ICommandHelp help; + private CommandHelp help; /** * Create a new generic command. @@ -30,7 +30,7 @@ public class GenericCommand implements ICommand { * null, in which case the description is repeated for * the detailed help. */ - public GenericCommand(ICommandHandler handler, String description, String help) { + public GenericCommand(CommandHandler handler, String description, String help) { if(handler == null) throw new NullPointerException("Command handler must not be null"); this.handler = handler; @@ -43,17 +43,17 @@ public class GenericCommand implements ICommand { } @Override - public ICommand aliased() { + public Command aliased() { return new DelegatingCommand(this); } @Override - public ICommandHandler getHandler() { + public CommandHandler getHandler() { return handler; } @Override - public ICommandHelp getHelp() { + public CommandHelp getHelp() { return help; } diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java index ee2bdbb..7977391 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java @@ -17,17 +17,17 @@ import java.util.function.Consumer; * @author ben * */ -public class GenericCommandMode implements ICommandMode { +public class GenericCommandMode implements CommandMode { /* * Contains the commands this mode handles */ - private IMap commandHandlers; - private IMap defaultHandlers; + private IMap commandHandlers; + private IMap defaultHandlers; /* * Contains help topics without an associated command */ - private IMap helpTopics; + private IMap helpTopics; /* * The action to execute upon encountering an unknown command @@ -103,7 +103,7 @@ public class GenericCommandMode implements ICommandMode { throw new IllegalArgumentException( "Cannot bind alias '" + aliasName + "' to a command with a bound handler"); else { - ICommand aliasedCommand; + Command aliasedCommand; if(defaultHandlers.containsKey(commandName)) { aliasedCommand = defaultHandlers.get(commandName).aliased(); @@ -127,7 +127,7 @@ public class GenericCommandMode implements ICommandMode { * if the specified command already has a handler * registered */ - public void addCommandHandler(String command, ICommand handler) { + public void addCommandHandler(String command, Command handler) { if(command == null) throw new NullPointerException("Command must not be null"); else if(handler == null) @@ -147,7 +147,7 @@ public class GenericCommandMode implements ICommandMode { * @param topic * The contents of the topic */ - public void addHelpTopic(String topicName, ICommandHelp topic) { + public void addHelpTopic(String topicName, CommandHelp topic) { helpTopics.put(topicName, topic); } @@ -274,7 +274,7 @@ public class GenericCommandMode implements ICommandMode { private void doHelpSummary() { normalOutput.accept("Help topics for this command mode are as follows:\n"); - if(commandHandlers.getSize() > 0) { + if(commandHandlers.size() > 0) { commandHandlers.forEachValue(command -> { if(!command.isAlias()) { normalOutput.accept("\t" + command.getHelp().getSummary() + "\n"); @@ -285,7 +285,7 @@ public class GenericCommandMode implements ICommandMode { } normalOutput.accept("\nHelp topics available in all command modes are as follows\n"); - if(defaultHandlers.getSize() > 0) { + if(defaultHandlers.size() > 0) { defaultHandlers.forEachValue(command -> { if(!command.isAlias()) { normalOutput.accept("\t" + command.getHelp().getSummary() + "\n"); @@ -296,7 +296,7 @@ public class GenericCommandMode implements ICommandMode { } normalOutput.accept("\nHelp topics not associated with a command are as follows\n"); - if(helpTopics.getSize() > 0) { + if(helpTopics.size() > 0) { helpTopics.forEachValue(topic -> { normalOutput.accept("\t" + topic.getSummary() + "\n"); }); @@ -324,14 +324,14 @@ public class GenericCommandMode implements ICommandMode { public String getCustomPrompt() { if(customPrompt != null) return customPrompt; - return ICommandMode.super.getCustomPrompt(); + return CommandMode.super.getCustomPrompt(); } @Override public String getName() { if(modeName != null) return modeName; - return ICommandMode.super.getName(); + return CommandMode.super.getName(); } @Override @@ -340,7 +340,7 @@ public class GenericCommandMode implements ICommandMode { } @Override - public ICommandMode process(String command, String[] args) { + public CommandMode process(String command, String[] args) { normalOutput.accept("\n"); if(defaultHandlers.containsKey(command)) diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericHelp.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericHelp.java index bbdd1fc..edda5c0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericHelp.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericHelp.java @@ -6,7 +6,7 @@ package bjc.utils.cli; * @author ben * */ -public class GenericHelp implements ICommandHelp { +public class GenericHelp implements CommandHelp { // The strings for this help topic private String summary; private String description; diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommand.java deleted file mode 100644 index 6d30c6a..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommand.java +++ /dev/null @@ -1,39 +0,0 @@ -package bjc.utils.cli; - -/** - * Represents a command that can be invoked from a {@link ICommandMode} - * - * @author ben - * - */ -public interface ICommand { - /** - * Create a command that serves as an alias to this one - * - * @return A command that serves as an alias to this one - */ - ICommand aliased(); - - /** - * Get the handler that executes this command - * - * @return The handler that executes this command - */ - ICommandHandler getHandler(); - - /** - * Get the help entry for this command - * - * @return The help entry for this command - */ - ICommandHelp getHelp(); - - /** - * Check if this command is an alias of another command - * - * @return Whether or not this command is an alias of another - */ - default boolean isAlias() { - return false; - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java deleted file mode 100644 index d1f7f77..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -package bjc.utils.cli; - -import java.util.function.Function; - -/** - * A handler for a command - * - * @author ben - * - */ -@FunctionalInterface -public interface ICommandHandler extends Function { - /** - * Execute this command - * - * @param args - * The arguments for this command - * @return The command mode to switch to after this command, or null to - * stop executing commands - */ - default ICommandMode handle(String[] args) { - return this.apply(args); - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHelp.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHelp.java deleted file mode 100644 index f267594..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHelp.java +++ /dev/null @@ -1,27 +0,0 @@ -package bjc.utils.cli; - -/** - * Interface for the help entry for a command - * - * @author ben - * - */ -public interface ICommandHelp { - /** - * Get the description of a command. - * - * @return The description of a command - */ - String getDescription(); - - /** - * Get the summary line for a command. - * - * A summary line should consist of a string of the following format - * "\t" where anything in angle brackets - * should be filled in. - * - * @return The summary line line for a command - */ - String getSummary(); -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java deleted file mode 100644 index 431a8cf..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java +++ /dev/null @@ -1,72 +0,0 @@ -package bjc.utils.cli; - -/** - * A mode for determining the commands that are valid to enter, and then - * handling those commands - * - * @author ben - * - */ -public interface ICommandMode extends Comparable { - /** - * Check to see if this mode can handle the specified command - * - * @param command - * The command to check - * @return Whether or not this mode can handle the command. It is - * assumed not by default - */ - default boolean canHandle(String command) { - return false; - }; - - /** - * Get the custom prompt for this mode - * - * @return the custom prompt for this mode - * - * @throws UnsupportedOperationException - * if this mode doesn't support a custom prompt - */ - default String getCustomPrompt() { - throw new UnsupportedOperationException("This mode doesn't support a custom prompt"); - } - - /** - * Get the name of this command mode - * - * @return The name of this command mode, which is the empty string by - * default - */ - public default String getName() { - return ""; - } - - /** - * Check if this mode uses a custom prompt - * - * @return Whether or not this mode uses a custom prompt - */ - default boolean isCustomPromptEnabled() { - return false; - } - - /** - * Process a command in this mode - * - * @param command - * The command to process - * @param args - * A list of arguments to the command - * @return The command mode to use for the next command. Defaults to - * returning this, and doing nothing else - */ - default ICommandMode process(String command, String[] args) { - return this; - } - - @Override - default int compareTo(ICommandMode o) { - return getName().compareTo(o.getName()); - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/NullHelp.java b/BJC-Utils2/src/main/java/bjc/utils/cli/NullHelp.java index 0d511a4..289d9c1 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/NullHelp.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/NullHelp.java @@ -6,7 +6,7 @@ package bjc.utils.cli; * @author ben * */ -public class NullHelp implements ICommandHelp { +public class NullHelp implements CommandHelp { @Override public String getDescription() { return "No description provided"; diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDS.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDS.java new file mode 100644 index 0000000..6dc0337 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDS.java @@ -0,0 +1,69 @@ +package bjc.utils.cli.fds; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import bjc.utils.ioutils.Block; +import bjc.utils.ioutils.BlockReader; + +/** + * Runs a FDS (FDiskScript) interface. + * + * This is a rudimentary console interface inspired heavily by FDisk's interface + * style. + * + * Commands are denoted by a single character, but can invoke submodes. + * + * @author bjculkin + * + */ +public class FDS { + /** + * Run a provided FDS mode until it is exited or there is no more input. + * + * @param comin + * The command input source for the FDS mode. + * + * @param datain + * The data input source for the FDS mode. + * + * @param out + * The output source for the FDS mode. + * + * @param initialMode + * The mode to start in. + * + * @param initialState + * The initial state for the mode. + * + * @return The final state of the mode. + * + * @throws FDSException + * If something went wrong during mode execution. + */ + public static S runFDS(InputStream comin, InputStream datain, OutputStream out, FDSMode initialMode, + S initialState) throws FDSException { + PrintStream printer = new PrintStream(out); + + try (BlockReader blockSource = new BlockReader("\\R", new InputStreamReader(comin))) { + printer.print("Enter a command (m for help): "); + + while (blockSource.hasNext()) { + Block comBlock = blockSource.next(); + + String comString = comBlock.contents.trim(); + + char comChar = comString.charAt(0); + + printer.println(String.format("\nRecieved command '%s'\n", comChar)); + + printer.print("Enter a command (m for help): "); + } + } catch (Exception ex) { + throw new FDSException("Unexpected I/O error", ex); + } + + return initialState; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSCommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSCommand.java new file mode 100644 index 0000000..0a6d29c --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSCommand.java @@ -0,0 +1,26 @@ +package bjc.utils.cli.fds; + +import java.util.Iterator; + +/** + * A command attached to an FDS interface. + * + * @author bjculkin + * + * @param + * The state type of the interface. + */ +public interface FDSCommand { + /** + * Run this command. + * + * @param state + * The current FDS state. + * + * @param input + * The source for data input. + * + * @return The new state, after running the command. + */ + S run(S state, Iterator input); +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSException.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSException.java new file mode 100644 index 0000000..7569d95 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSException.java @@ -0,0 +1,32 @@ +package bjc.utils.cli.fds; + +/** + * Exception thrown when something goes wrong with FDS. + * + * @author bjculkin + * + */ +public class FDSException extends Exception { + /** + * Create a new FDS exception with a message and a cause. + * + * @param message + * The message for the exception. + * + * @param cause + * The cause of the exception. + */ + public FDSException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Create a new FDS exception with a message. + * + * @param message + * The message for the exception. + */ + public FDSException(String message) { + super(message); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSMode.java new file mode 100644 index 0000000..acdcbcb --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSMode.java @@ -0,0 +1,94 @@ +package bjc.utils.cli.fds; + +import bjc.utils.cli.CommandHelp; +import bjc.utils.cli.NullHelp; + +/** + * A collection of related FDS commands. + * + * @author bjculkin + * + * @param + * The FDS state type. + */ +public interface FDSMode { + /** + * Get all the characters that are registered to something in this mode. + * + * In this context, something means a command or submode. + * + * @return All of the characters registered to something in this mode. + */ + char[] registeredChars(); + + /* + * Check for the existence of commands/submodes. + */ + + /** + * Check if there is a command registered to the given character. + * + * @param c + * The character to check + * + * @return Whether or not there is a command bound to that character. + */ + boolean hasCommand(char c); + + /** + * Check if there is a submode registered to the given character. + * + * @param c + * The character to check + * + * @return Whether or not there is a submode bound to that character. + */ + boolean hasSubmode(char c); + + /* + * Get commands and submodes. + */ + + /** + * Get the command attached to a given character. + * + * @param c + * The character to get the command for. + * + * @return The command bound to that character. + * + * @throws FDSException + * If there is no command bound to that character. + */ + FDSCommand getCommand(char c) throws FDSException; + + /** + * Get the command attached to a given character. + * + * @param c + * The character to get the command for. + * + * @return The command bound to that character. + * + * @throws FDSException + * If there is no command bound to that character. + */ + FDSMode getSubmode(char c) throws FDSException; + + /* + * Help utilities + */ + /** + * Get the help for what's bound to a character. + * + * This should be one line. + * + * @param c + * The character to look at the help for. + * + * @return The help for what's bound to the character. + */ + default CommandHelp getHelp(char c) { + return new NullHelp(); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/SimpleFDSMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/SimpleFDSMode.java new file mode 100644 index 0000000..2f6e660 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/SimpleFDSMode.java @@ -0,0 +1,142 @@ +package bjc.utils.cli.fds; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import bjc.utils.cli.CommandHelp; + +import static java.lang.String.format; + +/** + * Simple implementation of {@link FDSMode}. + * + * @author bjculkin + * + * @param + * The FDS state type. + */ +public class SimpleFDSMode implements FDSMode { + private Map> commands; + private Map> modes; + private Map help; + + private Set registered; + private char[] registeredArray; + private boolean changed; + + /** + * Create a new empty FDS mode. + */ + public SimpleFDSMode() { + commands = new HashMap<>(); + modes = new HashMap<>(); + help = new HashMap<>(); + + registered = new HashSet<>(); + changed = true; + } + + /** + * Add a command to the mode. + * + * @param c + * The character to bind to the command. + * + * @param comm + * The command to add. + * + * @param hlp + * The help for the command. + * + * @throws FDSException + * If the character is already bound to a command. + */ + public void addCommand(char c, FDSCommand comm, CommandHelp hlp) throws FDSException { + if (comm == null) + throw new NullPointerException("Command must not be null"); + else if (commands.containsKey(c) || modes.containsKey(c)) + throw new FDSException(format("Character '%s' is already bound")); + + commands.put(c, comm); + + registered.add(c); + if (!changed) changed = true; + } + + /** + * Add a submode to the mode. + * + * @param c + * The character to bind to the submode. + * + * @param mode + * The submode to add. + * + * @throws FDSException + * If the character is already bound to a submode. + */ + public void addSubmode(char c, FDSMode mode) throws FDSException { + if (mode == null) + throw new NullPointerException("Mode must not be null"); + else if (modes.containsKey(c) || commands.containsKey(c)) + throw new FDSException(format("Character '%s' is already bound")); + + modes.put(c, mode); + + registered.add(c); + if (!changed) changed = true; + } + + @Override + public char[] registeredChars() { + if (!changed) return registeredArray; + + registeredArray = new char[registered.size()]; + + int i = 0; + for (char c : registered) { + registeredArray[i] = c; + + i += 1; + } + + changed = false; + + return registeredArray; + } + + @Override + public boolean hasCommand(char c) { + return commands.containsKey(c); + } + + @Override + public boolean hasSubmode(char c) { + return modes.containsKey(c); + } + + @Override + public FDSCommand getCommand(char c) throws FDSException { + if (!commands.containsKey(c)) { + throw new FDSException(String.format("No command bound to '%s'", c)); + } + + return commands.get(c); + } + + @Override + public FDSMode getSubmode(char c) throws FDSException { + if (!modes.containsKey(c)) { + throw new FDSException(String.format("No mode bound to '%s'", c)); + } + + return modes.get(c); + } + + @Override + public CommandHelp getHelp(char c) { + return help.get(c); + } +} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazy.java index 0ec69f0..cc1c0c0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazy.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazy.java @@ -9,9 +9,10 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.function.UnaryOperator; -/** +/* * Implements a lazy holder that has been bound */ +@SuppressWarnings("javadoc") public class BoundLazy implements IHolder { /* * The old value @@ -48,7 +49,7 @@ public class BoundLazy implements IHolder IHolder bind(Function> bindr) { - if(bindr == null) throw new NullPointerException("Binder must not be null"); + if (bindr == null) throw new NullPointerException("Binder must not be null"); /* * Prepare a list of pending actions @@ -65,7 +66,7 @@ public class BoundLazy implements IHolder implements IHolder Function> lift( Function func) { - if(func == null) throw new NullPointerException("Function to lift must not be null"); + if (func == null) throw new NullPointerException("Function to lift must not be null"); return (val) -> { return new Lazy<>(func.apply(val)); @@ -92,7 +93,7 @@ public class BoundLazy implements IHolder IHolder map(Function mapper) { - if(mapper == null) throw new NullPointerException("Mapper must not be null"); + if (mapper == null) throw new NullPointerException("Mapper must not be null"); // Prepare a list of pending actions IList> pendingActions = new FunctionalList<>(); @@ -103,7 +104,7 @@ public class BoundLazy implements IHolder oldHolder = boundHolder; // Bound the value if it hasn't been bound - if(!holderBound) { + if (!holderBound) { oldHolder = oldSupplier.get().unwrap(binder); } @@ -117,14 +118,14 @@ public class BoundLazy implements IHolder transform(UnaryOperator transformer) { - if(transformer == null) throw new NullPointerException("Transformer must not be null"); + if (transformer == null) throw new NullPointerException("Transformer must not be null"); actions.add(transformer); @@ -133,9 +134,9 @@ public class BoundLazy implements IHolder UnwrappedType unwrap(Function unwrapper) { - if(unwrapper == null) throw new NullPointerException("Unwrapper must not be null"); + if (unwrapper == null) throw new NullPointerException("Unwrapper must not be null"); - if(!holderBound) { + if (!holderBound) { boundHolder = oldSupplier.get().unwrap(binder::apply); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazyPair.java index 6ab8121..de290a6 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazyPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazyPair.java @@ -9,9 +9,10 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; -/** +/* * Implements a lazy pair that has been bound */ +@SuppressWarnings("javadoc") public class BoundLazyPair implements IPair { /* * The supplier of the left value diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundListHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundListHolder.java index 467d55d..c838ce7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundListHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundListHolder.java @@ -10,6 +10,7 @@ import java.util.function.UnaryOperator; /* * Holds a list, converted into a holder */ +@SuppressWarnings("javadoc") public class BoundListHolder implements IHolder { private IList> heldHolders; diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java index c5e9c9f..35df1c3 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java @@ -12,6 +12,7 @@ import java.util.function.Supplier; /* * A lazy pair, with only one side bound */ +@SuppressWarnings("javadoc") public class HalfBoundLazyPair implements IPair { private Supplier oldSupplier; diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedLazy.java index f400345..de161e5 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedLazy.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedLazy.java @@ -6,6 +6,7 @@ import bjc.utils.data.Lazy; import java.util.function.Function; import java.util.function.UnaryOperator; +@SuppressWarnings("javadoc") public class WrappedLazy implements IHolder { private IHolder> held; diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedOption.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedOption.java index 1639351..e98332c 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedOption.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedOption.java @@ -6,6 +6,7 @@ import bjc.utils.data.Option; import java.util.function.Function; import java.util.function.UnaryOperator; +@SuppressWarnings("javadoc") public class WrappedOption implements IHolder { private IHolder> held; diff --git a/BJC-Utils2/src/main/java/bjc/utils/esodata/PushdownMap.java b/BJC-Utils2/src/main/java/bjc/utils/esodata/PushdownMap.java index 7587b86..1e8d2d3 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/esodata/PushdownMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/esodata/PushdownMap.java @@ -69,8 +69,8 @@ public class PushdownMap implements IMap } @Override - public int getSize() { - return backing.getSize(); + public int size() { + return backing.size(); } @Override @@ -79,7 +79,7 @@ public class PushdownMap implements IMap } @Override - public IMap mapValues(Function transformer) { + public IMap transform(Function transformer) { throw new UnsupportedOperationException("Cannot transform pushdown maps."); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/esodata/Tape.java b/BJC-Utils2/src/main/java/bjc/utils/esodata/Tape.java index 58efc80..f53f6f7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/esodata/Tape.java +++ b/BJC-Utils2/src/main/java/bjc/utils/esodata/Tape.java @@ -45,6 +45,8 @@ public interface Tape { /** * Insert an element after the current item. + * + * @param itm The item to insert. */ void insertAfter(T itm); diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java index d7bb0de..49382bc 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java @@ -62,8 +62,8 @@ class ExtendedMap implements IMap { } @Override - public int getSize() { - return store.getSize() + delegate.getSize(); + public int size() { + return store.size() + delegate.size(); } @Override @@ -72,7 +72,7 @@ class ExtendedMap implements IMap { } @Override - public IMap mapValues(Function transformer) { + public IMap transform(Function transformer) { return new TransformedValueMap<>(this, transformer); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java index 10a727c..b4e5981 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java @@ -98,7 +98,7 @@ public class FunctionalMap implements IMap implements IMap IMap mapValues(Function transformer) { + public IMap transform(Function transformer) { if(transformer == null) throw new NullPointerException("Transformer must not be null"); return new TransformedValueMap<>(this, transformer); diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java index d83b5c2..6bb5de6 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java @@ -5,109 +5,124 @@ import java.util.function.Consumer; import java.util.function.Function; /** - * Functional wrapper over map providing some useful things + * Functional wrapper over map providing some useful things. * * @author ben * * @param - * The type of this map's keys + * The type of this map's keys. + * * @param - * The type of this map's values - * + * The type of this map's values. */ public interface IMap { /** - * Delete all the values in the map - */ - void clear(); - - /** - * Check if this map contains the specified key + * Execute an action for each entry in the map. * - * @param key - * The key to check - * @return Whether or not the map contains the key - */ - boolean containsKey(KeyType key); - - /** - * Extends this map, creating a new map that will delegate queries to - * the map, but store any added values itself - * - * @return An extended map + * @param action + * the action to execute for each entry in the map. */ - IMap extend(); + void forEach(BiConsumer action); /** - * Execute an action for each entry in the map + * Perform an action for each key in the map. * * @param action - * the action to execute for each entry in the map + * The action to perform on each key in the map. */ - void forEach(BiConsumer action); + default void forEachKey(Consumer action) { + forEach((key, val) -> action.accept(key)); + } /** - * Perform an action for each key in the map + * Perform an action for each value in the map. * * @param action - * The action to perform on each key in the map + * The action to perform on each value in the map. */ - void forEachKey(Consumer action); + default void forEachValue(Consumer action) { + forEach((key, val) -> action.accept(val)); + } /** - * Perform an action for each value in the map + * Check if this map contains the specified key. * - * @param action - * The action to perform on each value in the map + * @param key + * The key to check. + * + * @return Whether or not the map contains the key. */ - void forEachValue(Consumer action); + boolean containsKey(KeyType key); /** - * Get the value assigned to the given key + * Get the value assigned to the given key. * * @param key - * The key to look for a value under - * @return The value of the key - * - * + * The key to look for a value under. + * + * @return The value of the key. */ ValueType get(KeyType key); /** * Get a value from the map, and return a default value if the key - * doesn't exist + * doesn't exist. * * @param key - * The key to attempt to retrieve + * The key to attempt to retrieve. + * * @param defaultValue - * The value to return if the key doesn't exist + * The value to return if the key doesn't exist. + * * @return The value associated with the key, or the default value if - * the key doesn't exist + * the key doesn't exist. */ default ValueType getOrDefault(KeyType key, ValueType defaultValue) { try { return get(key); - } catch(IllegalArgumentException iaex) { - // We don't care about this, because it indicates a key - // is - // missing + } catch (IllegalArgumentException iaex) { + /* + * We don't care about this, because it indicates a key + * is missing. + */ return defaultValue; } } /** - * Get the number of entries in this map + * Add an entry to the map. * - * @return The number of entries in this map + * @param key + * The key to put the value under. + * + * @param val + * The value to add. + * + * @return The previous value of the key in the map, or null if the key + * wasn't in the map. However, note that it may also return null + * if the key was set to null. + * + * @throws UnsupportedOperationException + * if the map implementation doesn't support modifying + * the map + */ + ValueType put(KeyType key, ValueType val); + + /** + * Delete all the values in the map. */ - int getSize(); + default void clear() { + keyList().forEach((key) -> remove(key)); + } /** - * Get a list of all the keys in this map + * Get the number of entries in this map. * - * @return A list of all the keys in this map + * @return The number of entries in this map. */ - IList keyList(); + default int size() { + return keyList().getSize(); + } /** * Transform the values returned by this map. @@ -117,46 +132,57 @@ public interface IMap { * likely not work as expected. * * @param - * The new type of returned values + * The new type of returned values. + * * @param transformer - * The function to use to transform values - * @return The map where each value will be transformed after lookup + * The function to use to transform values. + * + * @return The map where each value will be transformed after lookup. */ - IMap mapValues(Function transformer); + default IMap transform(Function transformer) { + return new TransformedValueMap<>(this, transformer); + } /** - * Add an entry to the map - * - * @param key - * The key to put the value under - * @param val - * The value to add - * @return The previous value of the key in the map, or null if the key - * wasn't in the map. However, note that it may also return null - * if the key was set to null. + * Extends this map, creating a new map that will delegate queries to + * the map, but store any added values itself. * - * @throws UnsupportedOperationException - * if the map implementation doesn't support modifying - * the map + * @return An extended map. */ - ValueType put(KeyType key, ValueType val); + IMap extend(); /** - * Remove the value bound to the key + * Remove the value bound to the key. * * @param key - * The key to remove from the map + * The key to remove from the map. + * * @return The previous value for the key in the map, or null if the key * wasn't in the class. NOTE: Just because you received null, * doesn't mean the map wasn't changed. It may mean that someone - * put a null value for that key into the map + * put a null value for that key into the map. */ ValueType remove(KeyType key); /** - * Get a list of the values in this map + * Get a list of all the keys in this map. * - * @return A list of values in this map + * @return A list of all the keys in this map. */ - IList valueList(); + IList keyList(); + + /** + * Get a list of the values in this map. + * + * @return A list of values in this map. + */ + default IList valueList() { + IList returns = new FunctionalList<>(); + + for (KeyType key : keyList()) { + returns.add(get(key)); + } + + return returns; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/SentryList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/SentryList.java index 060f69e..f52a286 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/SentryList.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/SentryList.java @@ -2,11 +2,27 @@ package bjc.utils.funcdata; import java.util.List; +/** + * A list that logs when items are inserted into it. + * + * @author bjculkin + * + * @param The type of item in the list. + */ public class SentryList extends FunctionalList { + /** + * Create a new sentry list. + */ public SentryList() { super(); } + /** + * Create a new sentry list backed by an existing list. + * + * @param backing + * The backing list. + */ public SentryList(List backing) { super(backing); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java index d4e1762..89ea96d 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java @@ -65,8 +65,8 @@ final class TransformedValueMap implements IMap implements IMap IMap mapValues(Function transform) { + public IMap transform(Function transform) { return new TransformedValueMap<>(this, transform); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java index 15d7753..66ee993 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java @@ -19,7 +19,7 @@ import java.util.function.Supplier; * @author ben * * @param - * The values that make up sentances of this grammar. + * The values that make up sentences of this grammar. */ public class WeightedGrammar { /** @@ -77,20 +77,38 @@ public class WeightedGrammar { public WeightedGrammar(Random source) { this(); - if(source == null) throw new NullPointerException("Source of randomness must be non-null"); + if (source == null) throw new NullPointerException("Source of randomness must be non-null"); rng = source; } + /** + * Configure the action to perform on special tokens. + * + * @param marker + * The marker to find special tokens. + * + * @param action + * The action to take on those tokens. + */ public void configureSpecial(Predicate marker, BiFunction, IList> action) { specialMarker = marker; specialAction = action; } + /** + * Adds a special rule to the grammar. + * + * @param ruleName + * The name of the special rule. + * + * @param cse + * The case for the rule. + */ public void addSpecialRule(E ruleName, Supplier> cse) { - if(ruleName == null) + if (ruleName == null) throw new NullPointerException("Rule name must not be null"); - else if(cse == null) throw new NullPointerException("Case must not be null"); + else if (cse == null) throw new NullPointerException("Case must not be null"); specialRules.put(ruleName, cse); } @@ -106,9 +124,9 @@ public class WeightedGrammar { * The case being added. */ public void addCase(E ruleName, int probability, IList cse) { - if(ruleName == null) + if (ruleName == null) throw new NullPointerException("Rule name must be not null"); - else if(cse == null) throw new NullPointerException("Case body must not be null"); + else if (cse == null) throw new NullPointerException("Case body must not be null"); rules.get(ruleName).addProbability(probability, cse); } @@ -123,13 +141,13 @@ public class WeightedGrammar { * @return Whether the alias was succesfully created */ public boolean addGrammarAlias(E name, E alias) { - if(name == null) + if (name == null) throw new NullPointerException("Subgrammar name must not be null"); - else if(alias == null) throw new NullPointerException("Subgrammar alias must not be null"); + else if (alias == null) throw new NullPointerException("Subgrammar alias must not be null"); - if(subgrammars.containsKey(alias)) return false; + if (subgrammars.containsKey(alias)) return false; - if(subgrammars.containsKey(name)) { + if (subgrammars.containsKey(name)) { subgrammars.put(alias, subgrammars.get(name)); return true; } @@ -142,14 +160,14 @@ public class WeightedGrammar { * * @param name * The name of the rule to add. - * @return Whether or not the rule was succesfully added. + * @return Whether or not the rule was successfully added. */ public boolean addRule(E name) { - if(rng == null) { + if (rng == null) { rng = new Random(); } - if(name == null) throw new NullPointerException("Rule name must not be null"); + if (name == null) throw new NullPointerException("Rule name must not be null"); return addRule(name, new WeightedRandom<>(rng)); } @@ -164,11 +182,11 @@ public class WeightedGrammar { * @return Whether or not the rule was succesfully added. */ public boolean addRule(E name, WeightedRandom> cases) { - if(name == null) + if (name == null) throw new NullPointerException("Name must not be null"); - else if(cases == null) throw new NullPointerException("Cases must not be null"); + else if (cases == null) throw new NullPointerException("Cases must not be null"); - if(rules.containsKey(name)) return false; + if (rules.containsKey(name)) return false; rules.put(name, cases); return true; @@ -184,11 +202,11 @@ public class WeightedGrammar { * @return Whether or not the subgrammar was succesfully added. */ public boolean addSubgrammar(E name, WeightedGrammar subgrammar) { - if(name == null) + if (name == null) throw new NullPointerException("Subgrammar name must not be null"); - else if(subgrammar == null) throw new NullPointerException("Subgrammar must not be null"); + else if (subgrammar == null) throw new NullPointerException("Subgrammar must not be null"); - if(subgrammars.containsKey(name)) return false; + if (subgrammars.containsKey(name)) return false; subgrammars.put(name, subgrammar); return true; @@ -201,7 +219,7 @@ public class WeightedGrammar { * The name of the rule to remove. */ public void deleteRule(E name) { - if(name == null) throw new NullPointerException("Rule name must not be null"); + if (name == null) throw new NullPointerException("Rule name must not be null"); rules.remove(name); } @@ -213,7 +231,7 @@ public class WeightedGrammar { * The name of the subgrammar to remove. */ public void deleteSubgrammar(E name) { - if(name == null) throw new NullPointerException("Rule name must not be null"); + if (name == null) throw new NullPointerException("Rule name must not be null"); subgrammars.remove(name); } @@ -221,20 +239,20 @@ public class WeightedGrammar { /** * Generate a set of debug sentences for the specified rule. * - * Only generates sentances one layer deep. + * Only generates sentences one layer deep. * * @param ruleName * The rule to test. - * @return A set of sentances generated by the specified rule. + * @return A set of sentences generated by the specified rule. */ public IList> generateDebugValues(E ruleName) { - if(ruleName == null) throw new NullPointerException("Rule name must not be null"); + if (ruleName == null) throw new NullPointerException("Rule name must not be null"); IList> returnedList = new FunctionalList<>(); WeightedRandom> ruleGenerator = rules.get(ruleName); - for(int i = 0; i < 10; i++) { + for (int i = 0; i < 10; i++) { returnedList.add(ruleGenerator.generateValue()); } @@ -261,49 +279,49 @@ public class WeightedGrammar { * rule. */ public IList generateGenericValues(E initRules, Function tokenTransformer, T spacer) { - if(initRules == null) + if (initRules == null) throw new NullPointerException("Initial rule must not be null"); - else if(tokenTransformer == null) + else if (tokenTransformer == null) throw new NullPointerException("Transformer must not be null"); - else if(spacer == null) throw new NullPointerException("Spacer must not be null"); + else if (spacer == null) throw new NullPointerException("Spacer must not be null"); IList returnedList = new FunctionalList<>(); IList genRules = new FunctionalList<>(initRules); - if(specialMarker != null) { - if(specialMarker.test(initRules)) { + if (specialMarker != null) { + if (specialMarker.test(initRules)) { genRules = specialAction.apply(initRules, this); } } - for(E initRule : genRules.toIterable()) { - if(specialRules.containsKey(initRule)) { - for(E rulePart : specialRules.get(initRule).get().toIterable()) { + for (E initRule : genRules.toIterable()) { + if (specialRules.containsKey(initRule)) { + for (E rulePart : specialRules.get(initRule).get().toIterable()) { Iterable generatedRuleParts = generateGenericValues(rulePart, tokenTransformer, spacer).toIterable(); - for(T generatedRulePart : generatedRuleParts) { + for (T generatedRulePart : generatedRuleParts) { returnedList.add(generatedRulePart); returnedList.add(spacer); } } - } else if(subgrammars.containsKey(initRule)) { + } else if (subgrammars.containsKey(initRule)) { Iterable ruleParts = subgrammars.get(initRule) .generateGenericValues(initRule, tokenTransformer, spacer).toIterable(); - for(T rulePart : ruleParts) { + for (T rulePart : ruleParts) { returnedList.add(rulePart); returnedList.add(spacer); } - } else if(rules.containsKey(initRule)) { + } else if (rules.containsKey(initRule)) { Iterable ruleParts = rules.get(initRule).generateValue().toIterable(); - for(E rulePart : ruleParts) { + for (E rulePart : ruleParts) { Iterable generatedRuleParts = generateGenericValues(rulePart, tokenTransformer, spacer).toIterable(); - for(T generatedRulePart : generatedRuleParts) { + for (T generatedRulePart : generatedRuleParts) { returnedList.add(generatedRulePart); returnedList.add(spacer); } @@ -311,7 +329,7 @@ public class WeightedGrammar { } else { T transformedToken = tokenTransformer.apply(initRule); - if(transformedToken == null) + if (transformedToken == null) throw new NullPointerException("Transformer created null token"); returnedList.add(transformedToken); @@ -353,7 +371,7 @@ public class WeightedGrammar { * @return The number of rules in this grammar */ public int getRuleCount() { - return rules.getSize(); + return rules.size(); } /** @@ -378,7 +396,7 @@ public class WeightedGrammar { * @return The subgrammar with the specified name. */ public WeightedGrammar getSubgrammar(E name) { - if(name == null) throw new NullPointerException("Subgrammar name must not be null"); + if (name == null) throw new NullPointerException("Subgrammar name must not be null"); return subgrammars.get(name); } @@ -392,6 +410,14 @@ public class WeightedGrammar { return initialRule != null && !initialRule.equalsIgnoreCase(""); } + /** + * Check if this grammar has a given rule. + * + * @param ruleName + * The rule to check for. + * + * @return Whether or not the grammar has a rule by that name. + */ public boolean hasRule(E ruleName) { return rules.containsKey(ruleName) || specialRules.containsKey(ruleName); } @@ -409,11 +435,11 @@ public class WeightedGrammar { * The number of times to prefix the token */ public void multiPrefixRule(E ruleName, E prefixToken, int additionalProbability, int numberOfTimes) { - if(ruleName == null) + if (ruleName == null) throw new NullPointerException("Rule name must not be null"); - else if(prefixToken == null) + else if (prefixToken == null) throw new NullPointerException("Prefix token must not be null"); - else if(numberOfTimes < 1) + else if (numberOfTimes < 1) throw new IllegalArgumentException("Number of times to prefix must be positive."); WeightedRandom> rule = rules.get(ruleName); @@ -423,18 +449,18 @@ public class WeightedGrammar { rule.getValues().forEach((pair) -> { IList> newRule = new FunctionalList<>(); - for(int i = 1; i <= numberOfTimes; i++) { + for (int i = 1; i <= numberOfTimes; i++) { IList newCase = pair.merge((left, right) -> { IList returnVal = new FunctionalList<>(); - for(E val : right.toIterable()) { + for (E val : right.toIterable()) { returnVal.add(val); } return returnVal; }); - for(int j = 1; j <= i; j++) { + for (int j = 1; j <= i; j++) { newCase.prepend(prefixToken); } @@ -467,9 +493,9 @@ public class WeightedGrammar { * The token to prefix to the rule */ public void prefixRule(E ruleName, E prefixToken, int additionalProbability) { - if(ruleName == null) + if (ruleName == null) throw new NullPointerException("Rule name must not be null"); - else if(prefixToken == null) throw new NullPointerException("Prefix token must not be null"); + else if (prefixToken == null) throw new NullPointerException("Prefix token must not be null"); WeightedRandom> rule = rules.get(ruleName); @@ -479,7 +505,7 @@ public class WeightedGrammar { IList newCase = pair.merge((left, right) -> { IList returnVal = new FunctionalList<>(); - for(E val : right.toIterable()) { + for (E val : right.toIterable()) { returnVal.add(val); } @@ -515,9 +541,9 @@ public class WeightedGrammar { * Additional probability of the prefixed rule */ public void suffixRule(E ruleName, E suffixToken, int additionalProbability) { - if(ruleName == null) + if (ruleName == null) throw new NullPointerException("Rule name must not be null"); - else if(suffixToken == null) throw new NullPointerException("Prefix token must not be null"); + else if (suffixToken == null) throw new NullPointerException("Prefix token must not be null"); WeightedRandom> rule = rules.get(ruleName); @@ -527,7 +553,7 @@ public class WeightedGrammar { IList newCase = par.merge((left, right) -> { IList returnVal = new FunctionalList<>(); - for(E val : right.toIterable()) { + for (E val : right.toIterable()) { returnVal.add(val); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java index d033f04..ff36b2b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java @@ -208,7 +208,7 @@ public class Graph { * @return A count of the vertices in this graph */ public int getVertexCount() { - return backing.getSize(); + return backing.size(); } /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleSpinnerPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleSpinnerPanel.java index a573bea..2b48adf 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleSpinnerPanel.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/panels/SimpleSpinnerPanel.java @@ -16,7 +16,7 @@ import javax.swing.SpinnerModel; public class SimpleSpinnerPanel extends JPanel { private static final long serialVersionUID = -4734279623645236868L; - /* + /** * The spinner being used */ public final JSpinner inputValue; diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/Block.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/Block.java new file mode 100644 index 0000000..19de1ae --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/Block.java @@ -0,0 +1,87 @@ +package bjc.utils.ioutils; + +/** + * Represents a block of text read in from a source. + * + * @author EVE + * + */ +public class Block { + /** + * The contents of this block. + */ + public final String contents; + + /** + * The line of the source this block started on. + */ + public final int startLine; + + /** + * The line of the source this block ended on. + */ + public final int endLine; + + /** + * The number of this block. + */ + public final int blockNo; + + /** + * Create a new block. + * + * @param blockNo + * The number of this block. + * @param contents + * The contents of this block. + * @param startLine + * The line this block started on. + * @param endLine + * The line this block ended. + */ + public Block(int blockNo, String contents, int startLine, int endLine) { + this.contents = contents; + this.startLine = startLine; + this.endLine = endLine; + this.blockNo = blockNo; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + + result = prime * result + blockNo; + result = prime * result + ((contents == null) ? 0 : contents.hashCode()); + result = prime * result + endLine; + result = prime * result + startLine; + + return result; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null) return false; + if(!(obj instanceof Block)) return false; + + Block other = (Block) obj; + + if(blockNo != other.blockNo) return false; + + if(contents == null) { + if(other.contents != null) return false; + } else if(!contents.equals(other.contents)) return false; + + if(endLine != other.endLine) return false; + if(startLine != other.startLine) return false; + + return true; + } + + @Override + public String toString() { + return String.format("Block #%d (from lines %d to %d), length: %d characters", blockNo, startLine, + endLine, contents.length()); + } +} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/BlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/BlockReader.java index 33bbbd5..fed74fe 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/BlockReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/BlockReader.java @@ -2,6 +2,7 @@ package bjc.utils.ioutils; import java.io.LineNumberReader; import java.io.Reader; +import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Scanner; import java.util.function.Consumer; @@ -10,7 +11,7 @@ import java.util.regex.Pattern; /** * Implements reading numbered blocks from a source. * - * A block is a series of characters, seperated by some regular expression. + * A block is a series of characters, separated by some regular expression. * * NOTE: The EOF marker is always treated as a delimiter. You are expected to * handle blocks that may be shorter than you expect. @@ -18,93 +19,7 @@ import java.util.regex.Pattern; * @author EVE * */ -public class BlockReader implements AutoCloseable { - /** - * Represents a block of text read in from a source. - * - * @author EVE - * - */ - public static class Block { - /** - * The contents of this block. - */ - public final String contents; - - /** - * The line of the source this block started on. - */ - public final int startLine; - - /** - * The line of the source this block ended on. - */ - public final int endLine; - - /** - * The number of this block. - */ - public final int blockNo; - - /** - * Create a new block. - * - * @param blockNo - * The number of this block. - * @param contents - * The contents of this block. - * @param startLine - * The line this block started on. - * @param endLine - * The line this block ended. - */ - public Block(int blockNo, String contents, int startLine, int endLine) { - this.contents = contents; - this.startLine = startLine; - this.endLine = endLine; - this.blockNo = blockNo; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - - result = prime * result + blockNo; - result = prime * result + ((contents == null) ? 0 : contents.hashCode()); - result = prime * result + endLine; - result = prime * result + startLine; - - return result; - } - - @Override - public boolean equals(Object obj) { - if(this == obj) return true; - if(obj == null) return false; - if(!(obj instanceof Block)) return false; - - Block other = (Block) obj; - - if(blockNo != other.blockNo) return false; - - if(contents == null) { - if(other.contents != null) return false; - } else if(!contents.equals(other.contents)) return false; - - if(endLine != other.endLine) return false; - if(startLine != other.startLine) return false; - - return true; - } - - @Override - public String toString() { - return String.format("Block #%d (from lines %d to %d) length: %d characters", blockNo, startLine, - endLine, contents.length()); - } - } - +public class BlockReader implements AutoCloseable, Iterator { /* * I/O source for blocks. */ @@ -131,10 +46,10 @@ public class BlockReader implements AutoCloseable { lnReader = new LineNumberReader(source); blockReader = new Scanner(lnReader); - + String pattern = String.format("(?:%s)|\\Z", blockDelim); Pattern pt = Pattern.compile(pattern, Pattern.MULTILINE); - + blockReader.useDelimiter(pt); } @@ -159,7 +74,7 @@ public class BlockReader implements AutoCloseable { /** * Move to the next block. * - * @return Whether or not the next block was succesfully read. + * @return Whether or not the next block was successfully read. */ public boolean nextBlock() { try { @@ -171,7 +86,7 @@ public class BlockReader implements AutoCloseable { currBlock = new Block(blockNo, blockContents, blockStartLine, blockEndLine); return true; - } catch(NoSuchElementException nseex) { + } catch (NoSuchElementException nseex) { return false; } } @@ -183,7 +98,7 @@ public class BlockReader implements AutoCloseable { * The action to execute for each block */ public void forEachBlock(Consumer action) { - while(hasNextBlock()) { + while (hasNextBlock()) { nextBlock(); action.accept(currBlock); @@ -205,4 +120,30 @@ public class BlockReader implements AutoCloseable { lnReader.close(); } + + /** + * Set the delimiter used to separate blocks. + * + * @param delim + * The delimiter used to separate blocks. + */ + public void setDelimiter(String delim) { + blockReader.useDelimiter(delim); + } + + /* + * Iterator implementation. + */ + + @Override + public boolean hasNext() { + return blockReader.hasNext(); + } + + @Override + public Block next() { + nextBlock(); + + return getBlock(); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/delims/RegexCloser.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/delims/RegexCloser.java index 9ec2353..dc94686 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/delims/RegexCloser.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/delims/RegexCloser.java @@ -2,9 +2,21 @@ package bjc.utils.parserutils.delims; import java.util.function.BiPredicate; +/** + * A predicated closer for use with {@link RegexOpener}. + * + * @author bjculkin + * + */ public class RegexCloser implements BiPredicate { private String rep; + /** + * Create a new regex closer. + * + * @param closer + * The format string to use for closing. + */ public RegexCloser(String closer) { rep = closer; } @@ -18,5 +30,4 @@ public class RegexCloser implements BiPredicate { return work.equals(closer); } - } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/delims/RegexOpener.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/delims/RegexOpener.java index c9965f2..7b4aac0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/delims/RegexOpener.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/delims/RegexOpener.java @@ -7,11 +7,26 @@ import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * A predicated opener for use with {@link RegexOpener} + * + * @author bjculkin + * + */ public class RegexOpener implements Function> { private String name; private Pattern patt; + /** + * Create a new regex opener. + * + * @param groupName + * The name of the opened group. + * + * @param groupRegex + * The regex that matches the opener. + */ public RegexOpener(String groupName, String groupRegex) { name = groupName; @@ -22,12 +37,12 @@ public class RegexOpener implements Function> { public IPair apply(String str) { Matcher m = patt.matcher(str); - if(m.matches()) { + if (m.matches()) { int numGroups = m.groupCount(); String[] parms = new String[numGroups + 1]; - for(int i = 0; i <= numGroups; i++) { + for (int i = 0; i <= numGroups; i++) { parms[i] = m.group(i); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/AbstractInitialCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/AbstractInitialCommand.java index b263422..3c3a89b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/AbstractInitialCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/AbstractInitialCommand.java @@ -6,14 +6,27 @@ import bjc.utils.parserutils.pratt.InitialCommand; import bjc.utils.parserutils.pratt.ParserContext; import bjc.utils.parserutils.pratt.Token; +/** + * Abstract base for initial commands. + * + * @author bjculkin + * + * @param + * The key type of the tokens. + * + * @param + * The value type of the tokens. + * + * @param + * The state type of the parser. + */ public abstract class AbstractInitialCommand implements InitialCommand { @Override - public ITree> denote(Token operator, ParserContext ctx) - throws ParserException { + public ITree> denote(Token operator, ParserContext ctx) throws ParserException { return intNullDenotation(operator, ctx); } - protected abstract ITree> intNullDenotation(Token operator, - ParserContext ctx) throws ParserException; + protected abstract ITree> intNullDenotation(Token operator, ParserContext ctx) + throws ParserException; } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryCommand.java index bf6786b..781309c 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/BinaryCommand.java @@ -6,16 +6,36 @@ import bjc.utils.parserutils.ParserException; import bjc.utils.parserutils.pratt.ParserContext; import bjc.utils.parserutils.pratt.Token; +/** + * A binary operator. + * + * @author bjculkin + * + * @param + * The key type of the tokens. + * + * @param + * The value type of the tokens. + * + * @param + * The state type of the parser. + */ public abstract class BinaryCommand extends BinaryPostCommand { - public BinaryCommand(int leftPower) { - super(leftPower); + /** + * Create a new binary operator with the specified precedence. + * + * @param precedence + * The precedence of the operator. + */ + public BinaryCommand(int precedence) { + super(precedence); } protected abstract int rightBinding(); @Override - public ITree> denote(ITree> operand, Token operator, - ParserContext ctx) throws ParserException { + public ITree> denote(ITree> operand, Token operator, ParserContext ctx) + throws ParserException { ITree> opr = ctx.parse.parseExpression(rightBinding(), ctx.tokens, ctx.state, false); return new Tree<>(operator, operand, opr); diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ChainCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ChainCommand.java index aa85f75..1324586 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ChainCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ChainCommand.java @@ -8,21 +8,47 @@ import bjc.utils.parserutils.pratt.Token; import java.util.Set; +/** + * Create a new chained operator. + * + * @author bjculkin + * + * @param + * The key type of the tokens. + * + * @param + * The value type of the tokens. + * + * @param + * The state type of the parser. + */ public class ChainCommand extends BinaryPostCommand { private Set chainWith; private Token chain; - public ChainCommand(int leftPower, Set chainSet, Token chainMarker) { - super(leftPower); + /** + * Create a new chained operator. + * + * @param precedence + * The precedence of this operator. + * + * @param chainSet + * The operators to chain with. + * + * @param chainMarker + * The token to use as the node in the AST. + */ + public ChainCommand(int precedence, Set chainSet, Token chainMarker) { + super(precedence); chainWith = chainSet; chain = chainMarker; } @Override - public ITree> denote(ITree> operand, Token operator, - ParserContext ctx) throws ParserException { + public ITree> denote(ITree> operand, Token operator, ParserContext ctx) + throws ParserException { ITree> tree = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state, false); ITree> res = new Tree<>(operator, operand, tree); diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ConstantCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ConstantCommand.java index 2308cc7..10ff184 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ConstantCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/ConstantCommand.java @@ -6,16 +6,35 @@ import bjc.utils.parserutils.pratt.InitialCommand; import bjc.utils.parserutils.pratt.ParserContext; import bjc.utils.parserutils.pratt.Token; +/** + * A command that represents a specific tree. + * + * @author bjculkin + * + * @param + * The key type of the tokens. + * + * @param + * The value type of the tokens. + * + * @param + * The state type of the parser. + */ public class ConstantCommand implements InitialCommand { private ITree> val; + /** + * Create a new constant. + * + * @param con + * The tree this constant represents. + */ public ConstantCommand(ITree> con) { val = con; } @Override - public ITree> denote(Token operator, ParserContext ctx) - throws ParserException { + public ITree> denote(Token operator, ParserContext ctx) throws ParserException { return val; } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultNonInitialCommand.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultNonInitialCommand.java index 8c500a9..887dd25 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultNonInitialCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/DefaultNonInitialCommand.java @@ -20,7 +20,6 @@ import bjc.utils.parserutils.pratt.Token; * The state type of the parser. */ public class DefaultNonInitialCommand extends NonInitialCommand { - @Override public ITree> denote(ITree> operand, Token operator, ParserContext ctx) { throw new UnsupportedOperationException("Default command has no left denotation"); @@ -30,5 +29,4 @@ public class DefaultNonInitialCommand extends NonInitialCommand - * The token key type. - * - * @param - * The token value type. - * - * @param - * The parser state type. - */ -public class InitialInterleaveCommand extends AbstractInitialCommand { - @Override - protected ITree> intNullDenotation(Token operator, ParserContext ctx) - throws ParserException { - return null; - } - -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InterleaveSpecifier.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InterleaveSpecifier.java deleted file mode 100644 index fa2c592..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/pratt/commands/InterleaveSpecifier.java +++ /dev/null @@ -1,30 +0,0 @@ -package bjc.utils.parserutils.pratt.commands; - -/** - * The specifier for what to do for each element of a command. - * - * @author EVE - * - */ -public class InterleaveSpecifier { - /** - * The type of this specifier. - * - * @author EVE - * - */ - public static enum Type { - /** - * Parse an expression with the given priority. - */ - EXPRESSION, - /** - * Parse a statement with the given priority. - */ - STATEMENT, - /** - * Expect a token of a certain type to be present. - */ - EXPECT, LITERAL; - } -} \ No newline at end of file -- cgit v1.2.3