Tweaking to handle empty lines a bit better for #18.

This commit is contained in:
Rob Greene 2018-11-21 14:34:03 -06:00
parent c43baf9c15
commit ceecbd49fa
3 changed files with 96 additions and 20 deletions

View File

@ -1,6 +1,7 @@
package io.github.applecommander.bastools.api;
import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
import io.github.applecommander.bastools.api.model.Line;
@ -24,26 +25,27 @@ public class Parser {
public Program parse() {
Program program = new Program();
while (!tokens.isEmpty()) {
Line line = readLine(program);
program.lines.add(line);
readLine(program).ifPresent(program.lines::add);
}
return program;
}
public Line readLine(Program program) {
Line line = new Line(expectNumber(), program);
while (!tokens.isEmpty() && tokens.peek().type != Type.EOL) {
Statement statement = readStatement();
if (statement != null) {
line.statements.add(statement);
} else {
break;
}
}
if (!tokens.isEmpty() && tokens.peek().type == Type.EOL) {
tokens.remove(); // Skip that EOL
}
return line;
public Optional<Line> readLine(Program program) {
return expectNumber().map(lineNumber -> {
Line line = new Line(lineNumber, program);
while (!tokens.isEmpty() && tokens.peek().type != Type.EOL) {
Statement statement = readStatement();
if (statement != null) {
line.statements.add(statement);
} else {
break;
}
}
if (!tokens.isEmpty() && tokens.peek().type == Type.EOL) {
tokens.remove(); // Skip that EOL
}
return line;
});
}
public Statement readStatement() {
@ -57,15 +59,14 @@ public class Parser {
return statement;
}
public int expectNumber() {
public Optional<Integer> expectNumber() {
Token c = tokens.remove();
while (c.type == Type.EOL) {
// Allow blank lines...
c = tokens.remove();
return Optional.empty();
}
if (c.type != Type.NUMBER) {
throw new RuntimeException("Expected a number in line #" + c.line);
}
return c.number.intValue();
return Optional.of(c.number.intValue());
}
}

View File

@ -0,0 +1,25 @@
package io.github.applecommander.bastools.api;
import java.util.Queue;
import org.junit.Assert;
import org.junit.Test;
import io.github.applecommander.bastools.api.model.Program;
import io.github.applecommander.bastools.api.model.Token;
import io.github.applecommander.bastools.api.utils.TokenBuilder;
public class ParserTest {
@Test
public void testBlankLines() {
Queue<Token> tokens = TokenBuilder.builder()
.eol() // Blank line before
.number(10.0).ident("A").syntax('=').number(42.0).eol()
.eol() // Blank line after
.tokens();
Parser parser = new Parser(tokens);
Program program = parser.parse();
Assert.assertNotNull(program);
}
}

View File

@ -0,0 +1,50 @@
package io.github.applecommander.bastools.api.utils;
import java.util.LinkedList;
import java.util.Queue;
import io.github.applecommander.bastools.api.model.ApplesoftKeyword;
import io.github.applecommander.bastools.api.model.Token;
public class TokenBuilder {
private int lineNumber;
private Queue<Token> tokens = new LinkedList<Token>();
public static TokenBuilder builder() {
return new TokenBuilder();
}
public TokenBuilder eol() {
add(Token.eol(lineNumber));
lineNumber += 1;
return this;
}
public TokenBuilder number(Double number) {
return add(Token.number(lineNumber, number));
}
public TokenBuilder ident(String text) {
return add(Token.ident(lineNumber, text));
}
public TokenBuilder comment(String text) {
return add(Token.comment(lineNumber, text));
}
public TokenBuilder string(String text) {
return add(Token.string(lineNumber, text));
}
public TokenBuilder keyword(ApplesoftKeyword keyword) {
return add(Token.keyword(lineNumber, keyword));
}
public TokenBuilder syntax(int ch) {
return add(Token.syntax(lineNumber, ch));
}
public TokenBuilder directive(String text) {
return add(Token.directive(lineNumber, text));
}
private TokenBuilder add(Token token) {
tokens.add(token);
return this;
}
public Queue<Token> tokens() {
return tokens;
}
}