summaryrefslogtreecommitdiff
path: root/RGens/src/main/java/bjc/rgens/newparser
diff options
context:
space:
mode:
Diffstat (limited to 'RGens/src/main/java/bjc/rgens/newparser')
-rw-r--r--RGens/src/main/java/bjc/rgens/newparser/CaseElement.java2
-rw-r--r--RGens/src/main/java/bjc/rgens/newparser/RGrammar.java9
-rw-r--r--RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java66
-rw-r--r--RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java11
-rw-r--r--RGens/src/main/java/bjc/rgens/newparser/Rule.java10
-rw-r--r--RGens/src/main/java/bjc/rgens/newparser/RuleCase.java6
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");