mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-27 15:03:21 -04:00
simplified test data parser
This commit is contained in:
parent
a6759f0073
commit
ba776b8ba4
@ -43,7 +43,7 @@ public class Parser {
|
||||
*/
|
||||
public Parser parse() throws IOException, ParserException {
|
||||
parseHeader();
|
||||
emitter = parseValues(false);
|
||||
emitter = parseRows(false);
|
||||
expect(Tokenizer.Token.EOF);
|
||||
return this;
|
||||
}
|
||||
@ -69,7 +69,7 @@ public class Parser {
|
||||
return new ParserException(Lang.get("err_unexpectedToken_N0_inLine_N1", name, tok.getLine()));
|
||||
}
|
||||
|
||||
private LineEmitter parseValues(boolean loop) throws IOException, ParserException {
|
||||
private LineEmitter parseRows(boolean loop) throws IOException, ParserException {
|
||||
LineEmitterList list = new LineEmitterList();
|
||||
while (true) {
|
||||
Tokenizer.Token t = tok.peek();
|
||||
@ -80,40 +80,38 @@ public class Parser {
|
||||
if (loop)
|
||||
throw newUnexpectedToken(t);
|
||||
return list.minimize();
|
||||
case NUMBER:
|
||||
list.add(parseLine());
|
||||
break;
|
||||
case BITS:
|
||||
case OPEN:
|
||||
case IDENT:
|
||||
if (tok.getIdent().equals("end")) {
|
||||
tok.consume();
|
||||
expect(Tokenizer.Token.IDENT);
|
||||
if (!tok.getIdent().equals("loop"))
|
||||
throw newUnexpectedToken(t);
|
||||
if (!loop)
|
||||
throw newUnexpectedToken(t);
|
||||
return list.minimize();
|
||||
} else if (tok.getIdent().equals("repeat")) {
|
||||
tok.consume();
|
||||
expect(Tokenizer.Token.OPEN);
|
||||
int count = (int) parseInt();
|
||||
if (count > 1 << 16)
|
||||
throw new ParserException(Lang.get("err_toManyTestEntries"));
|
||||
expect(Tokenizer.Token.CLOSE);
|
||||
list.add(new LineEmitterRepeat("n", count, parseLine()));
|
||||
} else if (tok.getIdent().equals("loop")) {
|
||||
tok.consume();
|
||||
expect(Tokenizer.Token.OPEN);
|
||||
expect(Tokenizer.Token.IDENT);
|
||||
String var = tok.getIdent();
|
||||
expect(Tokenizer.Token.COMMA);
|
||||
int count = (int) parseInt();
|
||||
if (count > 1 << 16)
|
||||
throw new ParserException(Lang.get("err_toManyTestEntries"));
|
||||
expect(Tokenizer.Token.CLOSE);
|
||||
list.add(new LineEmitterRepeat(var, count, parseValues(true)));
|
||||
} else {
|
||||
list.add(parseLine());
|
||||
}
|
||||
case NUMBER:
|
||||
list.add(parseSingleRow());
|
||||
break;
|
||||
case END:
|
||||
tok.consume();
|
||||
expect(Tokenizer.Token.LOOP);
|
||||
if (!loop)
|
||||
throw newUnexpectedToken(t);
|
||||
return list.minimize();
|
||||
case REPEAT:
|
||||
tok.consume();
|
||||
expect(Tokenizer.Token.OPEN);
|
||||
int count = (int) parseInt();
|
||||
if (count > 1 << 16)
|
||||
throw new ParserException(Lang.get("err_toManyTestEntries"));
|
||||
expect(Tokenizer.Token.CLOSE);
|
||||
list.add(new LineEmitterRepeat("n", count, parseSingleRow()));
|
||||
break;
|
||||
case LOOP:
|
||||
tok.consume();
|
||||
expect(Tokenizer.Token.OPEN);
|
||||
expect(Tokenizer.Token.IDENT);
|
||||
String var = tok.getIdent();
|
||||
expect(Tokenizer.Token.COMMA);
|
||||
count = (int) parseInt();
|
||||
if (count > 1 << 16)
|
||||
throw new ParserException(Lang.get("err_toManyTestEntries"));
|
||||
expect(Tokenizer.Token.CLOSE);
|
||||
list.add(new LineEmitterRepeat(var, count, parseRows(true)));
|
||||
break;
|
||||
default:
|
||||
throw newUnexpectedToken(t);
|
||||
@ -121,7 +119,7 @@ public class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
private LineEmitter parseLine() throws IOException, ParserException {
|
||||
private LineEmitter parseSingleRow() throws IOException, ParserException {
|
||||
LineEmitterSimple line = null;
|
||||
while (true) {
|
||||
Tokenizer.Token token = tok.next();
|
||||
@ -132,25 +130,24 @@ public class Parser {
|
||||
Value num = new Value(tok.getIdent());
|
||||
line.add((vals, conext) -> vals.add(num));
|
||||
break;
|
||||
case BITS:
|
||||
expect(Tokenizer.Token.OPEN);
|
||||
int bitCount = (int) parseInt();
|
||||
expect(Tokenizer.Token.COMMA);
|
||||
Expression exp = parseExpression();
|
||||
line.add(new ValueAppenderBits(bitCount, exp));
|
||||
expect(Tokenizer.Token.CLOSE);
|
||||
break;
|
||||
case IDENT:
|
||||
if (tok.getIdent().equals("bits")) {
|
||||
expect(Tokenizer.Token.OPEN);
|
||||
int bitCount = (int) parseInt();
|
||||
expect(Tokenizer.Token.COMMA);
|
||||
Expression exp = parseExpression();
|
||||
line.add(new ValueAppenderBits(bitCount, exp));
|
||||
expect(Tokenizer.Token.CLOSE);
|
||||
} else {
|
||||
try {
|
||||
final Value value = new Value(tok.getIdent().toUpperCase());
|
||||
line.add((vals, context) -> vals.add(value));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ParserException(Lang.get("err_notANumber_N0_inLine_N1", tok.getIdent(), tok.getLine()));
|
||||
}
|
||||
try {
|
||||
final Value value = new Value(tok.getIdent().toUpperCase());
|
||||
line.add((vals, context) -> vals.add(value));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ParserException(Lang.get("err_notANumber_N0_inLine_N1", tok.getIdent(), tok.getLine()));
|
||||
}
|
||||
break;
|
||||
case OPEN:
|
||||
Expression exp = parseExpression();
|
||||
exp = parseExpression();
|
||||
line.add((vals, context) -> vals.add(new Value((int) exp.value(context))));
|
||||
expect(Tokenizer.Token.CLOSE);
|
||||
break;
|
||||
|
@ -2,6 +2,7 @@ package de.neemann.digital.testing.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Simple tokenizer to tokenize boolean expressions.
|
||||
@ -10,7 +11,19 @@ import java.io.Reader;
|
||||
*/
|
||||
public class Tokenizer {
|
||||
|
||||
enum Token {UNKNOWN, IDENT, AND, OR, NOT, OPEN, CLOSE, NUMBER, EOL, EOF, SHIFTLEFT, SHIFTRIGHT, COMMA, EQUAL, ADD, SUB, MUL, GREATER, SMALER, DIV}
|
||||
enum Token {
|
||||
UNKNOWN, IDENT, AND, OR, NOT, OPEN, CLOSE, NUMBER, EOL, EOF, SHIFTLEFT, SHIFTRIGHT, COMMA, EQUAL,
|
||||
ADD, SUB, MUL, GREATER, SMALER, DIV, END, LOOP, REPEAT, BITS
|
||||
}
|
||||
|
||||
private static HashMap<String, Token> statementMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
statementMap.put("end", Token.END);
|
||||
statementMap.put("loop", Token.LOOP);
|
||||
statementMap.put("repeat", Token.REPEAT);
|
||||
statementMap.put("bits", Token.BITS);
|
||||
}
|
||||
|
||||
private final Reader in;
|
||||
private Token token;
|
||||
@ -136,6 +149,8 @@ public class Tokenizer {
|
||||
wasChar = false;
|
||||
}
|
||||
} while (wasChar);
|
||||
token = statementMap.get(builder.toString());
|
||||
if (token == null) token = Token.IDENT;
|
||||
} else if (isNumberChar(c)) {
|
||||
token = Token.NUMBER;
|
||||
builder.setLength(0);
|
||||
|
@ -37,7 +37,7 @@ public class ParserLoopTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testNested() throws IOException, ParserException {
|
||||
Parser parser = new Parser("A B\nloop(i,10)\nloop(j,10)\n C ((i+j)*2)\nend loop\nend loop").parse();
|
||||
Parser parser = new Parser("A B\nloop(i,10)\nloop(j,10)\n C (i+j*2)\nend loop\nend loop").parse();
|
||||
LineCollector td = new LineCollector(parser);
|
||||
|
||||
assertEquals(2, td.getNames().size());
|
||||
@ -47,7 +47,7 @@ public class ParserLoopTest extends TestCase {
|
||||
for (int j = 0; j < 10; j++) {
|
||||
int ind = i * 10 + j;
|
||||
assertEquals(Value.Type.CLOCK, td.getLines().get(ind)[0].getType());
|
||||
assertEquals((i + j) * 2, td.getLines().get(ind)[1].getValue());
|
||||
assertEquals(i + j * 2, td.getLines().get(ind)[1].getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -69,7 +69,7 @@ public class ParserLoopTest extends TestCase {
|
||||
|
||||
public void testMissingEndLoop() throws IOException, ParserException {
|
||||
try {
|
||||
new Parser("A B\nloop(i,10) C ((i+j)*2)").parse();
|
||||
new Parser("A B\nloop(i,10) C (i)").parse();
|
||||
fail();
|
||||
} catch (ParserException e) {
|
||||
}
|
||||
@ -77,7 +77,7 @@ public class ParserLoopTest extends TestCase {
|
||||
|
||||
public void testUnexpectedEndLoop() throws IOException, ParserException {
|
||||
try {
|
||||
new Parser("A B\n C ((i+j)*2)\nend loop").parse();
|
||||
new Parser("A B\n C 1\nend loop").parse();
|
||||
fail();
|
||||
} catch (ParserException e) {
|
||||
}
|
||||
@ -85,7 +85,7 @@ public class ParserLoopTest extends TestCase {
|
||||
|
||||
public void testIncompleteEndLoop() throws IOException, ParserException {
|
||||
try {
|
||||
new Parser("A B\n C ((i+j)*2)\nend").parse();
|
||||
new Parser("A B\n C 1\nend").parse();
|
||||
fail();
|
||||
} catch (ParserException e) {
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user