Improvements to the Parsing and more options how to deal with sectioning
-Added: Sectioning of if statements are now a thing. (TESTING || VALUES) -Added: Number Parsing is now a thing for conditions. DATE>=12 -Fixed: Logger not using println at the end.
This commit is contained in:
parent
6e5e91d0bd
commit
a63defacbb
|
@ -5,7 +5,7 @@ repositories {
|
|||
}
|
||||
|
||||
archivesBaseName = 'Simple Code Generator'
|
||||
version = '1.1.4'
|
||||
version = '1.2.0'
|
||||
apply plugin: 'maven'
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
|
|
|
@ -2,12 +2,12 @@ package speiger.src.builder.base;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import speiger.src.builder.conditions.ICondition;
|
||||
import speiger.src.builder.misc.IdGenerator;
|
||||
import speiger.src.builder.processor.CompiledArguments;
|
||||
|
||||
public class ConditionedSegment
|
||||
{
|
||||
|
@ -27,13 +27,13 @@ public class ConditionedSegment
|
|||
segments.add(segment);
|
||||
}
|
||||
|
||||
public int build(Set<String> parsePool, StringBuilder builder, int baseIndex)
|
||||
public int build(CompiledArguments process, StringBuilder builder, int baseIndex)
|
||||
{
|
||||
baseIndex += index;
|
||||
int length = builder.length();
|
||||
for(int i = 0,m=segments.size();i<m;i++)
|
||||
{
|
||||
if(segments.get(i).build(parsePool, builder, baseIndex)) break;
|
||||
if(segments.get(i).build(process, builder, baseIndex)) break;
|
||||
}
|
||||
return builder.length() - length;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ package speiger.src.builder.base;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import speiger.src.builder.conditions.ICondition;
|
||||
import speiger.src.builder.processor.CompiledArguments;
|
||||
|
||||
public class Segment
|
||||
{
|
||||
|
@ -19,14 +19,14 @@ public class Segment
|
|||
this.segments = segments;
|
||||
}
|
||||
|
||||
public boolean build(Set<String> parsePool, StringBuilder builder, int index)
|
||||
public boolean build(CompiledArguments process, StringBuilder builder, int index)
|
||||
{
|
||||
if(condition.isValid(parsePool))
|
||||
if(condition.isValid(process))
|
||||
{
|
||||
builder.insert(index, text);
|
||||
for(int i = 0,offset=0,m=segments.size();i<m;i++)
|
||||
{
|
||||
offset += segments.get(i).build(parsePool, builder, index+offset);
|
||||
offset += segments.get(i).build(process, builder, index+offset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.StringJoiner;
|
|||
import speiger.src.builder.mappers.IMapper;
|
||||
import speiger.src.builder.misc.FileUtils;
|
||||
import speiger.src.builder.misc.IdGenerator;
|
||||
import speiger.src.builder.processor.CompiledArguments;
|
||||
|
||||
public class Template
|
||||
{
|
||||
|
@ -32,13 +33,14 @@ public class Template
|
|||
return fileName;
|
||||
}
|
||||
|
||||
public String build(Set<String> parsePool, List<IMapper> mappers, boolean printNoWork, Set<IMapper> done)
|
||||
public String build(CompiledArguments process, boolean printNoWork, Set<IMapper> done)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(textFile);
|
||||
for(int i = 0,offset=0,m=segments.size();i<m;i++)
|
||||
{
|
||||
offset += segments.get(i).build(parsePool, builder, offset);
|
||||
offset += segments.get(i).build(process, builder, offset);
|
||||
}
|
||||
List<IMapper> mappers = process.getMapper();
|
||||
String result = builder.toString();
|
||||
for(int i = 0,m=mappers.size();i<m;i++)
|
||||
{
|
||||
|
|
|
@ -2,28 +2,32 @@ package speiger.src.builder.conditions;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import speiger.src.builder.processor.CompiledArguments;
|
||||
|
||||
public class AndCondition implements ICondition
|
||||
{
|
||||
List<ICondition> conditions = new ArrayList<>();
|
||||
|
||||
public AndCondition() {}
|
||||
|
||||
public AndCondition(ICondition base)
|
||||
{
|
||||
conditions.add(base);
|
||||
addCondition(base);
|
||||
}
|
||||
|
||||
public void addCondition(ICondition e)
|
||||
{
|
||||
if(e == null) return;
|
||||
conditions.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Set<String> parsePool)
|
||||
public boolean isValid(CompiledArguments args)
|
||||
{
|
||||
for(int i = 0,m=conditions.size();i<m;i++)
|
||||
{
|
||||
if(!conditions.get(i).isValid(parsePool))
|
||||
if(!conditions.get(i).isValid(args))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package speiger.src.builder.conditions;
|
||||
|
||||
import java.util.Set;
|
||||
import speiger.src.builder.processor.CompiledArguments;
|
||||
|
||||
public class FlagCondition implements ICondition
|
||||
{
|
||||
|
@ -14,8 +14,8 @@ public class FlagCondition implements ICondition
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Set<String> parsePool)
|
||||
public boolean isValid(CompiledArguments args)
|
||||
{
|
||||
return parsePool.contains(flag) != inverted;
|
||||
return args.test(flag) != inverted;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +1,55 @@
|
|||
package speiger.src.builder.conditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import speiger.src.builder.misc.RegexUtil;
|
||||
import speiger.src.builder.processor.CompiledArguments;
|
||||
|
||||
public interface ICondition
|
||||
{
|
||||
public static final Set<Character> VALID_CHARACTERS = new HashSet<>(Arrays.asList('(', ')'));
|
||||
public static final ICondition ALWAYS_TRUE = T -> true;
|
||||
|
||||
public boolean isValid(Set<String> parsePool);
|
||||
|
||||
public static ICondition parse(String condition)
|
||||
{
|
||||
String[] elements = condition.split(" ");
|
||||
List<ICondition> conditions = new ArrayList<ICondition>();
|
||||
for(int i = 0;i<elements.length;i++)
|
||||
{
|
||||
if(elements[i].equalsIgnoreCase("&&"))
|
||||
{
|
||||
if(i==elements.length-1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(condition.isEmpty())
|
||||
{
|
||||
conditions.add(new AndCondition(parseSimpleCondition(elements[++i])));
|
||||
}
|
||||
else
|
||||
{
|
||||
ICondition con = conditions.get(conditions.size() - 1);
|
||||
if(con instanceof AndCondition)
|
||||
{
|
||||
((AndCondition)con).addCondition(parseSimpleCondition(elements[++i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
AndCondition replacement = new AndCondition(con);
|
||||
replacement.addCondition(parseSimpleCondition(elements[++i]));
|
||||
conditions.set(conditions.size()-1, replacement);
|
||||
public boolean isValid(CompiledArguments args);
|
||||
|
||||
public static ICondition parse(List<String> elements) {
|
||||
List<ICondition> conditions = new ArrayList<>();
|
||||
AndCondition activeAnd = null;
|
||||
for(int i = 0,m=elements.size();i<m;i++) {
|
||||
String entry = elements.get(i);
|
||||
if(entry.equalsIgnoreCase("(")) {
|
||||
int endIndex = RegexUtil.lastIndexOf(elements, i, "(", ")");
|
||||
if(endIndex == -1) throw new IllegalStateException("A Condition Closer [ ) ] is missing");
|
||||
ICondition result = parse(elements.subList(i+1, endIndex));
|
||||
if(activeAnd != null) activeAnd.addCondition(result);
|
||||
else conditions.add(result);
|
||||
i = endIndex+1;
|
||||
}
|
||||
else if(entry.equalsIgnoreCase("&&")) {
|
||||
if(activeAnd != null) continue;
|
||||
if(i != 0) {
|
||||
ICondition prev = conditions.get(conditions.size()-1);
|
||||
if(prev instanceof AndCondition) activeAnd = (AndCondition)prev;
|
||||
else {
|
||||
activeAnd = new AndCondition(prev);
|
||||
conditions.set(conditions.size()-1, activeAnd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
activeAnd = new AndCondition();
|
||||
conditions.add(activeAnd);
|
||||
}
|
||||
}
|
||||
else if(!elements[i].equalsIgnoreCase("||"))
|
||||
{
|
||||
conditions.add(parseSimpleCondition(elements[i]));
|
||||
else if(entry.equalsIgnoreCase("||")) {
|
||||
activeAnd = null;
|
||||
}
|
||||
else {
|
||||
if(activeAnd != null) activeAnd.addCondition(parseCondition(entry));
|
||||
else conditions.add(parseCondition(entry));
|
||||
}
|
||||
}
|
||||
switch(conditions.size())
|
||||
|
@ -54,8 +60,15 @@ public interface ICondition
|
|||
}
|
||||
}
|
||||
|
||||
static ICondition parseSimpleCondition(String s)
|
||||
public static ICondition parse(String condition)
|
||||
{
|
||||
return parse(Arrays.asList(RegexUtil.ensureWhitespaces(condition, VALID_CHARACTERS).split(" ")));
|
||||
}
|
||||
|
||||
static ICondition parseCondition(String s)
|
||||
{
|
||||
ICondition numbers = NumberCondition.tryBuild(s);
|
||||
if(numbers != null) return numbers;
|
||||
return s.startsWith("!") ? new FlagCondition(s.substring(1), true) : new FlagCondition(s, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package speiger.src.builder.conditions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import speiger.src.builder.processor.CompiledArguments;
|
||||
|
||||
public class NumberCondition implements ICondition
|
||||
{
|
||||
private static final Pattern SCANNER = Pattern.compile(Operation.buildReggex());
|
||||
String flag;
|
||||
Operation op;
|
||||
int number;
|
||||
boolean flipped;
|
||||
|
||||
public NumberCondition(String flag, Operation op, int number, boolean flipped)
|
||||
{
|
||||
this.flag = flag;
|
||||
this.op = op;
|
||||
this.number = number;
|
||||
this.flipped = flipped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(CompiledArguments args)
|
||||
{
|
||||
return op.matches(flipped ? args.get(flag) : number, flipped ? number : args.get(flag));
|
||||
}
|
||||
|
||||
public static NumberCondition tryBuild(String arg)
|
||||
{
|
||||
Matcher match = SCANNER.matcher(arg);
|
||||
if(!match.find()) return null;
|
||||
int start = match.start();
|
||||
int end = match.end();
|
||||
Operation op = Operation.byId(arg.substring(start, end));
|
||||
if(op == null) throw new IllegalArgumentException("Operation ["+arg.substring(start, end)+"] is unknown");
|
||||
String key = arg.substring(0, start);
|
||||
String value = arg.substring(end);
|
||||
int[] result = new int[1];
|
||||
if(parse(key, result)) return new NumberCondition(value, op, result[0], true);
|
||||
if(parse(value, result)) return new NumberCondition(key, op, result[0], false);
|
||||
throw new IllegalStateException("Neither key or value are parsable");
|
||||
}
|
||||
|
||||
|
||||
private static boolean parse(String arg, int[] output) {
|
||||
try { output[0] = Integer.parseInt(arg); }
|
||||
catch(Exception e) { return false;}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static enum Operation
|
||||
{
|
||||
EQUALS("=="),
|
||||
GREATER_EQUALS(">="),
|
||||
GREATER(">"),
|
||||
SMALLER_EQUALS("<="),
|
||||
SMALLER("<"),
|
||||
NOT_EQUALS("!="),
|
||||
BIT_EQUALS_ALL("&="),
|
||||
BIT_EQUALS_ANY("|="),
|
||||
BIT_EQUALS_NOT("~=");
|
||||
|
||||
static final Map<String, Operation> DATA = Arrays.stream(values()).collect(Collectors.toMap(Operation::getId, Function.identity()));
|
||||
String key;
|
||||
|
||||
private Operation(String key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public static String buildReggex()
|
||||
{
|
||||
StringJoiner joiner = new StringJoiner("|\\", "\\", "");
|
||||
for(Operation entry : values())
|
||||
{
|
||||
joiner.add(entry.getId());
|
||||
}
|
||||
return joiner.toString();
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
public boolean matches(int key, int value)
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case EQUALS: return key == value;
|
||||
case NOT_EQUALS: return key != value;
|
||||
case GREATER: return key > value;
|
||||
case SMALLER: return key < value;
|
||||
case BIT_EQUALS_ALL: return (key & value) == value;
|
||||
case BIT_EQUALS_ANY: return (key & value) != 0;
|
||||
case BIT_EQUALS_NOT: return (key & value) == 0;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Operation byId(String key)
|
||||
{
|
||||
return DATA.get(key);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
package speiger.src.builder.conditions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import speiger.src.builder.processor.CompiledArguments;
|
||||
|
||||
public class OrCondition implements ICondition
|
||||
{
|
||||
|
@ -13,11 +14,11 @@ public class OrCondition implements ICondition
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Set<String> parsePool)
|
||||
public boolean isValid(CompiledArguments args)
|
||||
{
|
||||
for(int i = 0,m=conditions.size();i<m;i++)
|
||||
{
|
||||
if(conditions.get(i).isValid(parsePool))
|
||||
if(conditions.get(i).isValid(args))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package speiger.src.builder.misc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class RegexUtil
|
||||
{
|
||||
public static String searchUntil(String text, int startIndex, char increase, char decrease)
|
||||
|
@ -42,4 +45,32 @@ public class RegexUtil
|
|||
if(start == -1) return null;
|
||||
return new int[]{start, offset};
|
||||
}
|
||||
|
||||
public static int lastIndexOf(List<String> list, int startIndex, String increase, String decrease)
|
||||
{
|
||||
if(!list.get(startIndex).equalsIgnoreCase(increase)) return -1;
|
||||
int inc = 0;
|
||||
for(int i = startIndex;i<list.size();i++)
|
||||
{
|
||||
String entry = list.get(i);
|
||||
if(entry.equalsIgnoreCase(increase)) inc++;
|
||||
else if(entry.equalsIgnoreCase(decrease)) {
|
||||
inc--;
|
||||
if(inc <= 0) return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static String ensureWhitespaces(String s, Set<Character> set) {
|
||||
StringBuilder builder = new StringBuilder(s);
|
||||
for(int i = s.length()-1;i>=0;i--) {
|
||||
char entry = builder.charAt(i);
|
||||
if(entry != ' ' && set.contains(entry)) {
|
||||
if(builder.charAt(i+1) != ' ') builder.insert(i+1, ' ');
|
||||
if(builder.charAt(i-1) != ' ') builder.insert(i, ' ');
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ public class BuildTask implements Runnable
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
String s = template.build(process.parsePool, process.mappers, mappers != null, mappers != null ? mappers[1] : null);
|
||||
String s = template.build(new CompiledArguments(process), mappers != null, mappers != null ? mappers[1] : null);
|
||||
if(mappers != null)
|
||||
{
|
||||
mappers[0].addAll(process.mappers);
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package speiger.src.builder.processor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import speiger.src.builder.mappers.IMapper;
|
||||
|
||||
public class CompiledArguments
|
||||
{
|
||||
List<IMapper> mapper;
|
||||
Set<String> flags;
|
||||
Map<String, Integer> flaggedValues;
|
||||
|
||||
public CompiledArguments(TemplateProcess process)
|
||||
{
|
||||
mapper = process.mappers;
|
||||
flags = process.parsePool;
|
||||
flaggedValues = process.parseValues;
|
||||
}
|
||||
|
||||
public List<IMapper> getMapper()
|
||||
{
|
||||
return mapper;
|
||||
}
|
||||
|
||||
public boolean test(String key)
|
||||
{
|
||||
return flags.contains(key);
|
||||
}
|
||||
|
||||
public int get(String key)
|
||||
{
|
||||
return flaggedValues.getOrDefault(key, 0);
|
||||
}
|
||||
}
|
|
@ -4,8 +4,10 @@ import java.nio.file.Path;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
|
@ -16,6 +18,7 @@ public class TemplateProcess
|
|||
UnaryOperator<Path> pathBuilder;
|
||||
String fileName;
|
||||
Set<String> parsePool = new HashSet<>();
|
||||
Map<String, Integer> parseValues = new HashMap<>();
|
||||
List<IMapper> mappers = new ArrayList<>();
|
||||
|
||||
public TemplateProcess(String fileName)
|
||||
|
@ -41,6 +44,18 @@ public class TemplateProcess
|
|||
return this;
|
||||
}
|
||||
|
||||
public TemplateProcess addValue(String key, int value)
|
||||
{
|
||||
parseValues.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateProcess addValues(Map<String, Integer> values)
|
||||
{
|
||||
parseValues.putAll(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateProcess addMapper(IMapper mapper)
|
||||
{
|
||||
mappers.add(mapper);
|
||||
|
|
|
@ -158,7 +158,7 @@ public abstract class TemplateProcessor
|
|||
System.out.println("Finished Building ["+counters[0].get()+"] Files from ["+counters[1].get()+"] in "+(System.currentTimeMillis() - start)+"ms (Template Parsing: "+counters[2].get()+"ms (avg: "+((counters[2].get() / Math.max(1D, counters[1].get())))+"ms)");
|
||||
FileUtils.saveMappings(existing, dataFolder);
|
||||
afterFinish();
|
||||
System.out.print("Saved Changes");
|
||||
System.out.println("Saved Changes");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue