From 93884fa70a1fdcef373353639f10cec7aee7cec0 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Fri, 20 Jul 2018 12:51:08 -0300 Subject: Update --- .../java/bjc/rgens/parser/RGrammarBuilder.java | 6 ++++ src/main/java/bjc/rgens/parser/RGrammarSet.java | 5 ++- .../bjc/rgens/parser/elements/CaseElement.java | 12 +++++-- .../rgens/parser/elements/MethodCaseElement.java | 41 ++++++++++++++++++++++ .../parser/elements/methods/MethodElement.java | 7 ++++ .../parser/elements/vars/RRefVariableElement.java | 5 ++- .../parser/elements/vars/VariableElement.java | 15 ++++++-- 7 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 src/main/java/bjc/rgens/parser/elements/MethodCaseElement.java create mode 100644 src/main/java/bjc/rgens/parser/elements/methods/MethodElement.java diff --git a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java index 8f0a2d1..4d4157e 100755 --- a/src/main/java/bjc/rgens/parser/RGrammarBuilder.java +++ b/src/main/java/bjc/rgens/parser/RGrammarBuilder.java @@ -351,6 +351,12 @@ public class RGrammarBuilder { rules.get(rule).replaceCases(newCaseList); }*/ + /* + * @NOTE + * + * This should be moved into its own class somewhere, as it is general + * eneough. + */ private static List> powerList(Set elements) { /* * Fast-case the most common usage diff --git a/src/main/java/bjc/rgens/parser/RGrammarSet.java b/src/main/java/bjc/rgens/parser/RGrammarSet.java index b110d21..783ca26 100755 --- a/src/main/java/bjc/rgens/parser/RGrammarSet.java +++ b/src/main/java/bjc/rgens/parser/RGrammarSet.java @@ -33,7 +33,10 @@ public class RGrammarSet { public RGrammarSet() { grammars = new HashMap<>(); - exportedRules = new TreeMap<>(); + // @NOTE + // Swap which line is commented to toggle ordering of exports + //exportedRules = new TreeMap<>(); + exportedRules = new HashMap<>(); loadedFrom = new HashMap<>(); diff --git a/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/src/main/java/bjc/rgens/parser/elements/CaseElement.java index a44ef6c..f950f6d 100755 --- a/src/main/java/bjc/rgens/parser/elements/CaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/CaseElement.java @@ -5,6 +5,8 @@ import bjc.utils.funcutils.StringUtils; import bjc.rgens.parser.GenerationState; import bjc.rgens.parser.GrammarException; +import java.util.Arrays; + /** * A element in a rule case. * @@ -91,7 +93,7 @@ public abstract class CaseElement { char op = varName.charAt(varName.length() - 1); - System.err.printf("\t\tTRACE: Colon definition w/ op %d", (int)op); + 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); @@ -110,7 +112,7 @@ public abstract class CaseElement { return VariableDefCaseElement.parseVariable(varName, parts[1], ' ', true); } else if (specialBody.matches("\\S+=\\S+")) { - String[] parts = specialBody.split("="); + String[] parts = StringUtils.levelSplit(specialBody, "=").toArray(new String[0]); if(parts.length != 2) { throw new GrammarException("Variables must have a name and a definition"); } @@ -140,6 +142,12 @@ public abstract class CaseElement { // String[] elms = StringUtils.levelSplit(rawCase, "|").toArray(new String[0]); // return new InlineRuleCaseElement(elms); + } else if (StringUtils.levelContains(rawCase, ".")) { + String[] parts = StringUtils.levelSplit(rawCase, ".").toArray(new String[0]); + + CaseElement base = createElement(parts[0]); + + return new MethodCaseElement(base, Arrays.copyOfRange(parts, 1, parts.length)); } else { return new RuleCaseElement(rawCase); } diff --git a/src/main/java/bjc/rgens/parser/elements/MethodCaseElement.java b/src/main/java/bjc/rgens/parser/elements/MethodCaseElement.java new file mode 100644 index 0000000..49375bc --- /dev/null +++ b/src/main/java/bjc/rgens/parser/elements/MethodCaseElement.java @@ -0,0 +1,41 @@ +package bjc.rgens.parser.elements; + +import bjc.rgens.parser.GenerationState; +import bjc.rgens.parser.GrammarException; +import bjc.rgens.parser.elements.CaseElement; +import bjc.rgens.parser.methods.MethodElement; + +import java.util.List; +import java.util.LinkedList; + +public class MethodCaseElement extends CaseElement { + public CaseElement base; + + public List methods; + + public MethodCaseElement(CaseElement base, String... rawMethods) { + this(base, new MethodElement[0]); + + // @TODO + // + // Implement this + } + + public MethodCaseElement(CaseElement base, MethodElement... rawMethods) { + this.base = base; + + methods = new LinkedList<>(); + + for(MethodElement elm : rawMethods) { + methods.add(rawMethods); + } + } + + public void generate(GenerationState state) { + base.generate(state); + + for(MethodElement method : methods) { + method.call(state); + } + } +} diff --git a/src/main/java/bjc/rgens/parser/elements/methods/MethodElement.java b/src/main/java/bjc/rgens/parser/elements/methods/MethodElement.java new file mode 100644 index 0000000..0e8f37c --- /dev/null +++ b/src/main/java/bjc/rgens/parser/elements/methods/MethodElement.java @@ -0,0 +1,7 @@ +package bjc.rgens.parser.elements.methods; + +import bjc.rgens.parser.GenerationState; + +public interface MethodElement { + public void call(GenerationState state); +} 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 d731d64..5c0a768 100644 --- a/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java +++ b/src/main/java/bjc/rgens/parser/elements/vars/RRefVariableElement.java @@ -16,6 +16,9 @@ public class RRefVariableElement extends VariableElement { public void generate(GenerationState state) { Rule rl = state.findRule(value, true); + if(rl == null) + throw new GrammarException(String.format("Could not find rule '%s'", value)); + GenerationState newState = state.newBuf(); rl.generate(newState); @@ -23,7 +26,7 @@ public class RRefVariableElement extends VariableElement { String res = newState.contents.toString(); if(forbidSpaces && res.contains(" ")) { - throw new GrammarException("Spaces not allowed in this context (rule-reference %s)"); + throw new GrammarException(String.format("Spaces not allowed in this context (rule-reference %s)", state)); } state.contents.append(res); 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 19c1e2c..2193b3c 100644 --- a/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java +++ b/src/main/java/bjc/rgens/parser/elements/vars/VariableElement.java @@ -36,7 +36,12 @@ public abstract class VariableElement { VariableElement prevElement = null; - for (String part : parts) { + for (String npart : parts) { + // @HACK + // This is so that inline refs to hypenized rule names + // work. Not sure this is a good impl. strategy + String part = npart.replaceAll("\\(|\\)", ""); + VariableElement elm = null; if(part.startsWith("$")) { @@ -47,7 +52,7 @@ public abstract class VariableElement { elm = new ARefVariableElement(part.substring(1)); } else if (part.startsWith("%")) { - elm = new RRefVariableElement(forbidSpaces, part.substring(1)); + elm = new RRefVariableElement(forbidSpaces, String.format("[%s]", part.substring(1))); } else if (part.startsWith("/")) { throw new GrammarException("Template variables aren't implemented yet"); } else { @@ -55,7 +60,11 @@ public abstract class VariableElement { /* Aggregate chain literals together */ ((LiteralVariableElement)prevElement).val += part; } else { - elm = new LiteralVariableElement(forbidSpaces, part); + if(part.contains(" ")) { + elm = new LiteralVariableElement(false, part); + } else { + elm = new LiteralVariableElement(true, part); + } } } -- cgit v1.2.3