summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/rgens/parser/RGrammarFormatter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/bjc/rgens/parser/RGrammarFormatter.java')
-rwxr-xr-xsrc/main/java/bjc/rgens/parser/RGrammarFormatter.java97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/main/java/bjc/rgens/parser/RGrammarFormatter.java b/src/main/java/bjc/rgens/parser/RGrammarFormatter.java
new file mode 100755
index 0000000..a2454dc
--- /dev/null
+++ b/src/main/java/bjc/rgens/parser/RGrammarFormatter.java
@@ -0,0 +1,97 @@
+package bjc.rgens.parser;
+
+import bjc.rgens.parser.elements.CaseElement;
+import bjc.utils.funcdata.IList;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Format randomized grammars to strings properly.
+ *
+ * @author EVE
+ */
+public class RGrammarFormatter {
+ /**
+ * Format a grammar into a file that represents that grammar.
+ *
+ * @param gram
+ * The grammar to format.
+ *
+ * @return
+ * The formatted grammar.
+ */
+ public static String formatGrammar(RGrammar gram) {
+ StringBuilder sb = new StringBuilder();
+
+ Map<String, Rule> rules = gram.getRules();
+
+ String initRuleName = gram.getInitialRule();
+
+ Set<String> processedRules = new HashSet<>();
+
+ if (initRuleName != null) {
+ processRule(rules.get(initRuleName), sb);
+
+ processedRules.add(initRuleName);
+ }
+
+ for (Rule rule : rules.values()) {
+ if (!processedRules.contains(rule.name)) {
+ sb.append("\n\n");
+
+ processRule(rule, sb);
+ }
+
+ processedRules.add(rule.name);
+ }
+
+ return sb.toString().trim();
+ }
+
+ /* Format a rule. */
+ private static void processRule(Rule rule, StringBuilder sb) {
+ IList<RuleCase> cases = rule.getCases();
+
+ StringBuilder ruleBuilder = new StringBuilder();
+
+ ruleBuilder.append(rule.name);
+ ruleBuilder.append(" \u2192 ");
+
+ int markerPos = ruleBuilder.length();
+
+ processCase(cases.first(), ruleBuilder);
+
+ sb.append(ruleBuilder.toString().trim());
+
+ ruleBuilder = new StringBuilder();
+
+ for (RuleCase cse : cases.tail()) {
+ sb.append("\n\t");
+
+ for (int i = 8; i < markerPos; i++) {
+ ruleBuilder.append(" ");
+ }
+
+ processCase(cse, ruleBuilder);
+
+ sb.append(ruleBuilder.toString());
+
+ ruleBuilder = new StringBuilder();
+ }
+
+ }
+
+ /* Format a case. */
+ private static void processCase(RuleCase cse, StringBuilder sb) {
+ /* Process each element, adding a space. */
+ for (CaseElement element : cse.getElements()) {
+ sb.append(element.toString());
+ sb.append(" ");
+ }
+
+ /* Remove the trailing space. */
+ sb.deleteCharAt(sb.length() - 1);
+ }
+}