This commit is contained in:
Gideon le Grange 2014-10-08 04:40:27 +02:00
parent 8ce5fce77f
commit 935c76ae34
3 changed files with 94 additions and 62 deletions

View File

@ -19,7 +19,7 @@ public class Example8 extends Example {
} }
private void test() throws MikrotikApiException, InterruptedException { private void test() throws MikrotikApiException, InterruptedException {
List<Map<String, String>> res = con.execute("/ip/hotspot/user/print where uptime<00:00:01"); List<Map<String, String>> res = con.execute("/ip/hotspot/user/print where uptime!=1");
for (Map<String, String> r : res) { for (Map<String, String> r : res) {
System.out.println(r); System.out.println(r);
} }

View File

@ -82,13 +82,14 @@ class Parser {
case TEXT: { case TEXT: {
String name = text; String name = text;
next(); next();
expect(Token.EQUALS, Token.LESS, Token.MORE); expect(Token.EQUALS, Token.LESS, Token.MORE, Token.NOT_EQUALS);
switch (token) { switch (token) {
case EQUALS: case EQUALS:
eqExpr(name); eqExpr(name);
break; break;
case NOT_EQUALS : case NOT_EQUALS :
notExpr(name); notExpr(name);
break;
case LESS: case LESS:
lessExpr(name); lessExpr(name);
break; break;
@ -106,6 +107,7 @@ class Parser {
case AND : andExpr(); case AND : andExpr();
break; break;
case OR : orExpr(); case OR : orExpr();
break;
} }
} }

View File

@ -13,16 +13,17 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package me.legrange.mikrotik.impl; package me.legrange.mikrotik.impl;
/** /**
* A simple scanner. * A simple scanner.
*
* @author gideon * @author gideon
*/ */
class Scanner { class Scanner {
enum Token { enum Token {
SLASH("/"), COMMA(","), EOL(), WS, TEXT, SLASH("/"), COMMA(","), EOL(), WS, TEXT,
LESS("<"), MORE(">"), EQUALS("="), NOT_EQUALS("!="), LESS("<"), MORE(">"), EQUALS("="), NOT_EQUALS("!="),
WHERE, NOT, AND, OR, RETURN; WHERE, NOT, AND, OR, RETURN;
@ -40,21 +41,25 @@ class Scanner {
symb = null; symb = null;
} }
private final String symb; private final String symb;
} }
/** create a scanner for the given line of text */ /**
* create a scanner for the given line of text
*/
Scanner(String line) { Scanner(String line) {
this.line = line; this.line = line;
nextChar(); nextChar();
} }
/** return the next token from the text */ /**
* return the next token from the text
*/
Token next() throws ScanException { Token next() throws ScanException {
text = null; text = null;
switch (c) { switch (c) {
case '\n' : return Token.EOL; case '\n':
return Token.EOL;
case ' ': case ' ':
case '\t': case '\t':
return whiteSpace(); return whiteSpace();
@ -85,34 +90,51 @@ class Scanner {
} }
/** return the text associated with the last token returned */ /**
* return the text associated with the last token returned
*/
String text() { String text() {
if (text != null) return text.toString(); if (text != null) {
return text.toString();
}
return ""; return "";
} }
/** return the position of the scanner */ /**
int pos() { return pos; } * return the position of the scanner
*/
int pos() {
return pos;
}
/** process 'name' tokens which could be key words or text */ /**
* process 'name' tokens which could be key words or text
*/
private Token name() throws ScanException { private Token name() throws ScanException {
text = new StringBuilder(); text = new StringBuilder();
while (!in(c, "[ \t\r\n=<>]")) { while (!in(c, "[ \t\r\n=<>!]")) {
text.append(c); text.append(c);
nextChar(); nextChar();
} }
String val = text.toString().toLowerCase(); String val = text.toString().toLowerCase();
switch (val) { switch (val) {
case "where" : return Token.WHERE; case "where":
case "not" : return Token.NOT; return Token.WHERE;
case "and" : return Token.AND; case "not":
case "or" : return Token.OR; return Token.NOT;
case "return" : return Token.RETURN; case "and":
return Token.AND;
case "or":
return Token.OR;
case "return":
return Token.RETURN;
} }
return Token.TEXT; return Token.TEXT;
} }
/** process quoted text */ /**
* process quoted text
*/
private Token quotedText(char quote) throws ScanException { private Token quotedText(char quote) throws ScanException {
nextChar(); // eat the '"' nextChar(); // eat the '"'
text = new StringBuilder(); text = new StringBuilder();
@ -127,7 +149,9 @@ class Scanner {
return Token.TEXT; return Token.TEXT;
} }
/** process white space */ /**
* process white space
*/
private Token whiteSpace() { private Token whiteSpace() {
while ((c == ' ') || (c == '\t')) { while ((c == ' ') || (c == '\t')) {
nextChar(); nextChar();
@ -135,27 +159,33 @@ class Scanner {
return Token.WS; return Token.WS;
} }
/** process the not equals token */ /**
* process the not equals token
*/
private Token notEquals() throws ScanException { private Token notEquals() throws ScanException {
nextChar(); // eat the ! nextChar(); // eat the !
if (c != '=') { if (c != '=') {
throw new ScanException(String.format("Expected = after !, found '%c'", c)); throw new ScanException(String.format("Expected = after !, found '%c'", c));
} }
nextChar(); // eat the =
return Token.NOT_EQUALS; return Token.NOT_EQUALS;
} }
/** return the next character from the line of text */ /**
* return the next character from the line of text
*/
private void nextChar() { private void nextChar() {
if (pos < line.length()) { if (pos < line.length()) {
c = line.charAt(pos); c = line.charAt(pos);
pos++; pos++;
} } else {
else {
c = '\n'; c = '\n';
} }
} }
/** check if the character matches the give expression */ /**
* check if the character matches the give expression
*/
private boolean in(char c, String cs) { private boolean in(char c, String cs) {
return ("" + c).matches(cs); return ("" + c).matches(cs);
} }