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