Добавлен парсер конфигурационных файлов
This commit is contained in:
parent
0b2f414098
commit
9964f2b346
135
src/com/annimon/everlastingsummer/ConfigParser.java
Normal file
135
src/com/annimon/everlastingsummer/ConfigParser.java
Normal file
@ -0,0 +1,135 @@
|
||||
package com.annimon.everlastingsummer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class ConfigParser {
|
||||
|
||||
private static final Token EOF = new Token("", TokenType.EOF);
|
||||
|
||||
public static ConfigParser parse(List<Token> tokens) {
|
||||
return new ConfigParser(tokens);
|
||||
}
|
||||
|
||||
private final List<Token> tokens;
|
||||
private final int tokensCount;
|
||||
private int position;
|
||||
private final Map<String, String> values;
|
||||
|
||||
private ConfigParser(List<Token> tokens) {
|
||||
this.tokens = tokens;
|
||||
tokensCount = tokens.size();
|
||||
position = 0;
|
||||
values = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
public void addValue(String key, String value) {
|
||||
values.put(key, value);
|
||||
}
|
||||
|
||||
public boolean isValueExists(String key) {
|
||||
return values.containsKey(key);
|
||||
}
|
||||
|
||||
public String getValue(String key) {
|
||||
if (!isValueExists(key)) return "";
|
||||
return values.get(key);
|
||||
}
|
||||
|
||||
public double getValueAsDouble(String key) {
|
||||
if (!isValueExists(key)) return 0;
|
||||
return Double.parseDouble(values.get(key));
|
||||
}
|
||||
|
||||
public boolean getValueAsBoolean(String key) {
|
||||
if (!isValueExists(key)) return false;
|
||||
return "true".equalsIgnoreCase(values.get(key));
|
||||
}
|
||||
|
||||
public void parse() {
|
||||
while (!match(TokenType.EOF)) {
|
||||
match(TokenType.COMMAND);
|
||||
|
||||
if (lookMatch(0, TokenType.WORD)) {
|
||||
final String name = consume(TokenType.WORD).getText();
|
||||
|
||||
if (match(TokenType.EQ)) {
|
||||
// variable = expression
|
||||
addValue(name, expression());
|
||||
}
|
||||
if (lookMatch(1, TokenType.EQ) && match(TokenType.PLUS)) {
|
||||
// variable += expression
|
||||
consume(TokenType.EQ);
|
||||
addValue(name, getValue(name) + expression());
|
||||
}
|
||||
} else {
|
||||
position++;
|
||||
}
|
||||
}
|
||||
tokens.clear();
|
||||
}
|
||||
|
||||
private String expression() {
|
||||
return additive();
|
||||
}
|
||||
|
||||
private String additive() {
|
||||
String expression = unary();
|
||||
|
||||
while (true) {
|
||||
if (match(TokenType.PLUS)) {
|
||||
expression += unary();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
private String unary() {
|
||||
match(TokenType.PLUS);
|
||||
return primary();
|
||||
}
|
||||
|
||||
private String primary() {
|
||||
final Token current = get(0);
|
||||
if (match(TokenType.TEXT) || match(TokenType.NUMBER)) {
|
||||
return current.getText();
|
||||
}
|
||||
if (match(TokenType.WORD)) {
|
||||
return getValue(current.getText());
|
||||
}
|
||||
if (match(TokenType.LPAREN)) {
|
||||
String expr = expression();
|
||||
match(TokenType.RPAREN);
|
||||
return expr;
|
||||
}
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
|
||||
private boolean match(TokenType type) {
|
||||
if (get(0).getType() != type) return false;
|
||||
position++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private Token consume(TokenType type) {
|
||||
if (get(0).getType() != type) throw new RuntimeException("Ожидался токен " + type + ".");
|
||||
return tokens.get(position++);
|
||||
}
|
||||
|
||||
private boolean lookMatch(int pos, TokenType type) {
|
||||
return (type == get(pos).getType());
|
||||
}
|
||||
|
||||
private Token get(int offset) {
|
||||
if (position + offset >= tokensCount) return EOF;
|
||||
return tokens.get(position + offset);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user