Cleanup to parser

This commit is contained in:
Gideon Le Grange 2020-01-03 08:52:01 +02:00
parent 7d29f9265e
commit 1f31a6f3b5
1 changed files with 41 additions and 28 deletions

View File

@ -3,21 +3,27 @@ package me.legrange.mikrotik.impl;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import me.legrange.mikrotik.impl.Scanner.Token; import me.legrange.mikrotik.impl.Scanner.Token;
/** /**
* Parse the pseudo-command line into command objects. * Parse the pseudo-command line into command objects.
*
* @author GideonLeGrange * @author GideonLeGrange
*/ */
class Parser { class Parser {
/** parse the given bit of text into a Command object */ /**
* parse the given bit of text into a Command object
*/
static Command parse(String text) throws ParseException { static Command parse(String text) throws ParseException {
Parser parser = new Parser(text); Parser parser = new Parser(text);
return parser.parse(); return parser.parse();
} }
/** run parse on the internal data and return the command object */ /**
* run parse on the internal data and return the command object
*/
private Command parse() throws ParseException { private Command parse() throws ParseException {
command(); command();
while (!is(Token.WHERE, Token.RETURN, Token.EOL)) { while (!is(Token.WHERE, Token.RETURN, Token.EOL)) {
@ -67,8 +73,7 @@ class Parser {
next(); next();
} }
cmd.addParameter(new Parameter(name, val.toString())); cmd.addParameter(new Parameter(name, val.toString()));
} } else {
else {
cmd.addParameter(new Parameter(name)); cmd.addParameter(new Parameter(name));
} }
} }
@ -92,7 +97,7 @@ class Parser {
case EQUALS: case EQUALS:
eqExpr(name); eqExpr(name);
break; break;
case NOT_EQUALS : case NOT_EQUALS:
notExpr(name); notExpr(name);
break; break;
case LESS: case LESS:
@ -106,30 +111,36 @@ class Parser {
} }
} }
break; break;
case LEFT_BRACKET : { case LEFT_BRACKET:
next(); nestedExpr();
expr(); break;
expect(Token.RIGHT_BRACKET);
next();
}
break;
} }
// if you get here, you had a expression, see if you want more. // if you get here, you had a expression, see if you want more.
switch (token) { switch (token) {
case AND : andExpr(); case AND:
andExpr();
break; break;
case OR : orExpr(); case OR:
orExpr();
break; break;
} }
} }
private void nestedExpr() throws ParseException {
expect(Token.LEFT_BRACKET);
next();
expr();
expect(Token.RIGHT_BRACKET);
next();
}
private void andExpr() throws ParseException { private void andExpr() throws ParseException {
next(); // eat and next(); // eat and
expr(); expr();
cmd.addQuery("?#&"); cmd.addQuery("?#&");
} }
private void orExpr() throws ParseException { private void orExpr() throws ParseException {
next(); // eat or next(); // eat or
expr(); expr();
cmd.addQuery("?#|"); cmd.addQuery("?#|");
@ -142,7 +153,7 @@ class Parser {
cmd.addQuery("?#!"); cmd.addQuery("?#!");
} }
private void eqExpr(String name) throws ParseException { private void eqExpr(String name) throws ParseException {
next(); // eat = next(); // eat =
expect(Token.TEXT); expect(Token.TEXT);
cmd.addQuery(String.format("?%s=%s", name, text)); cmd.addQuery(String.format("?%s=%s", name, text));
@ -185,19 +196,21 @@ class Parser {
cmd.addProperty(props.toArray(new String[props.size()])); cmd.addProperty(props.toArray(new String[props.size()]));
} }
private void expect(Token...tokens) throws ParseException { private void expect(Token... tokens) throws ParseException {
if (!is(tokens)) if (!is(tokens))
throw new ParseException(String.format("Expected %s but found %s at position %d", Arrays.asList(tokens), this.token, scanner.pos())); throw new ParseException(String.format("Expected %s but found %s at position %d", Arrays.asList(tokens), this.token, scanner.pos()));
} }
private boolean is(Token...tokens) { private boolean is(Token... tokens) {
for (Token want : tokens) { for (Token want : tokens) {
if (this.token == want) return true; if (this.token == want) return true;
} }
return false; return false;
} }
/** move to the next token returned by the scanner */ /**
* move to the next token returned by the scanner
*/
private void next() throws ScanException { private void next() throws ScanException {
token = scanner.next(); token = scanner.next();
while (token == Token.WS) { while (token == Token.WS) {