me.legrange.mikrotik.impl.Scanner Maven / Gradle / Ivy
/*
* Copyright 2014 GideonLeGrange.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.legrange.mikrotik.impl;
import static me.legrange.mikrotik.impl.Scanner.Token.*;
/**
* A simple scanner.
*
* @author gideon
*/
class Scanner {
enum Token {
SLASH("/"), COMMA(","), EOL(), WS, TEXT,
LESS("<"), MORE(">"), EQUALS("="), NOT_EQUALS("!="), PIPE("!"),
WHERE, NOT, AND, OR, RETURN;
@Override
public String toString() {
return (symb == null) ? name() : symb;
}
private Token(String symb) {
this.symb = symb;
}
private Token() {
symb = null;
}
private final String symb;
}
/**
* create a scanner for the given line of text
*/
Scanner(String line) {
this.line = line;
nextChar();
}
/**
* return the next token from the text
*/
Token next() throws ScanException {
text = null;
switch (c) {
case '\n':
return EOL;
case ' ':
case '\t':
return whiteSpace();
case ',':
nextChar();
return COMMA;
case '/':
nextChar();
return SLASH;
case '<':
nextChar();
return LESS;
case '>':
nextChar();
return MORE;
case '=':
nextChar();
return EQUALS;
case '!':
return pipe();
case '"':
return quotedText('"');
case '\'':
return quotedText('\'');
default:
return name();
}
}
/**
* return the text associated with the last token returned
*/
String text() {
if (text != null) {
return text.toString();
}
return "";
}
/**
* return the position of the scanner
*/
int pos() {
return pos;
}
/**
* process 'name' tokens which could be key words or text
*/
private Token name() throws ScanException {
text = new StringBuilder();
while (!in(c, "[ \t\r\n=<>!]")) {
text.append(c);
nextChar();
}
String val = text.toString().toLowerCase();
switch (val) {
case "where":
return WHERE;
case "not":
return NOT;
case "and":
return AND;
case "or":
return OR;
case "return":
return RETURN;
}
return TEXT;
}
/**
* process quoted text
*/
private Token quotedText(char quote) throws ScanException {
nextChar(); // eat the '"'
text = new StringBuilder();
while (c != quote) {
if (c == '\n') {
throw new ScanException("Unclosed quoted text, reached end of line.");
}
text.append(c);
nextChar();
}
nextChar(); // eat the '"'
return TEXT;
}
/**
* process notEquals !
*/
private Token pipe() {
nextChar(); // eat !
if (c == '=') {
nextChar(); // eat =
return NOT_EQUALS;
}
return PIPE;
}
/**
* process white space
*/
private Token whiteSpace() {
while ((c == ' ') || (c == '\t')) {
nextChar();
}
return WS;
}
/**
* return the next character from the line of text
*/
private void nextChar() {
if (pos < line.length()) {
c = line.charAt(pos);
pos++;
} else {
c = '\n';
}
}
/**
* look ahead one character
*/
private char peek() {
if (pos < line.length()) {
return line.charAt(pos);
} else {
return '\n';
}
}
/**
* check if the character matches the give expression
*/
private boolean in(char c, String cs) {
return ("" + c).matches(cs);
}
private final String line;
private int pos = 0;
private char c;
private StringBuilder text;
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy