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' archivesBaseName = 'Simple Code Generator'
version = '1.1.4' version = '1.2.0'
apply plugin: 'maven' apply plugin: 'maven'
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {

View File

@ -2,12 +2,12 @@ package speiger.src.builder.base;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.StringJoiner; import java.util.StringJoiner;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import speiger.src.builder.conditions.ICondition; import speiger.src.builder.conditions.ICondition;
import speiger.src.builder.misc.IdGenerator; import speiger.src.builder.misc.IdGenerator;
import speiger.src.builder.processor.CompiledArguments;
public class ConditionedSegment public class ConditionedSegment
{ {
@ -27,13 +27,13 @@ public class ConditionedSegment
segments.add(segment); segments.add(segment);
} }
public int build(Set<String> parsePool, StringBuilder builder, int baseIndex) public int build(CompiledArguments process, StringBuilder builder, int baseIndex)
{ {
baseIndex += index; baseIndex += index;
int length = builder.length(); int length = builder.length();
for(int i = 0,m=segments.size();i<m;i++) 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; return builder.length() - length;
} }

View File

@ -2,9 +2,9 @@ package speiger.src.builder.base;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import speiger.src.builder.conditions.ICondition; import speiger.src.builder.conditions.ICondition;
import speiger.src.builder.processor.CompiledArguments;
public class Segment public class Segment
{ {
@ -19,14 +19,14 @@ public class Segment
this.segments = segments; 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); builder.insert(index, text);
for(int i = 0,offset=0,m=segments.size();i<m;i++) 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; return true;
} }

View File

