mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-18 17:34:43 -04:00
some cleanup
This commit is contained in:
parent
1e29779cbb
commit
4c654fdb60
@ -56,8 +56,8 @@ public class Parser {
|
||||
String text = tok.readText();
|
||||
if (text.length() > 0)
|
||||
s.add(c -> c.print(text));
|
||||
while (!isToken(EOF)) {
|
||||
if (isToken(STATIC)) {
|
||||
while (!nextIs(EOF)) {
|
||||
if (nextIs(STATIC)) {
|
||||
Statement stat = parseStatement();
|
||||
try {
|
||||
stat.execute(staticContext);
|
||||
@ -81,51 +81,57 @@ public class Parser {
|
||||
return parseStatement(true);
|
||||
}
|
||||
|
||||
private Statement parseStatement(boolean semicolon) throws IOException, ParserException {
|
||||
if (isToken(IDENT)) {
|
||||
/**
|
||||
* If 'isRealStatement' is false, the statement is parsed like an expression.
|
||||
* This mode is needed to implement the 'for' loop. In a C style for loop the pre and the
|
||||
* post code are expressions, which modify state, which is not supported by HGS. In the HGS
|
||||
* for loop the pre and the post code are statements where the semicolon at the end is omitted.
|
||||
*/
|
||||
private Statement parseStatement(boolean isRealStatement) throws IOException, ParserException {
|
||||
if (nextIs(IDENT)) {
|
||||
Reference ref = parseReference(tok.getIdent());
|
||||
if (isToken(EQUAL)) {
|
||||
if (nextIs(EQUAL)) {
|
||||
Expression val = parseExpression();
|
||||
if (semicolon) expect(SEMICOLON);
|
||||
if (isRealStatement) expect(SEMICOLON);
|
||||
return c -> ref.set(c, val.value(c));
|
||||
} else if (isToken(ADD)) {
|
||||
} else if (nextIs(ADD)) {
|
||||
expect(ADD);
|
||||
if (semicolon) expect(SEMICOLON);
|
||||
if (isRealStatement) expect(SEMICOLON);
|
||||
return c -> ref.set(c, Value.toLong(ref.get(c)) + 1);
|
||||
} else if (isToken(SUB)) {
|
||||
} else if (nextIs(SUB)) {
|
||||
expect(SUB);
|
||||
if (semicolon) expect(SEMICOLON);
|
||||
if (isRealStatement) expect(SEMICOLON);
|
||||
return c -> ref.set(c, Value.toLong(ref.get(c)) - 1);
|
||||
} else if (isToken(SEMICOLON)) {
|
||||
} else if (nextIs(SEMICOLON)) {
|
||||
return ref::get;
|
||||
} else
|
||||
throw newUnexpectedToken(tok.next());
|
||||
} else if (isToken(CODEEND)) {
|
||||
} else if (nextIs(CODEEND)) {
|
||||
String str = tok.readText();
|
||||
return c -> c.print(str);
|
||||
} else if (isToken(EQUAL)) {
|
||||
} else if (nextIs(EQUAL)) {
|
||||
Expression exp = parseExpression();
|
||||
if (tok.peek() != CODEEND) expect(SEMICOLON);
|
||||
return c -> c.print(exp.value(c).toString());
|
||||
} else if (isToken(PRINT)) {
|
||||
} else if (nextIs(PRINT)) {
|
||||
expect(OPEN);
|
||||
ArrayList<Expression> args = parseArgList();
|
||||
if (semicolon) expect(SEMICOLON);
|
||||
if (isRealStatement) expect(SEMICOLON);
|
||||
return c -> {
|
||||
for (Expression e : args)
|
||||
c.print(e.value(c).toString());
|
||||
};
|
||||
} else if (isToken(PRINTF)) {
|
||||
} else if (nextIs(PRINTF)) {
|
||||
expect(OPEN);
|
||||
ArrayList<Expression> args = parseArgList();
|
||||
if (semicolon) expect(SEMICOLON);
|
||||
if (isRealStatement) expect(SEMICOLON);
|
||||
return c -> c.print(FunctionFormat.format(c, args));
|
||||
} else if (isToken(IF)) {
|
||||
} else if (nextIs(IF)) {
|
||||
expect(OPEN);
|
||||
Expression cond = parseExpression();
|
||||
expect(CLOSE);
|
||||
Statement ifPart = parseStatement();
|
||||
if (isToken(ELSE)) {
|
||||
if (nextIs(ELSE)) {
|
||||
Statement elsePart = parseStatement();
|
||||
return c -> {
|
||||
if (Value.toBool(cond.value(c)))
|
||||
@ -138,14 +144,13 @@ public class Parser {
|
||||
if (Value.toBool(cond.value(c)))
|
||||
ifPart.execute(c);
|
||||
};
|
||||
|
||||
} else if (isToken(FOR)) {
|
||||
} else if (nextIs(FOR)) {
|
||||
expect(OPEN);
|
||||
Statement init = parseStatement(false);
|
||||
Statement init = parseStatement(false); // parse like an expression
|
||||
expect(SEMICOLON);
|
||||
Expression cond = parseExpression();
|
||||
expect(SEMICOLON);
|
||||
Statement inc = parseStatement(false);
|
||||
Statement inc = parseStatement(false); // parse like an expression
|
||||
expect(CLOSE);
|
||||
Statement inner = parseStatement();
|
||||
return c -> {
|
||||
@ -155,16 +160,24 @@ public class Parser {
|
||||
inc.execute(c);
|
||||
}
|
||||
};
|
||||
} else if (isToken(OPENBRACE)) {
|
||||
} else if (nextIs(WHILE)) {
|
||||
expect(OPEN);
|
||||
Expression cond = parseExpression();
|
||||
expect(CLOSE);
|
||||
Statement inner = parseStatement();
|
||||
return c -> {
|
||||
while (Value.toBool(cond.value(c))) inner.execute(c);
|
||||
};
|
||||
} else if (nextIs(OPENBRACE)) {
|
||||
Statements s = new Statements();
|
||||
while (!isToken(CLOSEDBRACE))
|
||||
while (!nextIs(CLOSEDBRACE))
|
||||
s.add(parseStatement());
|
||||
return s.optimize();
|
||||
} else if (isToken(PANIC)) {
|
||||
} else if (nextIs(PANIC)) {
|
||||
expect(OPEN);
|
||||
Expression message = parseExpression();
|
||||
expect(CLOSE);
|
||||
if (semicolon) expect(SEMICOLON);
|
||||
if (isRealStatement) expect(SEMICOLON);
|
||||
return c -> {
|
||||
throw new HGSEvalException(message.value(c).toString());
|
||||
};
|
||||
@ -174,9 +187,9 @@ public class Parser {
|
||||
|
||||
private ArrayList<Expression> parseArgList() throws IOException, ParserException {
|
||||
ArrayList<Expression> args = new ArrayList<>();
|
||||
if (!isToken(CLOSE)) {
|
||||
if (!nextIs(CLOSE)) {
|
||||
args.add(parseExpression());
|
||||
while (isToken(COMMA))
|
||||
while (nextIs(COMMA))
|
||||
args.add(parseExpression());
|
||||
expect(CLOSE);
|
||||
}
|
||||
@ -186,14 +199,14 @@ public class Parser {
|
||||
private Reference parseReference(String var) throws IOException, ParserException {
|
||||
Reference r = new ReferenceToVar(var);
|
||||
while (true) {
|
||||
if (isToken(OPENSQUARE)) {
|
||||
if (nextIs(OPENSQUARE)) {
|
||||
Expression index = parseExpression();
|
||||
expect(CLOSEDSQUARE);
|
||||
r = new ReferenceToArray(r, index);
|
||||
} else if (isToken(OPEN)) {
|
||||
} else if (nextIs(OPEN)) {
|
||||
ArrayList<Expression> args = parseArgList();
|
||||
r = new ReferenceToFunc(r, args);
|
||||
} else if (isToken(DOT)) {
|
||||
} else if (nextIs(DOT)) {
|
||||
expect(IDENT);
|
||||
r = new ReferenceToStruct(r, tok.getIdent());
|
||||
} else
|
||||
@ -201,7 +214,7 @@ public class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isToken(Tokenizer.Token t) throws IOException {
|
||||
private boolean nextIs(Tokenizer.Token t) throws IOException {
|
||||
if (tok.peek() == t) {
|
||||
tok.next();
|
||||
return true;
|
||||
@ -247,7 +260,7 @@ public class Parser {
|
||||
|
||||
private Expression parseExpression() throws IOException, ParserException {
|
||||
Expression ac = parseLessEquals();
|
||||
while (isToken(Tokenizer.Token.LESS)) {
|
||||
while (nextIs(Tokenizer.Token.LESS)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseLessEquals();
|
||||
ac = c -> Value.toLong(a.value(c)) < Value.toLong(b.value(c));
|
||||
@ -257,7 +270,7 @@ public class Parser {
|
||||
|
||||
private Expression parseLessEquals() throws IOException, ParserException {
|
||||
Expression ac = parseGreater();
|
||||
while (isToken(Tokenizer.Token.LESSEQUAL)) {
|
||||
while (nextIs(Tokenizer.Token.LESSEQUAL)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseGreater();
|
||||
ac = c -> Value.toLong(a.value(c)) <= Value.toLong(b.value(c));
|
||||
@ -267,7 +280,7 @@ public class Parser {
|
||||
|
||||
private Expression parseGreater() throws IOException, ParserException {
|
||||
Expression ac = parseGreaterEquals();
|
||||
while (isToken(Tokenizer.Token.GREATER)) {
|
||||
while (nextIs(Tokenizer.Token.GREATER)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseGreaterEquals();
|
||||
ac = c -> Value.toLong(a.value(c)) > Value.toLong(b.value(c));
|
||||
@ -277,7 +290,7 @@ public class Parser {
|
||||
|
||||
private Expression parseGreaterEquals() throws IOException, ParserException {
|
||||
Expression ac = parseEquals();
|
||||
while (isToken(Tokenizer.Token.GREATEREQUAL)) {
|
||||
while (nextIs(Tokenizer.Token.GREATEREQUAL)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseEquals();
|
||||
ac = c -> Value.toLong(a.value(c)) >= Value.toLong(b.value(c));
|
||||
@ -287,7 +300,7 @@ public class Parser {
|
||||
|
||||
private Expression parseEquals() throws IOException, ParserException {
|
||||
Expression ac = parseNotEquals();
|
||||
while (isToken(Tokenizer.Token.EQUAL)) {
|
||||
while (nextIs(Tokenizer.Token.EQUAL)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseNotEquals();
|
||||
ac = c -> Value.equals(a.value(c), b.value(c));
|
||||
@ -297,7 +310,7 @@ public class Parser {
|
||||
|
||||
private Expression parseNotEquals() throws IOException, ParserException {
|
||||
Expression ac = parseOR();
|
||||
while (isToken(Tokenizer.Token.NOTEQUAL)) {
|
||||
while (nextIs(Tokenizer.Token.NOTEQUAL)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseOR();
|
||||
ac = c -> !Value.equals(a.value(c), b.value(c));
|
||||
@ -307,7 +320,7 @@ public class Parser {
|
||||
|
||||
private Expression parseOR() throws IOException, ParserException {
|
||||
Expression ac = parseXOR();
|
||||
while (isToken(Tokenizer.Token.OR)) {
|
||||
while (nextIs(Tokenizer.Token.OR)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseXOR();
|
||||
ac = c -> Value.or(a.value(c), b.value(c));
|
||||
@ -317,7 +330,7 @@ public class Parser {
|
||||
|
||||
private Expression parseXOR() throws IOException, ParserException {
|
||||
Expression ac = parseAND();
|
||||
while (isToken(Tokenizer.Token.XOR)) {
|
||||
while (nextIs(Tokenizer.Token.XOR)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseAND();
|
||||
ac = c -> Value.xor(a.value(c), b.value(c));
|
||||
@ -327,7 +340,7 @@ public class Parser {
|
||||
|
||||
private Expression parseAND() throws IOException, ParserException {
|
||||
Expression ac = parseShiftRight();
|
||||
while (isToken(Tokenizer.Token.AND)) {
|
||||
while (nextIs(Tokenizer.Token.AND)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseShiftRight();
|
||||
ac = c -> Value.and(a.value(c), b.value(c));
|
||||
@ -337,7 +350,7 @@ public class Parser {
|
||||
|
||||
private Expression parseShiftRight() throws IOException, ParserException {
|
||||
Expression ac = parseShiftLeft();
|
||||
while (isToken(Tokenizer.Token.SHIFTRIGHT)) {
|
||||
while (nextIs(Tokenizer.Token.SHIFTRIGHT)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseShiftLeft();
|
||||
ac = c -> Value.toLong(a.value(c)) >> Value.toLong(b.value(c));
|
||||
@ -347,7 +360,7 @@ public class Parser {
|
||||
|
||||
private Expression parseShiftLeft() throws IOException, ParserException {
|
||||
Expression ac = parseAdd();
|
||||
while (isToken(Tokenizer.Token.SHIFTLEFT)) {
|
||||
while (nextIs(Tokenizer.Token.SHIFTLEFT)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseAdd();
|
||||
ac = c -> Value.toLong(a.value(c)) << Value.toLong(b.value(c));
|
||||
@ -357,7 +370,7 @@ public class Parser {
|
||||
|
||||
private Expression parseAdd() throws IOException, ParserException {
|
||||
Expression ac = parseSub();
|
||||
while (isToken(Tokenizer.Token.ADD)) {
|
||||
while (nextIs(Tokenizer.Token.ADD)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseSub();
|
||||
ac = c -> Value.add(a.value(c), b.value(c));
|
||||
@ -367,7 +380,7 @@ public class Parser {
|
||||
|
||||
private Expression parseSub() throws IOException, ParserException {
|
||||
Expression ac = parseMul();
|
||||
while (isToken(Tokenizer.Token.SUB)) {
|
||||
while (nextIs(Tokenizer.Token.SUB)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseMul();
|
||||
ac = c -> Value.toLong(a.value(c)) - Value.toLong(b.value(c));
|
||||
@ -377,7 +390,7 @@ public class Parser {
|
||||
|
||||
private Expression parseMul() throws IOException, ParserException {
|
||||
Expression ac = parseDiv();
|
||||
while (isToken(Tokenizer.Token.MUL)) {
|
||||
while (nextIs(Tokenizer.Token.MUL)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseDiv();
|
||||
ac = c -> Value.toLong(a.value(c)) * Value.toLong(b.value(c));
|
||||
@ -387,7 +400,7 @@ public class Parser {
|
||||
|
||||
private Expression parseDiv() throws IOException, ParserException {
|
||||
Expression ac = parseMod();
|
||||
while (isToken(Tokenizer.Token.DIV)) {
|
||||
while (nextIs(Tokenizer.Token.DIV)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseMod();
|
||||
ac = c -> Value.toLong(a.value(c)) / Value.toLong(b.value(c));
|
||||
@ -397,7 +410,7 @@ public class Parser {
|
||||
|
||||
private Expression parseMod() throws IOException, ParserException {
|
||||
Expression ac = parseIdent();
|
||||
while (isToken(Tokenizer.Token.MOD)) {
|
||||
while (nextIs(Tokenizer.Token.MOD)) {
|
||||
Expression a = ac;
|
||||
Expression b = parseIdent();
|
||||
ac = c -> Value.toLong(a.value(c)) % Value.toLong(b.value(c));
|
||||
@ -439,10 +452,10 @@ public class Parser {
|
||||
private FirstClassFunction parseFunction() throws IOException, ParserException {
|
||||
expect(OPEN);
|
||||
ArrayList<String> args = new ArrayList<>();
|
||||
if (!isToken(CLOSE)) {
|
||||
if (!nextIs(CLOSE)) {
|
||||
expect(IDENT);
|
||||
args.add(tok.getIdent());
|
||||
while (!isToken(CLOSE)) {
|
||||
while (!nextIs(CLOSE)) {
|
||||
expect(COMMA);
|
||||
expect(IDENT);
|
||||
args.add(tok.getIdent());
|
||||
|
@ -26,7 +26,7 @@ class Tokenizer {
|
||||
statementMap.put("if", Token.IF);
|
||||
statementMap.put("else", Token.ELSE);
|
||||
statementMap.put("for", Token.FOR);
|
||||
statementMap.put("while", Token.FOR);
|
||||
statementMap.put("while", Token.WHILE);
|
||||
statementMap.put("print", Token.PRINT);
|
||||
statementMap.put("printf", Token.PRINTF);
|
||||
statementMap.put("func", Token.FUNC);
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
package de.neemann.digital.core.element;
|
||||
|
||||
import de.neemann.digital.core.memory.DataField;
|
||||
import de.neemann.digital.hdl.hgs.Context;
|
||||
import de.neemann.digital.hdl.hgs.HGSEvalException;
|
||||
import de.neemann.digital.hdl.hgs.Parser;
|
||||
import de.neemann.digital.hdl.hgs.ParserException;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ElementAttributesTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Ensures that the ElementAtributes is accessible from within the template engine
|
||||
*/
|
||||
public void testElementAttibutes() throws IOException, ParserException, HGSEvalException {
|
||||
ElementAttributes attr = new ElementAttributes().set(Keys.BITS, 5);
|
||||
final Context c = new Context().setVar("elem", attr);
|
||||
new Parser("bits=<?=elem.Bits?>;").parse().execute(c);
|
||||
assertEquals("bits=5;", c.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the DataField is accessible from within the template engine
|
||||
*/
|
||||
public void testDataField() throws IOException, ParserException, HGSEvalException {
|
||||
DataField d = new DataField(5)
|
||||
.setData(0, 1)
|
||||
.setData(1, 7)
|
||||
.setData(2, 4)
|
||||
.setData(3, 8)
|
||||
.setData(4, 2);
|
||||
Context c= new Context().setVar("d", d);
|
||||
new Parser("(<? for(i=0;i<sizeOf(d);i++) { if (i>0) print(\"-\"); print(d[i]);} ?>)").parse().execute(c);
|
||||
assertEquals("(1-7-4-8-2)", c.toString());
|
||||
}
|
||||
|
||||
}
|
@ -5,9 +5,6 @@
|
||||
*/
|
||||
package de.neemann.digital.hdl.hgs;
|
||||
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.core.memory.DataField;
|
||||
import de.neemann.digital.hdl.hgs.function.FirstClassFunction;
|
||||
import de.neemann.digital.hdl.hgs.function.FuncAdapter;
|
||||
import de.neemann.digital.integration.FileScanner;
|
||||
@ -150,6 +147,8 @@ public class ParserTest extends TestCase {
|
||||
assertEquals("Hello -4-5- World!", c.toString());
|
||||
}
|
||||
|
||||
// for statement
|
||||
|
||||
public void testParseTemplateFor() throws IOException, ParserException, HGSEvalException {
|
||||
Context c = exec("Hello <? for (i=0;i<10;i++) print(i); ?> World!");
|
||||
assertEquals("Hello 0123456789 World!", c.toString());
|
||||
@ -178,30 +177,11 @@ public class ParserTest extends TestCase {
|
||||
assertEquals("Hello (12)(24)(36) World!", c.toString());
|
||||
}
|
||||
|
||||
// while statement
|
||||
|
||||
public void testParseTemplateElementAttibutes() throws IOException, ParserException, HGSEvalException {
|
||||
ElementAttributes attr = new ElementAttributes().set(Keys.BITS, 5);
|
||||
Context c = exec("bits=<?=elem.Bits?>;", new Context().setVar("elem", attr));
|
||||
assertEquals("bits=5;", c.toString());
|
||||
}
|
||||
|
||||
public void testParseTemplateDataField() throws IOException, ParserException, HGSEvalException {
|
||||
DataField d = new DataField(5)
|
||||
.setData(0, 1)
|
||||
.setData(1, 7)
|
||||
.setData(2, 4)
|
||||
.setData(3, 8)
|
||||
.setData(4, 2);
|
||||
Context c = exec("(<? for(i=0;i<sizeOf(d);i++) { if (i>0) print(\"-\"); print(d[i]);} ?>)",
|
||||
new Context().setVar("d", d));
|
||||
assertEquals("(1-7-4-8-2)", c.toString());
|
||||
}
|
||||
|
||||
public void testParseTemplateFormat() throws IOException, ParserException, HGSEvalException {
|
||||
ElementAttributes attr = new ElementAttributes().set(Keys.BITS, 17);
|
||||
Context c = new Context().setVar("elem", attr);
|
||||
exec("<? a=format(\"hex=%x;\",elem.Bits); print(a);?>", c);
|
||||
assertEquals("hex=11;", c.toString());
|
||||
public void testParseTemplateWhile() throws IOException, ParserException, HGSEvalException {
|
||||
Context c = exec("Hello <? i=0; while (i<=9) { =i; i++; } ?> World!");
|
||||
assertEquals("Hello 0123456789 World!", c.toString());
|
||||
}
|
||||
|
||||
public void testParseTemplateArray() throws IOException, ParserException, HGSEvalException {
|
||||
@ -249,13 +229,19 @@ public class ParserTest extends TestCase {
|
||||
assertEquals("4;", exec(t, new Context().setVar("m", 4)).toString());
|
||||
}
|
||||
|
||||
public void testParseTemplateFormat() throws IOException, ParserException, HGSEvalException {
|
||||
Context c = new Context().setVar("Bits", 17);
|
||||
exec("<? a=format(\"hex=%x;\",Bits); print(a);?>", c);
|
||||
assertEquals("hex=11;", c.toString());
|
||||
}
|
||||
|
||||
public void testComment() throws IOException, ParserException, HGSEvalException {
|
||||
Context c = exec("<? // comment\nprint(\"false\"); // zzz\n ?>;");
|
||||
assertEquals("false;", c.toString());
|
||||
}
|
||||
|
||||
public void testAddFunction() throws IOException, ParserException, HGSEvalException {
|
||||
Statement s = new Parser("a : in <?=type(elem.Bits)?>;").parse();
|
||||
Statement s = new Parser("a : in <?=type(Bits)?>;").parse();
|
||||
Context funcs = new Context().setVar("type", new FuncAdapter(1) {
|
||||
@Override
|
||||
protected Object f(Object... args) throws HGSEvalException {
|
||||
@ -268,10 +254,10 @@ public class ParserTest extends TestCase {
|
||||
});
|
||||
assertEquals("a : in std_logic;",
|
||||
exec(s, new Context(funcs)
|
||||
.setVar("elem", new ElementAttributes())).toString());
|
||||
.setVar("Bits", 1)).toString());
|
||||
assertEquals("a : in std_logic_vector(5 downto 0);",
|
||||
exec(s, new Context(funcs)
|
||||
.setVar("elem", new ElementAttributes().setBits(6))).toString());
|
||||
.setVar("Bits", 6)).toString());
|
||||
}
|
||||
|
||||
int flag = 0;
|
||||
@ -339,10 +325,11 @@ public class ParserTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
// checks the available VHDL templates
|
||||
public void testVHDLTemplates() throws Exception {
|
||||
final File path = new File(Resources.getRoot(), "../../main/resources/vhdl");
|
||||
int n=new FileScanner(f -> new Parser(new FileReader(f)).parse()).setSuffix(".tem").scan(path);
|
||||
assertTrue(n>10);
|
||||
int n = new FileScanner(f -> new Parser(new FileReader(f)).parse()).setSuffix(".tem").scan(path);
|
||||
assertTrue(n > 10);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user