diff options
Diffstat (limited to 'src/main/java/bjc/rgens/parser/elements/CaseElement.java')
| -rwxr-xr-x[-rw-r--r--] | src/main/java/bjc/rgens/parser/elements/CaseElement.java | 143 |
1 files changed, 85 insertions, 58 deletions
diff --git a/src/main/java/bjc/rgens/parser/elements/CaseElement.java b/src/main/java/bjc/rgens/parser/elements/CaseElement.java index d74ab52..a44ef6c 100644..100755 --- a/src/main/java/bjc/rgens/parser/elements/CaseElement.java +++ b/src/main/java/bjc/rgens/parser/elements/CaseElement.java @@ -1,17 +1,16 @@ package bjc.rgens.parser.elements; +import bjc.utils.funcutils.StringUtils; + +import bjc.rgens.parser.GenerationState; import bjc.rgens.parser.GrammarException; -/* - * @TODO 10/11/17 Ben Culkin :CaseElementSplit Split this into multiple - * subclasses based off of a value of ElementType. - */ /** * A element in a rule case. * * @author EVE */ -public class CaseElement { +public abstract class CaseElement { /** * The possible types of an element. * @@ -19,27 +18,27 @@ public class CaseElement { */ public static enum ElementType { /** An element that represents a literal string. */ - LITERAL, + LITERAL(true), /** An element that represents a rule reference. */ - RULEREF, + RULEREF(true), /** An element that represents a random range. */ - RANGE, + RANGE(true), /** An element that represents a variable that stores a string. */ - VARDEF, - /** - * An element that represents a variable that stores the result of generating a - * rule. - */ - EXPVARDEF; - } + VARIABLE(false); - /* Regexps for marking rule types. */ - private static final String SPECIAL_CASELEM = "\\{[^}]+\\}"; - private static final String REFER_CASELEM = "\\[[^\\]]+\\]"; - private static final String RANGE_CASELM = "\\[\\d+\\.\\.\\d+\\]"; + public final boolean spacing; + + private ElementType(boolean spacing) { + this.spacing = spacing; + } + } /** The type of this element. */ - public final ElementType type; + public boolean spacing; + + protected CaseElement() { + this(true); + } /** * Create a new case element. @@ -47,17 +46,17 @@ public class CaseElement { * @param typ * The type of this element. */ - protected CaseElement(ElementType typ) { - type = typ; + protected CaseElement(boolean spacing) { + this.spacing = spacing; } - @Override - public String toString() { - switch (type) { - default: - return String.format("Unknown type '%s'", type); - } - } + /** + * Generate this case element. + * + * @param state + * The current state of generation. + */ + public abstract void generate(GenerationState state); /** * Create a case element from a string. @@ -72,52 +71,80 @@ public class CaseElement { throw new NullPointerException("Case part cannot be null"); } - if (csepart.matches(SPECIAL_CASELEM)) { - /* Handle special cases. */ + if (csepart.matches("\\(\\S+\\)")) { + return createElement(csepart.substring(1, csepart.length() - 1)); + } else if (csepart.matches("\\{\\S+\\}")) { + /* + * Handle special case elements. + * + */ String specialBody = csepart.substring(1, csepart.length() - 1); - System.out.printf("\t\tTRACE: special body is '%s'\n", specialBody); + if (specialBody.matches("\\S+:\\S=\\S+")) { + String[] parts = StringUtils.levelSplit(specialBody, "=").toArray(new String[0]); - if (specialBody.matches("\\S+:=\\S+")) { - /* Handle expanding variable definitions. */ - String[] parts = specialBody.split(":="); + if(parts.length != 2) { + throw new GrammarException("Colon variables must have a name and a definition"); + } + + String varName = parts[0]; + + char op = varName.charAt(varName.length() - 1); + + System.err.printf("\t\tTRACE: Colon definition w/ op %d", (int)op); - if (parts.length != 2) { - String msg = "Expanded variables must be a name and a definition, seperated by :="; + // Remove the colon, plus any tacked on operator + varName = varName.substring(0, varName.length() - 2); - throw new GrammarException(msg); + return VariableDefCaseElement.parseVariable(varName, parts[1], op, true); + } else if (specialBody.matches("\\S+:=\\S+")) { + String[] parts = StringUtils.levelSplit(specialBody, "=").toArray(new String[0]); + + if(parts.length != 2) { + throw new GrammarException("Colon variables must have a name and a definition"); } - return new ExpVariableCaseElement(parts[0], parts[1]); - } else if (specialBody.matches("\\S+=\\S+")) { - /* Handle regular variable definitions. */ - String[] parts = specialBody.split("="); + String varName = parts[0]; - if (parts.length != 2) { - String msg = "Variables must be a name and a definition, seperated by ="; + varName = varName.substring(0, varName.length() - 1); - throw new GrammarException(msg); + return VariableDefCaseElement.parseVariable(varName, parts[1], ' ', true); + } else if (specialBody.matches("\\S+=\\S+")) { + String[] parts = specialBody.split("="); + if(parts.length != 2) { + throw new GrammarException("Variables must have a name and a definition"); } - return new LitVariableCaseElement(parts[0], parts[1]); - } else if (specialBody.matches("{empty}")) { + // Non-colon variables can't take an operator + return VariableDefCaseElement.parseVariable(parts[0], parts[1], (char)0, false); + } else if (specialBody.matches("empty")) { /* Literal blank, for empty cases. */ return new BlankCaseElement(); } else { throw new IllegalArgumentException(String.format("Unknown special case part '%s'", specialBody)); } - } else if (csepart.matches(REFER_CASELEM)) { - if (csepart.matches(RANGE_CASELM)) { - /* Handle ranges */ - String rawRange = csepart.substring(1, csepart.length() - 1); + } else if (csepart.matches("\\[\\S+\\]")) { + String rawCase = csepart.substring(1, csepart.length() - 1); - int firstNum = Integer.parseInt(rawRange.substring(0, rawRange.indexOf('.'))); - int secondNum = Integer.parseInt(rawRange.substring(rawRange.lastIndexOf('.') + 1)); + if (rawCase.matches("\\d+\\.{2}\\d+")) { + int firstNum = Integer.parseInt(rawCase.substring(0, rawCase.indexOf('.'))); + int secondNum = Integer.parseInt(rawCase.substring(rawCase.lastIndexOf('.') + 1)); return new RangeCaseElement(firstNum, secondNum); - } + } else if(rawCase.contains("||")) { + String[] elms = StringUtils.levelSplit(rawCase, "||").toArray(new String[0]); - return new RuleCaseElement(csepart); + return new InlineRuleCaseElement(elms); + } else if(rawCase.contains("|")) { + throw new GrammarException("\t\tERROR: Inline rule using | found, they use || now"); + + // String[] elms = StringUtils.levelSplit(rawCase, "|").toArray(new String[0]); + // return new InlineRuleCaseElement(elms); + } else { + return new RuleCaseElement(rawCase); + } + } else if(csepart.startsWith("%") && !csepart.equals("%")) { + return new RuleCaseElement(csepart); } else { return new LiteralCaseElement(csepart); } @@ -127,7 +154,7 @@ public class CaseElement { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + (spacing ? 0 : 2); return result; } @@ -140,8 +167,8 @@ public class CaseElement { if (getClass() != obj.getClass()) return false; CaseElement other = (CaseElement) obj; - if (type != other.type) + if (spacing != other.spacing) return false; return true; } -}
\ No newline at end of file +} |