@ -11,6 +11,7 @@ import java.util.StringJoiner;
import speiger.src.builder.mappers.IMapper; import speiger.src.builder.mappers.IMapper;
import speiger.src.builder.misc.FileUtils; import speiger.src.builder.misc.FileUtils;
import speiger.src.builder.misc.IdGenerator; import speiger.src.builder.misc.IdGenerator;
import speiger.src.builder.processor.CompiledArguments;
public class Template public class Template
{ {
@ -32,13 +33,14 @@ public class Template
return fileName; 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); StringBuilder builder = new StringBuilder(textFile);
for(int i = 0,offset=0,m=segments.size();i<m;i++) 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(); String result = builder.toString();
for(int i = 0,m=mappers.size();i<m;i++) 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.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import speiger.src.builder.processor.CompiledArguments;
public class AndCondition implements ICondition public class AndCondition implements ICondition
{ {
List<ICondition> conditions = new ArrayList<>(); List<ICondition> conditions = new ArrayList<>();
public AndCondition() {}
public AndCondition(ICondition base) public AndCondition(ICondition base)
{ {
conditions.add(base); addCondition(base);
} }
public void addCondition(ICondition e) public void addCondition(ICondition e)
{ {
if(e == null) return;
conditions.add(e); conditions.add(e);
} }
@Override @Override
public boolean isValid(Set<String> parsePool) public boolean isValid(CompiledArguments args)
{ {
for(int i = 0,m=conditions.size();i<m;i++) for(int i = 0,m=conditions.size();i<m;i++)
{ {
if(!conditions.get(i).isValid(parsePool)) if(!conditions.get(i).isValid(args))
{ {
return false; return false;
} }

View File

@ -1,6 +1,6 @@
package speiger.src.builder.conditions; package speiger.src.builder.conditions;
import java.util.Set; import speiger.src.builder.processor.CompiledArguments;
public class FlagCondition implements ICondition public class FlagCondition implements ICondition
{ {
@ -14,8 +14,8 @@ public class FlagCondition implements ICondition
} }
@Override @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; package speiger.src.builder.conditions;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import speiger.src.builder.misc.RegexUtil;
import speiger.src.builder.processor.CompiledArguments;
public interface ICondition public interface ICondition
{ {
public static final Set<Character> VALID_CHARACTERS = new HashSet<>(Arrays.asList('(', ')'));
public static final ICondition ALWAYS_TRUE = T -> true; 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) public static ICondition parse(List<String> elements) {
{ List<ICondition> conditions = new ArrayList<>();
String[] elements = condition.split(" "); AndCondition activeAnd = null;
List<ICondition> conditions = new ArrayList<ICondition>(); for(int i = 0,m=elements.size();i<m;i++) {
for(int i = 0;i<elements.length;i++) String entry = elements.get(i);
{ if(entry.equalsIgnoreCase("(")) {
if(elements[i].equalsIgnoreCase("&&")) int endIndex = RegexUtil.lastIndexOf(elements, i, "(", ")");
{ if(endIndex == -1) throw new IllegalStateException("A Condition Closer [ ) ] is missing");
if(i==elements.length-1) ICondition result = parse(elements.subList(i+1, endIndex));
{ if(activeAnd != null) activeAnd.addCondition(result);
continue; else conditions.add(result);
i = endIndex+1;
} }
if(condition.isEmpty()) else if(entry.equalsIgnoreCase("&&")) {
{ if(activeAnd != null) continue;
conditions.add(new AndCondition(parseSimpleCondition(elements[++i]))); if(i != 0) {
} ICondition prev = conditions.get(conditions.size()-1);
else if(prev instanceof AndCondition) activeAnd = (AndCondition)prev;
{ else {
ICondition con = conditions.get(conditions.size() - 1); activeAnd = new AndCondition(prev);
if(con instanceof AndCondition) conditions.set(conditions.size()-1, activeAnd);
{
((AndCondition)con).addCondition(parseSimpleCondition(elements[++i]));
}
else
{
AndCondition replacement = new AndCondition(con);
replacement.addCondition(parseSimpleCondition(elements[++i]));
conditions.set(conditions.size()-1, replacement);
} }
} }
else {
activeAnd = new AndCondition();
conditions.add(activeAnd);
} }
else if(!elements[i].equalsIgnoreCase("||")) }
{ else if(entry.equalsIgnoreCase("||")) {
conditions.add(parseSimpleCondition(elements[i])); activeAnd = null;
}
else {
if(activeAnd != null) activeAnd.addCondition(parseCondition(entry));
else conditions.add(parseCondition(entry));
} }
} }
switch(conditions.size()) 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); 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; package speiger.src.builder.conditions;
import java.util.List; import java.util.List;
import java.util.Set;
import speiger.src.builder.processor.CompiledArguments;
public class OrCondition implements ICondition public class OrCondition implements ICondition
{ {
@ -13,11 +14,11 @@ public class OrCondition implements ICondition
} }
@Override @Override
public boolean isValid(Set<String> parsePool) public boolean isValid(CompiledArguments args)
{ {
for(int i = 0,m=conditions.size();i<m;i++) for(int i = 0,m=conditions.size();i<m;i++)
{ {
if(conditions.get(i).isValid(parsePool)) if(conditions.get(i).isValid(args))
{ {
return true; return true;
} }

View File

@ -1,5 +1,8 @@
package speiger.src.builder.misc; package speiger.src.builder.misc;
import java.util.List;
import java.util.Set;
public class RegexUtil public class RegexUtil
{ {
public static String searchUntil(String text, int startIndex, char increase, char decrease) public static String searchUntil(String text, int startIndex, char increase, char decrease)
@ -42,4 +45,32 @@ public class RegexUtil
if(start == -1) return null; if(start == -1) return null;
return new int[]{start, offset}; 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 @Override
public void run() 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) if(mappers != null)
{ {
mappers[0].addAll(process.mappers); 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.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
@ -16,6 +18,7 @@ public class TemplateProcess
UnaryOperator<Path> pathBuilder; UnaryOperator<Path> pathBuilder;
String fileName; String fileName;
Set<String> parsePool = new HashSet<>(); Set<String> parsePool = new HashSet<>();
Map<String, Integer> parseValues = new HashMap<>();
List<IMapper> mappers = new ArrayList<>(); List<IMapper> mappers = new ArrayList<>();
public TemplateProcess(String fileName) public TemplateProcess(String fileName)
@ -41,6 +44,18 @@ public class TemplateProcess
return this; 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) public TemplateProcess addMapper(IMapper mapper)
{ {
mappers.add(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)"); 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); FileUtils.saveMappings(existing, dataFolder);
afterFinish(); afterFinish();
System.out.print("Saved Changes"); System.out.println("Saved Changes");
return true; return true;
} }
} }