From 33a165f0b0055d2bdf9a1fcaa639b31a7f87d9a6 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Fri, 8 Jun 2018 19:06:14 -0300 Subject: Major refactoring A major refactoring to the internals of how things work. I believe that nothing is broken --- src/main/java/bjc/rgens/parser/RGrammar.java | 6 +- .../rgens/parser/elements/BlankCaseElement.java | 2 + .../bjc/rgens/parser/elements/CaseElement.java | 61 ++++++++++-------- .../parser/elements/DependantRuleReference.java | 48 -------------- .../parser/elements/ExpVariableCaseElement.java | 4 +- .../parser/elements/InlineRuleCaseElement.java | 2 +- .../parser/elements/LitVariableCaseElement.java | 4 +- .../rgens/parser/elements/LiteralCaseElement.java | 11 ++-- .../rgens/parser/elements/NormalRuleReference.java | 18 ------ .../bjc/rgens/parser/elements/RuleCaseElement.java | 41 +++++++++--- .../parser/elements/RuleVarRefCaseElement.java | 32 --------- .../parser/elements/RuleVariableCaseElement.java | 4 +- .../rgens/parser/elements/StringCaseElement.java | 2 +- .../rgens/parser/elements/VariableCaseElement.java | 75 ---------------------- .../parser/elements/VariableDefCaseElement.java | 66 +++++++++++++++++++ .../parser/elements/VariableRuleReference.java | 31 --------- .../parser/elements/vars/ARefVariableElement.java | 8 +-- .../elements/vars/LiteralVariableElement.java | 4 +- .../parser/elements/vars/RRefVariableElement.java | 8 +-- .../parser/elements/vars/TRefVariableElement.java | 7 +- .../parser/elements/vars/VRefVariableElement.java | 6 +- .../parser/elements/vars/VariableElement.java | 30 ++++++--- 22 files changed, 185 insertions(+), 285 deletions(-) delete mode 100644 src/main/java/bjc/rgens/parser/elements/DependantRuleReference.java mode change 100755 => 100644 src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java delete mode 100644 src/main/java/bjc/rgens/parser/elements/NormalRuleReference.java delete mode 100644 src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java delete mode 100755 src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java create mode 100755 src/main/java/bjc/rgens/parser/elements/VariableDefCaseElement.java delete mode 100644 src/main/java/bjc/rgens/parser/elements/VariableRuleReference.java (limited to 'src/main/java/bjc') diff --git a/src/main/java/bjc/rgens/parser/RGrammar.java b/src/main/java/bjc/rgens/parser/RGrammar.java index e537781..337ab35 100755 --- a/src/main/java/bjc/rgens/parser/RGrammar.java +++ b/src/main/java/bjc/rgens/parser/RGrammar.java @@ -4,11 +4,7 @@ import bjc.utils.data.IPair; import bjc.utils.data.Pair; import bjc.utils.funcutils.StringUtils; -import bjc.rgens.parser.elements.CaseElement; -import bjc.rgens.parser.elements.LiteralCaseElement; -import bjc.rgens.parser.elements.RangeCaseElement; -import bjc.rgens.parser.elements.RuleCaseElement; -import bjc.rgens.parser.elements.VariableCaseElement; +import bjc.rgens.parser.elements.*; import java.util.Arrays; import java.util.ArrayList; diff --git a/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java b/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java index 7229e92..66ff310 100755 --- a/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/BlankCaseElement.java @@ -1,5 +1,7 @@ package bjc.rgens.parser.elements; +import bjc.rgens.parser.GenerationState; + public class BlankCaseElement extends LiteralCaseElement { public BlankCaseElement() { super(""); diff --git a/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/src/main/java/bjc/rgens/parser/elements/CaseElement.java index d799dbe..a44ef6c 100755 --- a/src/main/java/bjc/rgens/parser/elements/CaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/CaseElement.java @@ -71,27 +71,52 @@ public abstract class CaseElement { throw new NullPointerException("Case part cannot be null"); } - if (csepart.matches("\\{\\S+\\}")) { + if (csepart.matches("\\(\\S+\\)")) { + return createElement(csepart.substring(1, csepart.length() - 1)); + } else if (csepart.matches("\\{\\S+\\}")) { /* * Handle special case elements. * */ String specialBody = csepart.substring(1, csepart.length() - 1); - if (specialBody.matches("\\S+:=\\S+")) { - String[] parts = specialBody.split(":="); + if (specialBody.matches("\\S+:\\S=\\S+")) { + String[] parts = StringUtils.levelSplit(specialBody, "=").toArray(new String[0]); + if(parts.length != 2) { throw new GrammarException("Colon variables must have a name and a definition"); } - return VariableCaseElement.parseVariable(parts[0], parts[1], true); + String varName = parts[0]; + + char op = varName.charAt(varName.length() - 1); + + System.err.printf("\t\tTRACE: Colon definition w/ op %d", (int)op); + + // Remove the colon, plus any tacked on operator + varName = varName.substring(0, varName.length() - 2); + + return VariableDefCaseElement.parseVariable(varName, parts[1], op, true); + } else if (specialBody.matches("\\S+:=\\S+")) { + String[] parts = StringUtils.levelSplit(specialBody, "=").toArray(new String[0]); + + if(parts.length != 2) { + throw new GrammarException("Colon variables must have a name and a definition"); + } + + String varName = parts[0]; + + varName = varName.substring(0, varName.length() - 1); + + return VariableDefCaseElement.parseVariable(varName, parts[1], ' ', true); } else if (specialBody.matches("\\S+=\\S+")) { String[] parts = specialBody.split("="); if(parts.length != 2) { throw new GrammarException("Variables must have a name and a definition"); } - return VariableCaseElement.parseVariable(parts[0], parts[1], false); + // Non-colon variables can't take an operator + return VariableDefCaseElement.parseVariable(parts[0], parts[1], (char)0, false); } else if (specialBody.matches("empty")) { /* Literal blank, for empty cases. */ return new BlankCaseElement(); @@ -101,39 +126,25 @@ public abstract class CaseElement { } else if (csepart.matches("\\[\\S+\\]")) { String rawCase = csepart.substring(1, csepart.length() - 1); - if (rawCase.matches("\\d+\\.\\.\\d+")) { + if (rawCase.matches("\\d+\\.{2}\\d+")) { int firstNum = Integer.parseInt(rawCase.substring(0, rawCase.indexOf('.'))); int secondNum = Integer.parseInt(rawCase.substring(rawCase.lastIndexOf('.') + 1)); return new RangeCaseElement(firstNum, secondNum); } else if(rawCase.contains("||")) { String[] elms = StringUtils.levelSplit(rawCase, "||").toArray(new String[0]); - //String[] elms = rawCase.split("\\|\\|"); return new InlineRuleCaseElement(elms); } else if(rawCase.contains("|")) { - System.err.println("\t\tWARN: Inline rule using | found, they use || now"); - - String[] elms = StringUtils.levelSplit(rawCase, "|").toArray(new String[0]); - return new InlineRuleCaseElement(elms); - } else if(csepart.contains("$")) { - if(csepart.contains("-")) { - return new DependantRuleReference(csepart); - } + throw new GrammarException("\t\tERROR: Inline rule using | found, they use || now"); - return new VariableRuleReference(csepart); - } else if(csepart.contains("@")) { - // Trim @ - return new RuleVarRefCaseElement(rawCase.substring(1)); + // String[] elms = StringUtils.levelSplit(rawCase, "|").toArray(new String[0]); + // return new InlineRuleCaseElement(elms); } else { - return new NormalRuleReference(csepart); + return new RuleCaseElement(rawCase); } } else if(csepart.startsWith("%") && !csepart.equals("%")) { - String rName = String.format("[%s]", csepart.substring(1)); - - System.err.printf("\t\tTRACE: short ref to %s (%s)\n", rName, csepart); - - return new NormalRuleReference(rName); + return new RuleCaseElement(csepart); } else { return new LiteralCaseElement(csepart); } diff --git a/src/main/java/bjc/rgens/parser/elements/DependantRuleReference.java b/src/main/java/bjc/rgens/parser/elements/DependantRuleReference.java deleted file mode 100644 index 5eccf8e..0000000 --- a/src/main/java/bjc/rgens/parser/elements/DependantRuleReference.java +++ /dev/null @@ -1,48 +0,0 @@ -package bjc.rgens.parser.elements; - -import bjc.rgens.parser.GrammarException; -import bjc.rgens.parser.GenerationState; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class DependantRuleReference extends RuleCaseElement { - private static Pattern NAMEVAR_PATTERN = Pattern.compile("\\$(\\w+)"); - - public DependantRuleReference(String vl) { - super(vl, ReferenceType.DEPENDENT); - } - - @Override - public void generate(GenerationState state) { - String refBody = val.substring(1, val.length() - 1); - - /* Handle dependent rule names. */ - StringBuffer nameBuffer = new StringBuffer(); - - Matcher nameMatcher = NAMEVAR_PATTERN.matcher(refBody); - - while (nameMatcher.find()) { - String var = nameMatcher.group(1); - - if (!state.vars.containsKey(var)) { - String msg = String.format("No variable '%s' defined", var); - throw new GrammarException(msg); - } - - String name = state.vars.get(var); - - if (name.contains(" ")) { - throw new GrammarException("Variables substituted into names cannot contain spaces"); - } else if (name.equals("")) { - throw new GrammarException("Variables substituted into names cannot be empty"); - } - - nameMatcher.appendReplacement(nameBuffer, name); - } - - nameMatcher.appendTail(nameBuffer); - - doGenerate(String.format("[%s]", nameBuffer.toString()), state); - } -} diff --git a/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java index 198b0db..e58d073 100755 --- a/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/ExpVariableCaseElement.java @@ -9,9 +9,9 @@ import bjc.rgens.parser.RGrammar; import bjc.rgens.parser.Rule; import bjc.rgens.parser.RuleCase; -public class ExpVariableCaseElement extends VariableCaseElement { +public class ExpVariableCaseElement extends VariableDefCaseElement { public ExpVariableCaseElement(String name, String def) { - super(name, def, VariableType.EXPAND); + super(name, def); } @Override diff --git a/src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java b/src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java index ea22bb4..12b6f14 100644 --- a/src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/InlineRuleCaseElement.java @@ -28,7 +28,7 @@ public class InlineRuleCaseElement extends CaseElement { IPair, Integer> par = RGrammarParser.parseElementString(partArr); int prob = par.getRight(); - for(CaseElement elm :par.getLeft()) { + for(CaseElement elm : par.getLeft()) { elements.addProbability(prob, elm); } } diff --git a/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java index cd44ccb..3c6ba98 100755 --- a/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/LitVariableCaseElement.java @@ -2,9 +2,9 @@ package bjc.rgens.parser.elements; import bjc.rgens.parser.GenerationState; -public class LitVariableCaseElement extends VariableCaseElement { +public class LitVariableCaseElement extends VariableDefCaseElement { public LitVariableCaseElement(String name, String def) { - super(name, def, VariableType.NORMAL); + super(name, def); } public void generate(GenerationState state) { diff --git a/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java b/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java old mode 100755 new mode 100644 index 18c3482..6e0f8fd --- a/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/LiteralCaseElement.java @@ -2,12 +2,15 @@ package bjc.rgens.parser.elements; import bjc.rgens.parser.GenerationState; -public class LiteralCaseElement extends StringCaseElement { - public LiteralCaseElement(String vl) { - super(vl, true); +public class LiteralCaseElement extends CaseElement { + public String val; + + public LiteralCaseElement(String val) { + super(true); + + this.val = val; } - @Override public void generate(GenerationState state) { state.contents.append(val); } diff --git a/src/main/java/bjc/rgens/parser/elements/NormalRuleReference.java b/src/main/java/bjc/rgens/parser/elements/NormalRuleReference.java deleted file mode 100644 index 68553c2..0000000 --- a/src/main/java/bjc/rgens/parser/elements/NormalRuleReference.java +++ /dev/null @@ -1,18 +0,0 @@ -package bjc.rgens.parser.elements; - -import bjc.rgens.parser.GenerationState; - -public class NormalRuleReference extends RuleCaseElement { - public NormalRuleReference(String vl) { - super(vl, ReferenceType.NORMAL); - } - - @Override - public void generate(GenerationState state) { - String refersTo = val; - - GenerationState newState = state.newBuf(); - - doGenerate(refersTo, state); - } -} diff --git a/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java index 6aa50fc..f13dbdb 100755 --- a/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java @@ -4,23 +4,46 @@ import bjc.utils.data.IPair; import bjc.utils.data.Pair; import bjc.rgens.parser.*; +import bjc.rgens.parser.elements.vars.*; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -public abstract class RuleCaseElement extends StringCaseElement { - public static enum ReferenceType { - DEPENDENT, - VARIABLE, - NORMAL +public class RuleCaseElement extends CaseElement { + public List elements; + + public RuleCaseElement(String vl) { + super(true); + + this.elements = VariableElement.parseElementString(vl); + } + + public RuleCaseElement(String vl, List elements) { + super(true); + + this.elements = elements; } - public final ReferenceType ref; + public void generate(GenerationState state) { + GenerationState newState = state.newBuf(); + + boolean inName = false; + + for(VariableElement elm : elements) { + elm.generate(newState); + + if(inName == false) inName = elm.forbidSpaces; + } - protected RuleCaseElement(String vl, ReferenceType ref) { - super(vl, false); + String body = newState.contents.toString(); - this.ref = ref; + if(inName) { + doGenerate(String.format("[%s]", body), state); + } else { + state.contents.append(body); + } } protected void doGenerate(String actName, GenerationState state) { diff --git a/src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java b/src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java deleted file mode 100644 index 3192558..0000000 --- a/src/main/java/bjc/rgens/parser/elements/RuleVarRefCaseElement.java +++ /dev/null @@ -1,32 +0,0 @@ -package bjc.rgens.parser.elements; - -import bjc.utils.data.IPair; - -import bjc.rgens.parser.GenerationState; -import bjc.rgens.parser.GrammarException; -import bjc.rgens.parser.RecurLimitException; -import bjc.rgens.parser.RGrammar; -import bjc.rgens.parser.Rule; -import bjc.rgens.parser.RuleCase; - -public class RuleVarRefCaseElement extends StringCaseElement { - public RuleVarRefCaseElement(String vl) { - super(vl, false); - } - - public void generate(GenerationState state) { - if(!state.rlVars.containsKey(val)) { - throw new GrammarException("No rule variable named " + val); - } - - Rule rl = state.rlVars.get(val); - - GenerationState newState = state.newBuf(); - - rl.generate(newState); - - String res = newState.contents.toString(); - - 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 cbd8ce1..29b6fc9 100644 --- a/src/main/java/bjc/rgens/parser/elements/RuleVariableCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/RuleVariableCaseElement.java @@ -8,11 +8,11 @@ import bjc.rgens.parser.GenerationState; import bjc.rgens.parser.Rule; import bjc.rgens.parser.RGrammar; -public class RuleVariableCaseElement extends VariableCaseElement { +public class RuleVariableCaseElement extends VariableDefCaseElement { public final boolean exhaust; public RuleVariableCaseElement(String varName, String varDef, boolean exhaust) { - super(varName, varDef, VariableType.RULE); + super(varName, varDef); this.exhaust = exhaust; } diff --git a/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java b/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java index 57e2cc7..00441c0 100755 --- a/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/StringCaseElement.java @@ -3,7 +3,7 @@ package bjc.rgens.parser.elements; public abstract class StringCaseElement extends CaseElement { public final String val; - protected StringCaseElement(String vl, boolean isLiteral) { + protected StringCaseElement(String vl) { super(true); val = vl; diff --git a/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java b/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java deleted file mode 100755 index 63701e0..0000000 --- a/src/main/java/bjc/rgens/parser/elements/VariableCaseElement.java +++ /dev/null @@ -1,75 +0,0 @@ -package bjc.rgens.parser.elements; - -import bjc.rgens.parser.GrammarException; - -public abstract class VariableCaseElement extends CaseElement { - public static enum VariableType { - NORMAL, - EXPAND, - RULE - } - /** - * The name of the variable this element defines. - */ - public final String varName; - - /** - * The definition of the variable this element defines. - */ - public final String varDef; - - public final VariableType varType; - - public VariableCaseElement(String name, String def, VariableType varType) { - super(false); - - varName = name; - varDef = def; - - this.varType = varType; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((varDef == null) ? 0 : varDef.hashCode()); - result = prime * result + ((varName == null) ? 0 : varName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - VariableCaseElement other = (VariableCaseElement) obj; - if (varDef == null) { - if (other.varDef != null) - return false; - } else if (!varDef.equals(other.varDef)) - return false; - if (varName == null) { - if (other.varName != null) - return false; - } else if (!varName.equals(other.varName)) - return false; - return true; - } - - 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)); - } - } -} diff --git a/src/main/java/bjc/rgens/parser/elements/VariableDefCaseElement.java b/src/main/java/bjc/rgens/parser/elements/VariableDefCaseElement.java new file mode 100755 index 0000000..37a12b6 --- /dev/null +++ b/src/main/java/bjc/rgens/parser/elements/VariableDefCaseElement.java @@ -0,0 +1,66 @@ +package bjc.rgens.parser.elements; + +import bjc.rgens.parser.GrammarException; + +public abstract class VariableDefCaseElement extends CaseElement { + /** + * The name of the variable this element defines. + */ + public final String varName; + + /** + * The definition of the variable this element defines. + */ + public final String varDef; + + public VariableDefCaseElement(String name, String def) { + super(false); + + varName = name; + varDef = def; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((varDef == null) ? 0 : varDef.hashCode()); + result = prime * result + ((varName == null) ? 0 : varName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + VariableDefCaseElement other = (VariableDefCaseElement) obj; + if (varDef == null) { + if (other.varDef != null) + return false; + } else if (!varDef.equals(other.varDef)) + return false; + if (varName == null) { + if (other.varName != null) + return false; + } else if (!varName.equals(other.varName)) + return false; + return true; + } + + public static CaseElement parseVariable(String varName, String varDef, char op, 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)); + } + } +} diff --git a/src/main/java/bjc/rgens/parser/elements/VariableRuleReference.java b/src/main/java/bjc/rgens/parser/elements/VariableRuleReference.java deleted file mode 100644 index bebb9f7..0000000 --- a/src/main/java/bjc/rgens/parser/elements/VariableRuleReference.java +++ /dev/null @@ -1,31 +0,0 @@ -package bjc.rgens.parser.elements; - -import bjc.rgens.parser.GrammarException; -import bjc.rgens.parser.GenerationState; - -public class VariableRuleReference extends RuleCaseElement { - public VariableRuleReference(String vl) { - super(vl, ReferenceType.VARIABLE); - } - - public void generate(GenerationState state) { - String refBody = val.substring(1, val.length() - 1); - - /* Handle string references. */ - if (refBody.equals("$")) { - throw new GrammarException("Cannot refer to unnamed variables"); - } - - String key = refBody.substring(1); - - if (!state.vars.containsKey(key)) { - String msg = String.format("No variable '%s' defined", key); - - throw new GrammarException(msg); - } - - state.contents.append(state.vars.get(key)); - - return; - } -} diff --git a/src/main/java/bjc/rgens/parser/elements/vars/ARefVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/ARefVariableElement.java index 7a8910c..a4bb730 100644 --- a/src/main/java/bjc/rgens/parser/elements/vars/ARefVariableElement.java +++ b/src/main/java/bjc/rgens/parser/elements/vars/ARefVariableElement.java @@ -7,9 +7,9 @@ import bjc.rgens.parser.Rule; public class ARefVariableElement extends VariableElement { public String value; - private boolean forbidSpaces; + public ARefVariableElement(String val) { + super(false); - public ARefVariableElement(boolean forbidSpaces, String val) { value = val; } @@ -26,10 +26,6 @@ public class ARefVariableElement extends VariableElement { String res = newState.contents.toString(); - if(forbidSpaces && res.contains(" ")) { - throw new GrammarException("Spaces not allowed in this context (rule-var %s)"); - } - state.contents.append(res); } } diff --git a/src/main/java/bjc/rgens/parser/elements/vars/LiteralVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/LiteralVariableElement.java index 080f849..cf33c66 100644 --- a/src/main/java/bjc/rgens/parser/elements/vars/LiteralVariableElement.java +++ b/src/main/java/bjc/rgens/parser/elements/vars/LiteralVariableElement.java @@ -5,7 +5,9 @@ import bjc.rgens.parser.GenerationState; public class LiteralVariableElement extends VariableElement { public String val; - public LiteralVariableElement(String val) { + public LiteralVariableElement(boolean forbidSpaces, String val) { + super(forbidSpaces); + this.val = val; } diff --git a/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java index 6bf332f..d731d64 100644 --- a/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java +++ b/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java @@ -7,17 +7,13 @@ import bjc.rgens.parser.Rule; public class RRefVariableElement extends VariableElement { public String value; - private boolean forbidSpaces; - public RRefVariableElement(boolean forbidSpaces, String val) { + super(forbidSpaces); + value = val; } public void generate(GenerationState state) { - if(!state.rlVars.containsKey(value)) { - throw new GrammarException("No rule variable named " + value); - } - Rule rl = state.findRule(value, true); GenerationState newState = state.newBuf(); diff --git a/src/main/java/bjc/rgens/parser/elements/vars/TRefVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/TRefVariableElement.java index b10af87..a33d78c 100644 --- a/src/main/java/bjc/rgens/parser/elements/vars/TRefVariableElement.java +++ b/src/main/java/bjc/rgens/parser/elements/vars/TRefVariableElement.java @@ -10,14 +10,13 @@ import bjc.rgens.parser.templates.GrammarTemplate; * finish when template vars are implemented. */ public class TRefVariableElement extends VariableElement { - /* public String value; - private boolean forbidSpaces; - public TRefVariableElement(boolean forbidSpaces, String val) { + super(forbidSpaces); + value = val; - }*/ + } public void generate(GenerationState state) { /* diff --git a/src/main/java/bjc/rgens/parser/elements/vars/VRefVariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/VRefVariableElement.java index c6921ba..b19f785 100644 --- a/src/main/java/bjc/rgens/parser/elements/vars/VRefVariableElement.java +++ b/src/main/java/bjc/rgens/parser/elements/vars/VRefVariableElement.java @@ -6,12 +6,10 @@ import bjc.rgens.parser.GrammarException; public class VRefVariableElement extends VariableElement { public final String nam; - private final boolean forbidSpaces; - public VRefVariableElement(boolean forbidSpaces, String nam) { - this.nam = nam; + super(forbidSpaces); - this.forbidSpaces = forbidSpaces; + this.nam = nam; } public void generate(GenerationState state) { diff --git a/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java b/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java index 7a4260f..19c1e2c 100644 --- a/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java +++ b/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java @@ -1,5 +1,7 @@ package bjc.rgens.parser.elements.vars; +import bjc.utils.funcutils.StringUtils; + import bjc.rgens.parser.GenerationState; import bjc.rgens.parser.GrammarException; @@ -7,23 +9,29 @@ import java.util.ArrayList; import java.util.List; public abstract class VariableElement { + public boolean forbidSpaces; + + protected VariableElement(boolean forbidSpacing) { + forbidSpaces = forbidSpacing; + } + public abstract void generate(GenerationState state); - public static List parseVariableElements(String varElm) { - boolean forbidSpaces = varElm.contains("-"); + public static List parseElementString(String varElm) { + boolean forbidSpaces = StringUtils.levelContains(varElm, "-", "+"); String[] parts; if(forbidSpaces) { - parts = varElm.split("(?<=[+-])|(?=[+-])"); + parts = StringUtils.levelSplit(varElm, true, "-", "+").toArray(new String[0]); } else { parts = new String[] { varElm }; } - return parseVariableElements(forbidSpaces, parts); + return parseElementString(forbidSpaces, parts); } - public static List parseVariableElements(boolean forbidSpaces, String... parts) { + public static List parseElementString(boolean forbidSpaces, String... parts) { List elms = new ArrayList<>(parts.length); VariableElement prevElement = null; @@ -34,22 +42,26 @@ public abstract class VariableElement { if(part.startsWith("$")) { elm = new VRefVariableElement(forbidSpaces, part.substring(1)); } else if (part.startsWith("@")) { - elm = new ARefVariableElement(forbidSpaces, part.substring(1)); + if(forbidSpaces) + throw new GrammarException("Arrays references aren't allowed in rule names"); + + elm = new ARefVariableElement(part.substring(1)); } else if (part.startsWith("%")) { elm = new RRefVariableElement(forbidSpaces, part.substring(1)); } else if (part.startsWith("/")) { throw new GrammarException("Template variables aren't implemented yet"); } else { - if(prevElement instanceof LiteralVariableElement) { + if(prevElement != null && prevElement instanceof LiteralVariableElement) { /* Aggregate chain literals together */ - ((LiteralVariableElement)prevElement).val += elm; + ((LiteralVariableElement)prevElement).val += part; } else { - elm = new LiteralVariableElement(part); + elm = new LiteralVariableElement(forbidSpaces, part); } } if(elm != null) { elms.add(elm); + prevElement = elm; } } -- cgit v1.2.3