account for dangling opening/closing brace

This commit is contained in:
dfsek
2020-12-20 01:43:50 -07:00
parent 2880c29f8c
commit c4f927e72c
3 changed files with 14 additions and 9 deletions
@@ -1,13 +1,12 @@
package com.dfsek.terra.api.structures.parser; package com.dfsek.terra.api.structures.parser;
import com.dfsek.terra.api.structures.parser.exceptions.ParseException; import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
import com.dfsek.terra.api.structures.parser.lang.Argument;
import com.dfsek.terra.api.structures.parser.lang.Function; import com.dfsek.terra.api.structures.parser.lang.Function;
import java.util.List; import java.util.List;
public interface FunctionBuilder<T extends Function> { public interface FunctionBuilder<T extends Function<?>> {
T build(List<String> argumentList) throws ParseException; T build(List<String> argumentList) throws ParseException;
List<Argument<?>> getArguments(); int getArguments();
} }
@@ -45,6 +45,14 @@ public class Parser {
} catch(TokenizerException e) { } catch(TokenizerException e) {
throw new ParseException("Failed to tokenize input", e); throw new ParseException("Failed to tokenize input", e);
} }
// Check for dangling brackets
int blockLevel = 0;
for(Token t : tokens) {
if(t.getType().equals(Token.Type.BLOCK_BEGIN)) blockLevel++;
else if(t.getType().equals(Token.Type.BLOCK_END)) blockLevel--;
if(blockLevel < 0) throw new ParseException("Dangling closing brace: " + t.getStart());
}
if(blockLevel != 0) throw new ParseException("Dangling opening brace");
return parseBlock(tokens); return parseBlock(tokens);
} }
@@ -121,8 +129,8 @@ public class Parser {
List<String> arg = args.stream().map(Token::getContent).collect(Collectors.toList()); List<String> arg = args.stream().map(Token::getContent).collect(Collectors.toList());
FunctionBuilder<?> builder = functions.get(identifier.getContent()); FunctionBuilder<?> builder = functions.get(identifier.getContent());
if(arg.size() != builder.getArguments().size()) if(arg.size() != builder.getArguments() && builder.getArguments() != -1)
throw new ParseException("Expected " + builder.getArguments().size() + " arguments, found " + arg.size() + ": " + identifier.getStart()); throw new ParseException("Expected " + builder.getArguments() + " arguments, found " + arg.size() + ": " + identifier.getStart());
return functions.get(identifier.getContent()).build(arg); return functions.get(identifier.getContent()).build(arg);
} }
@@ -5,14 +5,12 @@ import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.structures.parser.FunctionBuilder; import com.dfsek.terra.api.structures.parser.FunctionBuilder;
import com.dfsek.terra.api.structures.parser.Parser; import com.dfsek.terra.api.structures.parser.Parser;
import com.dfsek.terra.api.structures.parser.exceptions.ParseException; import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
import com.dfsek.terra.api.structures.parser.lang.Argument;
import com.dfsek.terra.api.structures.parser.lang.Function; import com.dfsek.terra.api.structures.parser.lang.Function;
import com.dfsek.terra.api.structures.parser.lang.Item; import com.dfsek.terra.api.structures.parser.lang.Item;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
public class ParserTest { public class ParserTest {
@@ -27,8 +25,8 @@ public class ParserTest {
} }
@Override @Override
public List<Argument<?>> getArguments() { public int getArguments() {
return Arrays.asList(id -> id, Double::parseDouble); return 2;
} }
}); });