Оптимизация поиска ENDIF
This commit is contained in:
parent
326c70f514
commit
a10147782e
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user