All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.legrange.mikrotik.impl.Scanner Maven / Gradle / Ivy

There is a newer version: 3.0.8
Show newest version
/*
 * 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