Оптимизация поиска ENDIF

This commit is contained in:
Victor 2015-04-16 18:54:25 +03:00
parent 326c70f514
commit a10147782e

View File

@ -37,9 +37,9 @@ public final class Parser {
private int position;
private final Map<String, Integer> labels;
/** Оптимизация, чтобы каждый раз не искать endmenu,
/** Оптимизация, чтобы каждый раз не искать endmenu/endif,
* если их попросту нет в необработанном сценарии */
private boolean hasEndMenu;
private boolean hasEndMenu, hasEndIf;
public Parser(List<Token> tokens) {
this.tokens = tokens;
@ -47,6 +47,7 @@ public final class Parser {
position = 0;
labels = new HashMap<String, Integer>();
hasEndMenu = false;
hasEndIf = false;
preScan();
Variables.init();
}
@ -151,13 +152,7 @@ public final class Parser {
// Остаток от условного выражения. Пропускаем до появления ENDIF.
if (match(token, TokenType.ELSE)) {
int pos = 0;
while (true) {
if (lookMatch(pos, TokenType.ENDIF)) break;
if (lookMatch(pos, TokenType.EOF)) return true;
pos++;
}
position += pos;
if (hasEndIf) position += skipIf();
return false;
}
}
@ -375,6 +370,7 @@ public final class Parser {
final Expression condition = expression();
consume(TokenType.COLON);
if (!hasEndIf) return false;
if (condition.eval() == 0) {
// Если условие не верно, пропускаем блок до следующего ENDIF
int pos = 0;
@ -534,6 +530,8 @@ public final class Parser {
final TokenType current = tokens.get(i).getType();
if (current == TokenType.ENDMENU) {
hasEndMenu = true;
} else if (current == TokenType.ENDIF) {
hasEndIf = true;
} else if ( (current == TokenType.LABEL) &&
(tokens.get(i + 2).getType() == TokenType.COLON) ) {
// label word :
@ -566,6 +564,20 @@ public final class Parser {
return pos;
}
private int skipIf() {
int pos = 0;
int level = 1;
while (true) {
if (lookMatch(pos, TokenType.IF)) level++;
else if (lookMatch(pos, TokenType.ENDIF)) {
level--;
if (level <= 0) break;
}
pos++;
}
return pos;
}
private double consumeDouble() {
return Double.parseDouble(consume(TokenType.NUMBER).getText());