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:
Speiger 2022-12-13 13:02:25 +01:00
parent 6e5e91d0bd
commit a63defacbb
14 changed files with 271 additions and 56 deletions

View File

@ -5,7 +5,7 @@ repositories {
}
archivesBaseName = 'Simple Code Generator'
version = '1.1.4'
version = '1.2.0'
apply plugin: 'maven'
tasks.withType(JavaCompile) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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++)
{

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 boolean isValid(CompiledArguments args);
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 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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;
}
}