diff options
Diffstat (limited to 'src/main/java/bjc/rgens/parser/elements')
5 files changed, 135 insertions, 81 deletions
diff --git a/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/src/main/java/bjc/rgens/parser/elements/CaseElement.java index 522de7a..cc04781 100755 --- a/src/main/java/bjc/rgens/parser/elements/CaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/CaseElement.java @@ -131,7 +131,15 @@ public abstract class CaseElement { * Once the rule element execution has been refactored, * pass rawCase instead. */ - return new RuleCaseElement(csepart); + if(csepart.contains("$")) { + if(csepart.contains("-")) { + return new DependantRuleReference(csepart); + } + + return new VariableRuleReference(csepart); + } + + return new NormalRuleReference(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 new file mode 100644 index 0000000..5eccf8e --- /dev/null +++ b/src/main/java/bjc/rgens/parser/elements/DependantRuleReference.java @@ -0,0 +1,48 @@ +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/NormalRuleReference.java b/src/main/java/bjc/rgens/parser/elements/NormalRuleReference.java new file mode 100644 index 0000000..68553c2 --- /dev/null +++ b/src/main/java/bjc/rgens/parser/elements/NormalRuleReference.java @@ -0,0 +1,18 @@ +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 d91bebc..b4a4b58 100755 --- a/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/RuleCaseElement.java @@ -5,97 +5,44 @@ import bjc.rgens.parser.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class RuleCaseElement extends StringCaseElement { - private static Pattern NAMEVAR_PATTERN = Pattern.compile("\\$(\\w+)"); - - public RuleCaseElement(String vl) { - super(vl, false); +public abstract class RuleCaseElement extends StringCaseElement { + public static enum ReferenceType { + DEPENDENT, + VARIABLE, + NORMAL } - @Override - public void generate(GenerationState state) { - /* - * @NOTE - * - * :VarRefactor - * - * Figure out if this can be refactored in some way. - */ - String refersTo = val; - - GenerationState newState = state.newBuf(); - - if (refersTo.contains("$")) { - /* Parse variables */ - String refBody = refersTo.substring(1, refersTo.length() - 1); - - if (refBody.contains("-")) { - /* 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"); - } + public final ReferenceType ref; - nameMatcher.appendReplacement(nameBuffer, name); - } - - nameMatcher.appendTail(nameBuffer); - - refersTo = "[" + nameBuffer.toString() + "]"; - } else { - /* 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); - } + protected RuleCaseElement(String vl, ReferenceType ref) { + super(vl, false); - state.contents.append(state.vars.get(key)); + this.ref = ref; + } - return; - } - } + protected void doGenerate(String actName, GenerationState state) { + GenerationState newState = state.newBuf(); - if (refersTo.startsWith("[^")) { - refersTo = "[" + refersTo.substring(2); + if (actName.startsWith("[^")) { + actName = "[" + actName.substring(2); - RGrammar dst = state.importRules.get(refersTo); + RGrammar dst = state.importRules.get(actName); newState.swapGrammar(dst); /* :Postprocessing */ - newState.contents = new StringBuilder(dst.generate(refersTo, state.rnd, state.vars)); - } else if (state.rules.containsKey(refersTo)) { - RuleCase cse = state.rules.get(refersTo).getCase(state.rnd); + newState.contents = new StringBuilder(dst.generate(actName, state.rnd, state.vars)); + } else if (state.rules.containsKey(actName)) { + RuleCase cse = state.rules.get(actName).getCase(state.rnd); state.gram.generateCase(cse, newState); - } else if (state.importRules.containsKey(refersTo)) { - RGrammar dst = state.importRules.get(refersTo); + } else if (state.importRules.containsKey(actName)) { + RGrammar dst = state.importRules.get(actName); newState.swapGrammar(dst); /* :Postprocessing */ - newState.contents = new StringBuilder(dst.generate(refersTo, state.rnd, state.vars)); + newState.contents = new StringBuilder(dst.generate(actName, state.rnd, state.vars)); } else { /* * @TODO 5/29/18 Ben Culkin :RuleSuggesting @@ -104,26 +51,28 @@ public class RuleCaseElement extends StringCaseElement { */ /* if (ruleSearcher != null) { - Set<Match<? extends String>> results = ruleSearcher.search(refersTo, MAX_DISTANCE); + Set<Match<? extends String>> results = ruleSearcher.search(actName, MAX_DISTANCE); String[] resArray = results.stream().map(Match::getMatch).toArray((i) -> new String[i]); - String msg = String.format("No rule '%s' defined (perhaps you meant %s?)", refersTo, + String msg = String.format("No rule '%s' defined (perhaps you meant %s?)", actName, StringUtils.toEnglishList(resArray, false)); throw new GrammarException(msg); } */ - String msg = String.format("No rule '%s' defined", refersTo); + String msg = String.format("No rule '%s' defined", actName); throw new GrammarException(msg); } - if (refersTo.contains("+")) { + String res = newState.contents.toString(); + + if (actName.contains("+")) { /* Rule names with pluses in them get space-flattened */ - state.contents.append(newState.contents.toString().replaceAll("\\s+", "")); + state.contents.append(res.replaceAll("\\s+", "")); } else { - state.contents.append(newState.contents.toString()); + state.contents.append(res); } } } diff --git a/src/main/java/bjc/rgens/parser/elements/VariableRuleReference.java b/src/main/java/bjc/rgens/parser/elements/VariableRuleReference.java new file mode 100644 index 0000000..bebb9f7 --- /dev/null +++ b/src/main/java/bjc/rgens/parser/elements/VariableRuleReference.java @@ -0,0 +1,31 @@ +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; + } +} |
