From 05c9922b30cd0dcd2a452673c2e155215d074b19 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Tue, 5 Jun 2018 22:09:23 -0300 Subject: Templates pt. 3 Templates should now work, though there is no syntax to reference them from rules yet In addition, several internal things have been changed so as to improve code quality --- .../bjc/rgens/parser/elements/CaseElement.java | 50 ++++------------------ .../parser/elements/ExpVariableCaseElement.java | 6 +-- .../bjc/rgens/parser/elements/RuleCaseElement.java | 10 ++--- .../parser/elements/RuleVarRefCaseElement.java | 21 ++------- .../parser/elements/RuleVariableCaseElement.java | 8 ++-- .../rgens/parser/elements/VariableCaseElement.java | 15 +++++++ 6 files changed, 38 insertions(+), 72 deletions(-) (limited to 'src/main/java/bjc/rgens/parser/elements') 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 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 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 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 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)); + } + } } -- cgit v1.2.3