From 9964f2b34634ce83f50f08efcda91e39a4c617b0 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 15 Jun 2015 23:51:58 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BF=D0=B0=D1=80=D1=81=D0=B5=D1=80=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=84=D0=B8=D0=B3=D1=83=D1=80=D0=B0=D1=86=D0=B8=D0=BE?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everlastingsummer/ConfigParser.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/com/annimon/everlastingsummer/ConfigParser.java diff --git a/src/com/annimon/everlastingsummer/ConfigParser.java b/src/com/annimon/everlastingsummer/ConfigParser.java new file mode 100644 index 0000000..3910c77 --- /dev/null +++ b/src/com/annimon/everlastingsummer/ConfigParser.java @@ -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 tokens) { + return new ConfigParser(tokens); + } + + private final List tokens; + private final int tokensCount; + private int position; + private final Map values; + + private ConfigParser(List tokens) { + this.tokens = tokens; + tokensCount = tokens.size(); + position = 0; + values = new HashMap(); + } + + 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); + } +}