mirror of
https://github.com/AppleCommander/bastools.git
synced 2024-05-29 10:41:32 +00:00
Tweaking to handle empty lines a bit better for #18.
This commit is contained in:
parent
c43baf9c15
commit
ceecbd49fa
|
@ -1,6 +1,7 @@
|
||||||
package io.github.applecommander.bastools.api;
|
package io.github.applecommander.bastools.api;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
||||||
import io.github.applecommander.bastools.api.model.Line;
|
import io.github.applecommander.bastools.api.model.Line;
|
||||||
|
@ -24,26 +25,27 @@ public class Parser {
|
||||||
public Program parse() {
|
public Program parse() {
|
||||||
Program program = new Program();
|
Program program = new Program();
|
||||||
while (!tokens.isEmpty()) {
|
while (!tokens.isEmpty()) {
|
||||||
Line line = readLine(program);
|
readLine(program).ifPresent(program.lines::add);
|
||||||
program.lines.add(line);
|
|
||||||
}
|
}
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Line readLine(Program program) {
|
public Optional<Line> readLine(Program program) {
|
||||||
Line line = new Line(expectNumber(), program);
|
return expectNumber().map(lineNumber -> {
|
||||||
while (!tokens.isEmpty() && tokens.peek().type != Type.EOL) {
|
Line line = new Line(lineNumber, program);
|
||||||
Statement statement = readStatement();
|
while (!tokens.isEmpty() && tokens.peek().type != Type.EOL) {
|
||||||
if (statement != null) {
|
Statement statement = readStatement();
|
||||||
line.statements.add(statement);
|
if (statement != null) {
|
||||||
} else {
|
line.statements.add(statement);
|
||||||
break;
|
} else {
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
if (!tokens.isEmpty() && tokens.peek().type == Type.EOL) {
|
}
|
||||||
tokens.remove(); // Skip that EOL
|
if (!tokens.isEmpty() && tokens.peek().type == Type.EOL) {
|
||||||
}
|
tokens.remove(); // Skip that EOL
|
||||||
return line;
|
}
|
||||||
|
return line;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Statement readStatement() {
|
public Statement readStatement() {
|
||||||
|
@ -57,15 +59,14 @@ public class Parser {
|
||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int expectNumber() {
|
public Optional<Integer> expectNumber() {
|
||||||
Token c = tokens.remove();
|
Token c = tokens.remove();
|
||||||
while (c.type == Type.EOL) {
|
while (c.type == Type.EOL) {
|
||||||
// Allow blank lines...
|
return Optional.empty();
|
||||||
c = tokens.remove();
|
|
||||||
}
|
}
|
||||||
if (c.type != Type.NUMBER) {
|
if (c.type != Type.NUMBER) {
|
||||||
throw new RuntimeException("Expected a number in line #" + c.line);
|
throw new RuntimeException("Expected a number in line #" + c.line);
|
||||||
}
|
}
|
||||||
return c.number.intValue();
|
return Optional.of(c.number.intValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user