|
From: <cr...@us...> - 2009-06-07 04:58:48
|
Revision: 5543
http://jnode.svn.sourceforge.net/jnode/?rev=5543&view=rev
Author: crawley
Date: 2009-06-07 04:58:47 +0000 (Sun, 07 Jun 2009)
Log Message:
-----------
Adding 'eager' forms of the Powerset and Repeat syntaxes. (The latter is
not implemented yet.)
Modified Paths:
--------------
trunk/shell/src/shell/org/jnode/shell/syntax/OptionalSyntax.java
trunk/shell/src/shell/org/jnode/shell/syntax/PowersetSyntax.java
trunk/shell/src/shell/org/jnode/shell/syntax/RepeatSyntax.java
trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxSpecLoader.java
trunk/shell/src/test/org/jnode/test/shell/syntax/PowersetSyntaxTest.java
Modified: trunk/shell/src/shell/org/jnode/shell/syntax/OptionalSyntax.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/syntax/OptionalSyntax.java 2009-06-03 14:47:18 UTC (rev 5542)
+++ trunk/shell/src/shell/org/jnode/shell/syntax/OptionalSyntax.java 2009-06-07 04:58:47 UTC (rev 5543)
@@ -43,11 +43,11 @@
}
public OptionalSyntax(String label, Syntax...syntaxes) {
- this(label, null, syntaxes);
+ this(label, null, false, syntaxes);
}
public OptionalSyntax(Syntax...syntaxes) {
- this(null, null, syntaxes);
+ this(null, null, false, syntaxes);
}
@Override
Modified: trunk/shell/src/shell/org/jnode/shell/syntax/PowersetSyntax.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/syntax/PowersetSyntax.java 2009-06-03 14:47:18 UTC (rev 5542)
+++ trunk/shell/src/shell/org/jnode/shell/syntax/PowersetSyntax.java 2009-06-07 04:58:47 UTC (rev 5543)
@@ -28,21 +28,26 @@
* The syntax allows a child syntax to appear more than once, subject to Argument
* multiplicity constraints. As with an Alternatives, the child syntaxes are tried
* one at a time in the same order as the they were provided to the constructor.
+ * The 'eager' parameter specifies whether the syntax is 'eager' (i.e. matching as
+ * many instances as possible) or 'lazy' (i.e. matching as few instances as possible).
*
* @author cr...@jn...
*/
public class PowersetSyntax extends GroupSyntax {
- public PowersetSyntax(String label, String description, Syntax...syntaxes) {
+ private final boolean eager;
+
+ public PowersetSyntax(String label, boolean eager, String description, Syntax...syntaxes) {
super(label, description, syntaxes);
+ this.eager = eager;
}
public PowersetSyntax(String label, Syntax...syntaxes) {
- this(label, null, syntaxes);
+ this(label, false, null, syntaxes);
}
public PowersetSyntax(Syntax...syntaxes) {
- this(null, null, syntaxes);
+ this(null, false, null, syntaxes);
}
@Override
@@ -58,9 +63,17 @@
childMuSyntaxes[i] = children[i].prepare(bundle);
}
String label = this.label == null ? MuSyntax.genLabel() : this.label;
- MuSyntax res = new MuAlternation(label, null,
- new MuSequence(new MuAlternation((String) null, childMuSyntaxes),
- new MuBackReference(label)));
+ MuSyntax res;
+ if (eager) {
+ res = new MuAlternation(label,
+ new MuSequence(new MuAlternation((String) null, childMuSyntaxes),
+ new MuBackReference(label)),
+ null);
+ } else {
+ res = new MuAlternation(label, null,
+ new MuSequence(new MuAlternation((String) null, childMuSyntaxes),
+ new MuBackReference(label)));
+ }
res.resolveBackReferences();
return res;
}
@@ -89,6 +102,10 @@
@Override
public XMLElement toXML() {
- return basicElement("powerSet");
+ XMLElement element = basicElement("powerSet");
+ if (eager) {
+ element.setAttribute("eager", "true");
+ }
+ return element;
}
}
Modified: trunk/shell/src/shell/org/jnode/shell/syntax/RepeatSyntax.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/syntax/RepeatSyntax.java 2009-06-03 14:47:18 UTC (rev 5542)
+++ trunk/shell/src/shell/org/jnode/shell/syntax/RepeatSyntax.java 2009-06-07 04:58:47 UTC (rev 5543)
@@ -24,8 +24,11 @@
/**
- * A RepeatedSyntax instance specifies that a given 'child' syntax may appear
- * some number of times.
+ * A RepeatedSyntax instance specifies that a given 'child' syntax may be repeated
+ * a number of times as determined by the constructor arguments. These allow you
+ * to specify a minimum and/or maximum bound on the number of repetitions, and to
+ * specify whether the syntax is 'eager' (i.e. matching as many instances as possible) or
+ * 'lazy' (i.e. matching as few instances as possible).
*
* @author cr...@jn...
*/
@@ -34,6 +37,7 @@
private final Syntax child;
private final int minCount;
private final int maxCount;
+ private final boolean eager;
/**
* Construct syntax with caller-specified repetition count range and a label.
@@ -42,9 +46,12 @@
* @param child the child Syntax that may be repeated.
* @param minCount the minimum number of occurrences required.
* @param maxCount the maximum number of occurrences allowed.
+ * @param eager if {@code true}, the syntax matches as many child instances
+ * as possible, subject to the 'maxCount' constraint.
* @param description the description for this syntax
*/
- public RepeatSyntax(String label, Syntax child, int minCount, int maxCount, String description) {
+ public RepeatSyntax(String label, Syntax child, int minCount, int maxCount,
+ boolean eager, String description) {
super(label, description, child);
if (minCount < 0 || maxCount < minCount) {
throw new IllegalArgumentException("bad min/max counts");
@@ -52,6 +59,7 @@
this.child = child;
this.minCount = minCount;
this.maxCount = maxCount;
+ this.eager = eager;
}
/**
@@ -63,7 +71,7 @@
* @param maxCount the maximum number of occurrences allowed.
*/
public RepeatSyntax(String label, Syntax child, int minCount, int maxCount) {
- this(label, child, minCount, maxCount, null);
+ this(label, child, minCount, maxCount, false, null);
}
/**
@@ -74,7 +82,7 @@
* @param maxCount the maximum number of occurrences allowed.
*/
public RepeatSyntax(Syntax child, int minCount, int maxCount) {
- this(null, child, minCount, maxCount, null);
+ this(null, child, minCount, maxCount, false, null);
}
/**
@@ -83,7 +91,7 @@
* @param child the child Syntax that may be repeated.
*/
public RepeatSyntax(Syntax child) {
- this(null, child, 0, Integer.MAX_VALUE, null);
+ this(null, child, 0, Integer.MAX_VALUE, false, null);
}
@Override
@@ -170,6 +178,9 @@
if (maxCount != Integer.MAX_VALUE) {
element.setAttribute("maxCount", maxCount);
}
+ if (eager) {
+ element.setAttribute("eager", "true");
+ }
return element;
}
Modified: trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxSpecLoader.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxSpecLoader.java 2009-06-03 14:47:18 UTC (rev 5542)
+++ trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxSpecLoader.java 2009-06-07 04:58:47 UTC (rev 5543)
@@ -100,13 +100,15 @@
}
} else if (kind.equals("powerset")) {
int nos = syntaxElement.getNosChildren();
+ boolean eager = getFlag(syntaxElement, "eager", false);
Syntax[] members = new Syntax[nos];
for (int i = 0; i < nos; i++) {
members[i] = doLoad(syntaxElement.getChild(i));
}
- return new PowersetSyntax(label, description, members);
+ return new PowersetSyntax(label, eager, description, members);
} else if (kind.equals("repeat")) {
int nos = syntaxElement.getNosChildren();
+ boolean eager = getFlag(syntaxElement, "eager", false);
int minCount = getCount(syntaxElement, "minCount", 0);
int maxCount = getCount(syntaxElement, "maxCount", Integer.MAX_VALUE);
Syntax[] members = new Syntax[nos];
@@ -114,7 +116,7 @@
members[i] = doLoad(syntaxElement.getChild(i));
}
Syntax childSyntax = (members.length == 1) ? members[0] : new SequenceSyntax(members);
- return new RepeatSyntax(label, childSyntax, minCount, maxCount, description);
+ return new RepeatSyntax(label, childSyntax, minCount, maxCount, eager, description);
} else if (kind.equals("sequence")) {
int nos = syntaxElement.getNosChildren();
Syntax[] seq = new Syntax[nos];
Modified: trunk/shell/src/test/org/jnode/test/shell/syntax/PowersetSyntaxTest.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/syntax/PowersetSyntaxTest.java 2009-06-03 14:47:18 UTC (rev 5542)
+++ trunk/shell/src/test/org/jnode/test/shell/syntax/PowersetSyntaxTest.java 2009-06-07 04:58:47 UTC (rev 5543)
@@ -34,6 +34,9 @@
import org.jnode.shell.syntax.IntegerArgument;
import org.jnode.shell.syntax.OptionSyntax;
import org.jnode.shell.syntax.PowersetSyntax;
+import org.jnode.shell.syntax.RepeatSyntax;
+import org.jnode.shell.syntax.SequenceSyntax;
+import org.jnode.shell.syntax.StringArgument;
import org.jnode.shell.syntax.Syntax;
public class PowersetSyntaxTest extends TestCase {
@@ -43,9 +46,11 @@
new FileArgument("fileArg", Argument.OPTIONAL + Argument.MULTIPLE);
private final IntegerArgument intArg =
new IntegerArgument("intArg", Argument.OPTIONAL + Argument.MULTIPLE);
+ private final StringArgument otherArg =
+ new StringArgument("otherArg", Argument.OPTIONAL + Argument.MULTIPLE);
public Test() {
- registerArguments(fileArg, intArg);
+ registerArguments(fileArg, intArg, otherArg);
}
public void execute() throws Exception {
@@ -116,4 +121,129 @@
// expected
}
}
+
+ public void testLazy() throws Exception {
+ TestShell shell = new TestShell();
+ shell.addAlias("cmd", "org.jnode.test.shell.syntax.PowersetSyntaxTest$Test");
+ shell.addSyntax("cmd", new SequenceSyntax(
+ new PowersetSyntax(
+ new OptionSyntax("intArg", 'i'),
+ new OptionSyntax("fileArg", 'f')),
+ new RepeatSyntax(new OptionSyntax("otherArg", 'i'))));
+
+ CommandLine cl;
+ CommandInfo cmdInfo;
+ Command cmd;
+
+ cl = new CommandLine(new Token("cmd"), new Token[]{}, null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(0, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+
+ cl = new CommandLine(new Token("cmd"), new Token[]{new Token("-f"), new Token("F1")}, null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(1, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+ assertEquals("F1", cmd.getArgumentBundle().getArgument("fileArg").getValue().toString());
+
+ cl = new CommandLine(new Token("cmd"),
+ new Token[]{new Token("-f"), new Token("F1"), new Token("-i"), new Token("1")}, null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(1, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(1, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+ assertEquals("F1", cmd.getArgumentBundle().getArgument("fileArg").getValue().toString());
+ assertEquals("1", cmd.getArgumentBundle().getArgument("otherArg").getValue().toString());
+
+ cl = new CommandLine(new Token("cmd"),
+ new Token[]{new Token("-i"), new Token("1"), new Token("-f"), new Token("F1")}, null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(1, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(1, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+ assertEquals("F1", cmd.getArgumentBundle().getArgument("fileArg").getValue().toString());
+ assertEquals("1", cmd.getArgumentBundle().getArgument("intArg").getValue().toString());
+
+ cl = new CommandLine(new Token("cmd"),
+ new Token[]{
+ new Token("-i"), new Token("1"), new Token("-f"), new Token("F1"),
+ new Token("-i"), new Token("2")},
+ null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(1, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(1, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(1, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+ assertEquals("F1", cmd.getArgumentBundle().getArgument("fileArg").getValue().toString());
+ assertEquals("1", cmd.getArgumentBundle().getArgument("intArg").getValue().toString());
+ assertEquals("2", cmd.getArgumentBundle().getArgument("otherArg").getValue().toString());
+ }
+
+
+
+ public void testEager() throws Exception {
+ TestShell shell = new TestShell();
+ shell.addAlias("cmd", "org.jnode.test.shell.syntax.PowersetSyntaxTest$Test");
+ shell.addSyntax("cmd", new SequenceSyntax(
+ new PowersetSyntax(null, true, null,
+ new OptionSyntax("intArg", 'i'),
+ new OptionSyntax("fileArg", 'f')),
+ new RepeatSyntax(new OptionSyntax("otherArg", 'i'))));
+
+ CommandLine cl;
+ CommandInfo cmdInfo;
+ Command cmd;
+
+ cl = new CommandLine(new Token("cmd"), new Token[]{}, null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(0, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+
+ cl = new CommandLine(new Token("cmd"), new Token[]{new Token("-f"), new Token("F1")}, null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(1, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+ assertEquals("F1", cmd.getArgumentBundle().getArgument("fileArg").getValue().toString());
+
+ cl = new CommandLine(new Token("cmd"),
+ new Token[]{new Token("-f"), new Token("F1"), new Token("-i"), new Token("1")}, null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(1, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(1, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+ assertEquals("F1", cmd.getArgumentBundle().getArgument("fileArg").getValue().toString());
+ assertEquals("1", cmd.getArgumentBundle().getArgument("intArg").getValue().toString());
+
+ cl = new CommandLine(new Token("cmd"),
+ new Token[]{new Token("-i"), new Token("1"), new Token("-f"), new Token("F1")}, null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(1, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(1, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+ assertEquals("F1", cmd.getArgumentBundle().getArgument("fileArg").getValue().toString());
+ assertEquals("1", cmd.getArgumentBundle().getArgument("intArg").getValue().toString());
+
+ cl = new CommandLine(new Token("cmd"),
+ new Token[]{
+ new Token("-i"), new Token("1"), new Token("-f"), new Token("F1"),
+ new Token("-i"), new Token("2")},
+ null);
+ cmdInfo = cl.parseCommandLine(shell);
+ cmd = cmdInfo.createCommandInstance();
+ assertEquals(1, cmd.getArgumentBundle().getArgument("fileArg").getValues().length);
+ assertEquals(2, cmd.getArgumentBundle().getArgument("intArg").getValues().length);
+ assertEquals(0, cmd.getArgumentBundle().getArgument("otherArg").getValues().length);
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|