Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

lab03-ready / project_solve / lab03 / src / avangard / tools / checkers / MultiLineCommentsCheckerImpl

.java
Скачиваний:
61
Добавлен:
18.03.2015
Размер:
5 Кб
Скачать
☆
package avangard.tools.checkers;

public class MultiLineCommentsCheckerImpl implements CheckComment {

	private String curLine = null; // последняя (текущая) прочитанная строка
	private int curPos = 0; // индекс первого необработанного символа внутри curLine
	private boolean flagMultiLine = false; // true признак того, что был открыт многострочный комментарий '/*' или иной...
	private int curLineNum = 0;

	@Override
	public String toString() {
		return "current line #" + curLineNum + ", inside comment " + flagMultiLine + "\r\n\t'" + curLine + "'";
	}

	@Override
	public void clear() {
		this.flagMultiLine = false;
		this.curPos = 0;
		this.curLine = null;
		this.curLineNum = 0;
	}

	@Override
	public String removeComment(String data) {
		this.curLineNum++;
		this.curLine = data;
		return scanLine(0);
	}

	/**
	 * Вернёт true, если текущая строка проверена до конца ...
	 *
	 * @return
	 */
	private boolean endOfLine() {
		return (curLine == null) || (curLine.length() <= curPos);
	}

	/**
	 * Основная функция выкусывания комментария из curLine. Сделана рекурсивной,
	 * работает с внут переменными класса, так что это private-функция.
	 */
	private String scanLine(int from) {
		this.curPos = from;
		if (endOfLine()) { // в текущей строке больше уже нечего брать ...
			return "";
		}

		// если находимся внутри многострочного комментария ...
		if (flagMultiLine) {
			// ждём конца открытого ранее комментария ...
			final int closePos = curLine.indexOf("*/", this.curPos);
			if (closePos == -1) { // в этой строке комментарий не закрывается -> пропуск всего остатка ...
				this.curPos = this.curLine.length(); // пропуск до конца строки ...
				return ""; // ничего нет в строке ...
			}

			// конец многострочного комментария ...
			this.flagMultiLine = false;
			// начинаем накопление после символов, закрывающих комментарий ...
			this.curPos = closePos + 2;
		}

		// сканирование текущей строки до конца или начала нового комментария
		final int istart = this.curPos;
		scan:
		for (; this.curPos < this.curLine.length(); this.curPos++) {
			switch (this.curLine.charAt(this.curPos)) {
				case '/':
					// проверяем следующий символ ...
					if (this.curPos >= this.curLine.length()) // это последний символ в строке -> следующего нет
					// -> это точно не начало комментария "/*" ...
					{
						continue; // for
					}
					/* проверка начала комментария вида "/* xxx" ... */
					final boolean nextIsMultiLineOpen = this.curLine.charAt(this.curPos + 1) == '*';
					if (nextIsMultiLineOpen) {
						this.flagMultiLine = true; // true, т.к. открыт многострочный комментарий '/*'...
						// многострочный комментарий может продолжаться внутри строки,
						// так что просто ждём окончание в текущей строке -  рекурсия, 
						// + накапливаем текст...
						return this.curLine.substring(istart, this.curPos) + scanLine(this.curPos + 2);
					}

					/* проверка начала комментария вида "// xxx" ... */
					final boolean nextIsSlash = this.curLine.charAt(this.curPos + 1) == '/';
					if (!nextIsSlash) // это не двойной слеш - продолжаем ...
					{
						break; // переход "за" swicth
					}						// здесь код сработает когда комментарий будет начинаться с '//'
				// (!) тогда "проваливаемся" дальше в swicth ...

				/* начало комментария "# xxx" или "; xxx" */
				case '#':
				case ';':
						// тут вся часть строки до конца должна быть отброшена как комментарий,
					// а часть строки от curPos до этого символа - данные ...
					break scan; // for
				} // switch
		} // for
		// вернуть строку от исходной позиции до предпоследней проверенной ...
		final String result = this.curLine.substring(istart, this.curPos);
		this.curPos = this.curLine.length(); // пропуск до конца строки ...
		return result;
	}

}
Соседние файлы в папке checkers