diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2017-10-24 19:29:04 -0300 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2017-10-24 19:29:04 -0300 |
| commit | d6a2f1faa5d2f2009afe37a17b3c18faa2d79a0e (patch) | |
| tree | 13efb0414aeb9bb9b4d90f6f62878a9cfcf69a5d /RGens/src/main/java/bjc/rgens | |
| parent | e1f4d1f3fc86b67e82684d196d3948a13794d35f (diff) | |
Add a possible solution to :Spacing?
Diffstat (limited to 'RGens/src/main/java/bjc/rgens')
6 files changed, 96 insertions, 8 deletions
diff --git a/RGens/src/main/java/bjc/rgens/newparser/CaseElement.java b/RGens/src/main/java/bjc/rgens/newparser/CaseElement.java index 30b0172..5d52726 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/CaseElement.java +++ b/RGens/src/main/java/bjc/rgens/newparser/CaseElement.java @@ -373,6 +373,8 @@ public class CaseElement { /* Handle special cases. */ String specialBody = csepart.substring(1, csepart.length() - 1); + System.out.printf("\t\tTRACE: special body is '%s'\n", specialBody); + if (specialBody.matches("\\S+:=\\S+")) { /* Handle expanding variable definitions. */ String[] parts = specialBody.split(":="); diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java index 2dfec39..6539d60 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java @@ -187,6 +187,12 @@ public class RGrammar { case NORMAL: for (CaseElement elm : start.getElements()) { generateElement(elm, state); + state.contents.append(" "); + } + break; + case SPACEFLATTEN: + for (CaseElement elm : start.getElements()) { + generateElement(elm, state); } break; default: @@ -205,7 +211,6 @@ public class RGrammar { switch (elm.type) { case LITERAL: state.contents.append(elm.getLiteral()); - state.contents.append(" "); break; case RULEREF: generateRuleReference(elm, state); @@ -218,7 +223,6 @@ public class RGrammar { val += start; state.contents.append(val); - state.contents.append(" "); break; case VARDEF: generateVarDef(elm.getName(), elm.getDefn(), state); @@ -351,7 +355,6 @@ public class RGrammar { if (refersTo.contains("+")) { /* Rule names with pluses in them get space-flattened */ state.contents.append(newState.contents.toString().replaceAll("\\s+", "")); - state.contents.append(" "); } else { state.contents.append(newState.contents.toString()); } diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java index 4e9f9e1..a6b21a5 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java @@ -128,12 +128,32 @@ public class RGrammarBuilder { throw new NullPointerException("Rule name must not be null"); } else if (ruleName.equals("")) { throw new IllegalArgumentException("The empty string is not a valid rule name"); + } else if(!rules.containsKey(ruleName)) { + String msg = String.format("Rule '%s' is not a valid rule name."); + + throw new IllegalArgumentException(msg); } CaseElement element = CaseElement.createElement(suffix); - for (RuleCase ruleCase : rules.get(ruleName).getCases()) { - ruleCase.getElements().add(element); + FunctionalList<RuleCase> newCases = new FunctionalList<>(); + + IList<RuleCase> caseList = rules.get(ruleName).getCases(); + for (RuleCase ruleCase : caseList) { + FunctionalList<CaseElement> newCase = new FunctionalList<>(); + + for(CaseElement elm : ruleCase.getElements()) { + newCase.add(elm); + } + + newCase.add(element); + + newCases.add(new RuleCase(NORMAL, newCase)); + } + + + for (RuleCase newCase : newCases) { + caseList.add(newCase); } } @@ -155,12 +175,50 @@ public class RGrammarBuilder { throw new NullPointerException("Rule name must not be null"); } else if (ruleName.equals("")) { throw new IllegalArgumentException("The empty string is not a valid rule name"); + } else if(!rules.containsKey(ruleName)) { + String msg = String.format("Rule '%s' is not a valid rule name."); + + throw new IllegalArgumentException(msg); } CaseElement element = CaseElement.createElement(prefix); - for (RuleCase ruleCase : rules.get(ruleName).getCases()) { - ruleCase.getElements().add(element); + FunctionalList<RuleCase> newCases = new FunctionalList<>(); + + IList<RuleCase> caseList = rules.get(ruleName).getCases(); + for (RuleCase ruleCase : caseList) { + FunctionalList<CaseElement> newCase = new FunctionalList<>(); + + newCase.add(element); + + for(CaseElement elm : ruleCase.getElements()) { + newCase.add(elm); + } + + newCases.add(new RuleCase(NORMAL, newCase)); } + + + for (RuleCase newCase : newCases) { + caseList.add(newCase); + } + } + + public void despaceRule(String ruleName) { + if (ruleName == null) { + throw new NullPointerException("ruleName must not be null"); + } else if (ruleName.equals("")) { + throw new IllegalArgumentException("The empty string is not a valid rule name"); + } + + IList<RuleCase> caseList = rules.get(ruleName).getCases(); + + IList<RuleCase> newCaseList = new FunctionalList<>(); + + for(RuleCase cse : caseList) { + newCaseList.add(new RuleCase(SPACEFLATTEN, cse.getElements())); + } + + rules.get(ruleName).replaceCases(newCaseList); } } diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java index e253cc3..9451f8c 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java @@ -51,6 +51,17 @@ public class RGrammarParser { build.setInitialRule(body); }); + pragmas.put("despace-rule", (body, build, level) -> { + int sep = body.indexOf(' '); + + if (sep != -1) { + String msg = "despace-rule pragma takes only one argument, the name of the rule to despace"; + throw new GrammarException(msg); + } + + build.despaceRule(body); + }); + pragmas.put("export-rule", (body, build, level) -> { String[] exports = body.split(" "); diff --git a/RGens/src/main/java/bjc/rgens/newparser/Rule.java b/RGens/src/main/java/bjc/rgens/newparser/Rule.java index 612d603..0717233 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/Rule.java +++ b/RGens/src/main/java/bjc/rgens/newparser/Rule.java @@ -85,6 +85,16 @@ public class Rule { return cases; } + /** + * Replace the current list of cases with a new one. + * + * @param cases + * The new list of cases. + */ + public void replaceCases(IList<RuleCase> cases) { + this.cases = cases; + } + @Override public int hashCode() { final int prime = 31; diff --git a/RGens/src/main/java/bjc/rgens/newparser/RuleCase.java b/RGens/src/main/java/bjc/rgens/newparser/RuleCase.java index 4ec0d2d..2a10210 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RuleCase.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RuleCase.java @@ -21,6 +21,8 @@ public class RuleCase { public static enum CaseType { /** A normal case, composed from a list of elementList. */ NORMAL, + /** A case that doesn't insert spaces. */ + SPACEFLATTEN } /** The type of this case. */ @@ -31,7 +33,7 @@ public class RuleCase { * * <h2>Used For</h2> * <dl> - * <dt>NORMAL</dt> + * <dt>NORMAL, SPACEFLATTEN</dt> * <dd>Used as the list of elementList the rule is composed of.</dd> * </dl> */ @@ -49,6 +51,7 @@ public class RuleCase { public RuleCase(CaseType typ) { switch (typ) { case NORMAL: + case SPACEFLATTEN: throw new IllegalArgumentException("This type requires an element list parameter"); default: break; @@ -73,6 +76,7 @@ public class RuleCase { public RuleCase(CaseType typ, IList<CaseElement> elements) { switch (typ) { case NORMAL: + case SPACEFLATTEN: break; default: throw new IllegalArgumentException("This type doesn't have a element list parameter"); |
