Fixed bug #11
This commit is contained in:
parent
8ce5fce77f
commit
935c76ae34
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,79 +41,100 @@ 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':
|
||||||
case ' ' :
|
return Token.EOL;
|
||||||
case '\t' :
|
case ' ':
|
||||||
|
case '\t':
|
||||||
return whiteSpace();
|
return whiteSpace();
|
||||||
case ',' :
|
case ',':
|
||||||
nextChar();
|
nextChar();
|
||||||
return Token.COMMA;
|
return Token.COMMA;
|
||||||
case '/' :
|
case '/':
|
||||||
nextChar();
|
nextChar();
|
||||||
return Token.SLASH;
|
return Token.SLASH;
|
||||||
case '<' :
|
case '<':
|
||||||
nextChar();
|
nextChar();
|
||||||
return Token.LESS;
|
return Token.LESS;
|
||||||
case '>' :
|
case '>':
|
||||||
nextChar();
|
nextChar();
|
||||||
return Token.MORE;
|
return Token.MORE;
|
||||||
case '=' :
|
case '=':
|
||||||
nextChar();
|
nextChar();
|
||||||
return Token.EQUALS;
|
return Token.EQUALS;
|
||||||
case '!' :
|
case '!':
|
||||||
return notEquals();
|
return notEquals();
|
||||||
case '"' :
|
case '"':
|
||||||
return quotedText('"');
|
return quotedText('"');
|
||||||
case '\'' :
|
case '\'':
|
||||||
return quotedText('\'');
|
return quotedText('\'');
|
||||||
default :
|
default:
|
||||||
return name();
|
return name();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** return the text associated with the last token returned */
|
/**
|
||||||
String text() {
|
* return the text associated with the last token returned
|
||||||
if (text != null) return text.toString();
|
*/
|
||||||
|
String text() {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue