summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/rgens/parser/elements
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bjc/rgens/parser/elements')
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/CaseElement.java50
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java6
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/RuleCaseElement.java10
-rw-r--r--src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java21
-rw-r--r--src/main/java/bjc/rgens/parser/elements/RuleVariableCaseElement.java8
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/elements/VariableCaseElement.java15
6 files changed, 38 insertions, 72 deletions
diff --git a/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/src/main/java/bjc/rgens/parser/elements/CaseElement.java
index d86d2d3..68f5368 100755
--- a/src/main/java/bjc/rgens/parser/elements/CaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/CaseElement.java
@@ -79,54 +79,20 @@ public abstract class CaseElement {
//System.out.printf("\t\tTRACE: special body is '%s'\n", specialBody);
- if (specialBody.matches("\\$\\S+:=\\S+")) {
- /* Handle expanding variable definitions. */
+ if (specialBody.matches("\\S+:=\\S+")) {
String[] parts = specialBody.split(":=");
-
- if (parts.length != 2) {
- String msg = "Expanded variables must be a name and a definition, seperated by :=";
-
- throw new GrammarException(msg);
- }
-
- /* Trim $ */
- return new ExpVariableCaseElement(parts[0].substring(1), parts[1]);
- } else if (specialBody.matches("\\$\\S+=\\S+")) {
- /* Handle regular variable definitions. */
- String[] parts = specialBody.split("=");
-
- if (parts.length != 2) {
- String msg = "Variables must be a name and a definition, seperated by =";
-
- throw new GrammarException(msg);
+ if(parts.length != 2) {
+ throw new GrammarException("Colon variables must have a name and a definition");
}
- /* Trim $ */
- return new LitVariableCaseElement(parts[0].substring(1), parts[1]);
- } else if (specialBody.matches("\\@\\S+:=\\S+")) {
- /* Handle exhaustible rule variable definitions. */
- String[] parts = specialBody.split(":=");
-
- if (parts.length != 2) {
- String msg = "Rule variables must be a name and a definition, seperated by =";
-
- throw new GrammarException(msg);
- }
-
- /* Trim $ */
- return new RuleVariableCaseElement(parts[0].substring(1), parts[1], true);
- } else if (specialBody.matches("\\@\\S+=\\S+")) {
- /* Handle rule variable definitions. */
+ return VariableCaseElement.parseVariable(parts[0], parts[1], true);
+ } else if (specialBody.matches("\\S+=\\S+")) {
String[] parts = specialBody.split("=");
-
- if (parts.length != 2) {
- String msg = "Rule variables must be a name and a definition, seperated by =";
-
- throw new GrammarException(msg);
+ if(parts.length != 2) {
+ throw new GrammarException("Variables must have a name and a definition");
}
- /* Trim $ */
- return new RuleVariableCaseElement(parts[0].substring(1), parts[1], false);
+ return VariableCaseElement.parseVariable(parts[0], parts[1], false);
} else if (specialBody.matches("empty")) {
/* Literal blank, for empty cases. */
return new BlankCaseElement();
diff --git a/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java
index ae85139..3972e7a 100755
--- a/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java
@@ -18,10 +18,10 @@ public class ExpVariableCaseElement extends VariableCaseElement {
public void generate(GenerationState state) {
GenerationState newState = state.newBuf();
- IPair<RGrammar, Rule> par = state.findRule(varDef, true);
+ Rule rl = state.findRule(varDef, true);
- if(par != null) {
- RGrammar destGrammar = par.getLeft();
+ if(rl != null) {
+ RGrammar destGrammar = rl.belongsTo;
newState.swapGrammar(destGrammar);
String res = destGrammar.generate(varDef, state);
diff --git a/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java
index 3e3d182..e0c847a 100755
--- a/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java
@@ -26,18 +26,18 @@ public abstract class RuleCaseElement extends StringCaseElement {
protected void doGenerate(String actName, GenerationState state) {
GenerationState newState = state.newBuf();
- IPair<RGrammar, Rule> par;
+ Rule rl;
if (actName.startsWith("[^")) {
actName = "[" + actName.substring(2);
- par = state.findImport(actName);
+ rl = state.findImport(actName);
} else {
- par = state.findRule(actName, true);
+ rl = state.findRule(actName, true);
}
- if(par != null) {
- RGrammar destGrammar = par.getLeft();
+ if(rl != null) {
+ RGrammar destGrammar = rl.belongsTo;
newState.swapGrammar(destGrammar);
String res = destGrammar.generate(actName, newState);
diff --git a/src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java
index a7be1bb..3192558 100644
--- a/src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java
@@ -19,29 +19,14 @@ public class RuleVarRefCaseElement extends StringCaseElement {
throw new GrammarException("No rule variable named " + val);
}
- IPair<RGrammar, Rule> par = state.rlVars.get(val);
+ Rule rl = state.rlVars.get(val);
GenerationState newState = state.newBuf();
- newState.swapGrammar(par.getLeft());
- if(par.getRight().doRecur()) {
- RuleCase cse = par.getRight().getCase(state.rnd);
- System.err.printf("\tFINE: Generating %s (from %s)\n", cse, par.getRight().name);
-
- par.getLeft().generateCase(cse, newState);
-
- par.getRight().endRecur();
- } else {
- throw new RecurLimitException("Rule recurrence limit exceeded");
- }
+ rl.generate(newState);
String res = newState.contents.toString();
- if (par.getRight().name.contains("+")) {
- /* Rule names with pluses in them get space-flattened */
- state.contents.append(res.replaceAll("\\s+", ""));
- } else {
- state.contents.append(res);
- }
+ state.contents.append(res);
}
}
diff --git a/src/main/java/bjc/rgens/parser/elements/RuleVariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RuleVariableCaseElement.java
index fa1783f..cbd8ce1 100644
--- a/src/main/java/bjc/rgens/parser/elements/RuleVariableCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/RuleVariableCaseElement.java
@@ -18,17 +18,17 @@ public class RuleVariableCaseElement extends VariableCaseElement {
}
public void generate(GenerationState state) {
- IPair<RGrammar, Rule> par = state.findRule(varDef, true);
+ Rule rl = state.findRule(varDef, true);
- if(par == null) {
+ if(rl == null) {
throw new GrammarException("Can't create variable referencing non-existent rule " + varDef);
}
if(exhaust) {
- par = new Pair<>(par.getLeft(), par.getRight().exhaust());
+ rl = rl.exhaust();
}
- state.rlVars.put(varName, par);
+ state.rlVars.put(varName, rl);
if(exhaust) {
System.err.printf("\t\tFINE: Defined exhausted rulevar '%s' ('%s')\n", varName, varDef);
diff --git a/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java
index 63abe16..a2c15a7 100755
--- a/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java
+++ b/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java
@@ -1,5 +1,7 @@
package bjc.rgens.parser.elements;
+import bjc.rgens.parser.GrammarException;
+
public abstract class VariableCaseElement extends CaseElement {
public static enum VariableType {
NORMAL,
@@ -66,4 +68,17 @@ public abstract class VariableCaseElement extends CaseElement {
return String.format("{$%s=%s}", varName, varDef);
}
}
+
+ public static CaseElement parseVariable(String varName, String varDef, boolean colon) {
+ if(varName.startsWith("$")) {
+ // Handle normal/expanding variable definitions
+ if(colon) return new ExpVariableCaseElement(varName.substring(1), varDef);
+
+ return new LitVariableCaseElement(varName.substring(1), varDef);
+ } else if(varName.startsWith("@")) {
+ return new RuleVariableCaseElement(varName.substring(1), varDef, colon);
+ } else {
+ throw new GrammarException("Unrecognized declaration sigil " + varName.charAt(0));
+ }
+ }
}