diff options
Diffstat (limited to 'RGens/src/main/java/bjc')
| -rw-r--r-- | RGens/src/main/java/bjc/RGens/parser/RBGrammarReader.java | 119 | ||||
| -rw-r--r-- | RGens/src/main/java/bjc/RGens/parser/ReaderState.java | 4 |
2 files changed, 122 insertions, 1 deletions
diff --git a/RGens/src/main/java/bjc/RGens/parser/RBGrammarReader.java b/RGens/src/main/java/bjc/RGens/parser/RBGrammarReader.java index 84fee01..48e21b1 100644 --- a/RGens/src/main/java/bjc/RGens/parser/RBGrammarReader.java +++ b/RGens/src/main/java/bjc/RGens/parser/RBGrammarReader.java @@ -1,10 +1,20 @@ package bjc.RGens.parser; +import com.mifmif.common.regex.Generex; + import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Path; +import java.util.Random; +import java.util.function.BiFunction; +import java.util.function.Predicate; import bjc.utils.funcdata.FunctionalStringTokenizer; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.FunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; +import bjc.utils.funcutils.ListUtils; import bjc.utils.gen.WeightedGrammar; import bjc.utils.parserutils.RuleBasedConfigReader; @@ -17,6 +27,8 @@ import bjc.utils.parserutils.RuleBasedConfigReader; public class RBGrammarReader { private static RuleBasedConfigReader<ReaderState> reader; + private static Random numgen = new Random(); + static { setupReader(); @@ -80,7 +92,89 @@ public class RBGrammarReader { ReaderState initialState = new ReaderState(inputPath); try (FileInputStream inputStream = new FileInputStream(inputPath.toFile())) { - return reader.fromStream(inputStream, initialState).getGrammar(); + WeightedGrammar<String> gram = reader.fromStream(inputStream, initialState).getGrammar(); + + IMap<String, IList<String>> vars = new FunctionalMap<>(); + + Predicate<String> specialPredicate = (strang) -> { + if(strang.matches("\\{\\S+\\}") || strang.matches("\\[\\S+\\}")) { + return true; + } + + return false; + }; + + BiFunction<String, WeightedGrammar<String>, IList<String>> + specialAction = (strang, gramm) -> { + IList<String> retList = new FunctionalList<>(); + + if(strang.matches("\\{\\S+\\}")) { + if(strang.matches("\\{\\S+:=\\S+\\}")) { + String[] varParts = strang.split(":="); + + String varName = varParts[0].substring(1); + String ruleName = varParts[1].substring(0, varParts[1].length()); + + IList<String> varValue = gramm.generateGenericValues( + ruleName, (s) -> s, " "); + + vars.put(varName, varValue); + } else if(strang.matches("\\{\\S+=\\S+\\}")) { + String[] varParts = strang.split("="); + + String varName = varParts[0].substring(1); + String varValue = varParts[1].substring(0, varParts[1].length()); + + vars.put(varName, new FunctionalList<>(varValue)); + } else { + // @FIXME notify the user they did something wrong + retList.add(strang); + } + } else { + if(strang.matches("\\[\\$\\S+\\]")) { + String varName = strang.substring(2, strang.length()); + + retList = vars.get(varName); + } else if(strang.matches("\\[\\$\\S+\\-\\S+\\]")) { + String[] varParts = strang.substring(1, strang.length()).split("-"); + + StringBuilder actualName = new StringBuilder("["); + + for(String varPart : varParts) { + if(varPart.startsWith("$")) { + IList<String> varName = vars.get(varPart.substring(1)); + + if(varName.getSize() != 1) { + // @FIXME notify the user they did something wrong + } + + actualName.append(varName.first() + "-"); + } else { + actualName.append(varPart + "-"); + } + } + + // Trim trailing - + actualName.deleteCharAt(actualName.length() - 1); + actualName.append("]"); + + retList = gram.generateGenericValues(actualName.toString(), (s) -> s, " "); + } else { + // @FIXME notify the user they did something wrong + retList.add(strang); + } + } + + return retList; + }; + + Runnable specialReset = () -> { + vars.clear(); + }; + + gram.configureSpecial(specialPredicate, specialAction, specialReset); + + return gram; } catch (IOException ioex) { throw ioex; } @@ -118,6 +212,29 @@ public class RBGrammarReader { reader.addPragma("prefix-with", RBGrammarReader::prefixRule); reader.addPragma("suffix-with", RBGrammarReader::suffixRule); + + reader.addPragma("regex-rule", (tokenizer, state) -> { + String ruleName = tokenizer.nextToken(); + + IList<String> regx = tokenizer.toList(); + Generex regex = new Generex(ListUtils.collapseTokens(regx)); + + state.addSpecialRule(ruleName, () -> { + return new FunctionalList<>(regex.random().split(" ")); + }); + }); + + reader.addPragma("range-rule", (tokenizer, state) -> { + String ruleName = tokenizer.nextToken(); + + int start = Integer.parseInt(tokenizer.nextToken()); + int end = Integer.parseInt(tokenizer.nextToken()); + + state.addSpecialRule(ruleName, () -> { + return new FunctionalList<>(Integer.toString( + numgen.nextInt((end - start) + 1) + start)); + }); + }); } private static void loadSubGrammar(FunctionalStringTokenizer stk, ReaderState rs) { diff --git a/RGens/src/main/java/bjc/RGens/parser/ReaderState.java b/RGens/src/main/java/bjc/RGens/parser/ReaderState.java index b455844..8e846cf 100644 --- a/RGens/src/main/java/bjc/RGens/parser/ReaderState.java +++ b/RGens/src/main/java/bjc/RGens/parser/ReaderState.java @@ -3,6 +3,7 @@ package bjc.RGens.parser; import java.io.IOException; import java.nio.file.Path; import java.util.Stack; +import java.util.function.Supplier; import bjc.utils.funcdata.IList; import bjc.utils.gen.WeightedGrammar; @@ -124,6 +125,9 @@ public class ReaderState { currentGrammar.addCase(currentRule, ruleProbability, ruleParts); } + public void addSpecialRule(String ruleName, Supplier<IList<String>> cse) { + currentGrammar.addSpecialRule(ruleName, cse); + } /** * Edit a subgrammar of the current grammar * |
