package com.wesleyhome.math.equation;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.ANTLRErrorStrategy;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.BailErrorStrategy;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeListener;
import org.antlr.v4.runtime.tree.TerminalNode;
import com.wesleyhome.math.equation.grammer.EquationGrammarLexer;
import com.wesleyhome.math.equation.grammer.EquationGrammarParser;
import com.wesleyhome.math.equation.grammer.EquationGrammarParser.EqContext;
import com.wesleyhome.math.equation.grammer.EquationGrammarParser.ExpressionopContext;
import com.wesleyhome.math.equation.grammer.EquationGrammarParser.ProgContext;
class StringEquationParser {
ExpressionNode parseExpression(final String expression) throws ParseCancellationException {
final EquationGrammarParser parser = getParser(expression);
final EqContext eq = parser.eq();
final List<TerminalNode> equation1 = parseTree(eq);
final ExpressionopContext expressionop = parser.expressionop();
final List<TerminalNode> operatorTree = parseTree(expressionop);
final EqContext eq2 = parser.eq();
final List<TerminalNode> equation2 = parseTree(eq2);
return new ExpressionNode(getString(equation1), operatorTree.get(0), getString(equation2));
}
private String getString(List<TerminalNode> nodeList) {
final StringBuilder sb = new StringBuilder();
for (final TerminalNode terminalNode : nodeList) {
sb.append(terminalNode).append(" ");
}
return sb.toString();
}
/**
* @param equation
* @return
* @throws ParseCancellationException
* throws if equation is invalid
*/
List<TerminalNode> parseEquation(final String equation) throws ParseCancellationException {
final EquationGrammarParser parser = getParser(equation);
final ProgContext tree = parser.prog();
return parseTree(tree);
}
private EquationGrammarParser getParser(final String equation) {
final ANTLRInputStream input = new ANTLRInputStream(equation);
final EquationGrammarLexer lexer = new EquationGrammarLexer(input);
final TokenStream tokenStream = new CommonTokenStream(lexer);
final EquationGrammarParser parser = new EquationGrammarParser(tokenStream);
final ANTLRErrorStrategy handler = new BailErrorStrategy();
parser.setErrorHandler(handler);
final ParseTreeListener listener = new EquationGrammerListener();
parser.addParseListener(listener);
return parser;
}
private List<TerminalNode> parseTree(final ParseTree tree) {
final List<TerminalNode> tokens = new ArrayList<TerminalNode>();
if (tree instanceof TerminalNode) {
final TerminalNode terminalNode = (TerminalNode) tree;
final Token symbol = terminalNode.getSymbol();
final int type = symbol.getType();
if (Token.EOF != type) {
tokens.add(terminalNode);
}
return tokens;
}
final int childCount = tree.getChildCount();
for (int i = 0; i < childCount; i++) {
final ParseTree child = tree.getChild(i);
tokens.addAll(parseTree(child));
}
return tokens;
}
}