int eeeprintDotTree(antlr::RefAST tree, std::ostream& out, antlr::Parser& p) { int me = ++_dot_node; out << me << " [label=\"" << p.getTokenName(tree->getType()) << "\\n" << tree->getText() << "\"];" << std::endl; antlr::RefAST c = tree->getFirstChild(); while (antlr::nullAST != c) { int child = printDotTree(c, out, p); out << me << " -> " << child << ";" << std::endl; c = c->getNextSibling(); } return me; }
double getValue( antlr::RefAST &refAST ) { switch( refAST->getType() ) { case MExprParserTokenTypes::ADD : case MExprParserTokenTypes::SUB : { std::string op = refAST->getText(); antlr::RefAST child1 = refAST->getFirstChild(); double value1 = getValue( child1 ); if ( ISNAN( value1 ) ) return std::numeric_limits< double >::quiet_NaN(); antlr::RefAST child2 = child1->getNextSibling(); if ( child2 == antlr::nullAST ) { return op == "+" ? value1 : -value1; } double value2 = getValue( child2 ); if ( ISNAN( value2 ) ) return std::numeric_limits< double >::quiet_NaN(); return op == "+" ? value1 + value2 : value1 - value2; } case MExprParserTokenTypes::MUL : case MExprParserTokenTypes::DIV : case MExprParserTokenTypes::MOD : { std::string op = refAST->getText(); antlr::RefAST child1 = refAST->getFirstChild(); double value1 = getValue( child1 ); if ( ISNAN( value1 ) ) return std::numeric_limits< double >::quiet_NaN(); antlr::RefAST child2 = child1->getNextSibling(); double value2 = getValue( child2 ); if ( ISNAN( value2 ) ) return std::numeric_limits< double >::quiet_NaN(); if ( op == "*" ) return value1 * value2; if ( op == "/" ) return value1 / value2; // MOD (%) if ( value2 == 0 ) return std::numeric_limits< double >::quiet_NaN(); return static_cast< int >( value1 ) % static_cast< int >( value2 ); } case MExprParserTokenTypes::VAR : { std::string op = refAST->getText(); if ( op == "pi" ) return M_PI; if ( op == "e" ) return M_E; return std::numeric_limits< double >::quiet_NaN(); } case MExprParserTokenTypes::NUM : { std::string num = refAST->getText(); return atof( num.c_str() ); } } return std::numeric_limits< double >::quiet_NaN(); }