<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marius Bancila's Blog &#187; grammar</title>
	<atom:link href="http://mariusbancila.ro/blog/tag/grammar/feed/" rel="self" type="application/rss+xml" />
	<link>http://mariusbancila.ro/blog</link>
	<description>Sharing my opinions and ideas!</description>
	<lastBuildDate>Fri, 06 Apr 2012 13:45:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Evaluate Expressions &#8211; Part 4: Evaluate the Abstract Syntax Tree</title>
		<link>http://mariusbancila.ro/blog/2009/02/06/evaluate-expressions-%e2%80%93-part-4-evaluate-the-abstract-syntax-tree/</link>
		<comments>http://mariusbancila.ro/blog/2009/02/06/evaluate-expressions-%e2%80%93-part-4-evaluate-the-abstract-syntax-tree/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 06:00:45 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[Articles & Tutorials]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[AST]]></category>
		<category><![CDATA[expressions]]></category>
		<category><![CDATA[grammar]]></category>
		<category><![CDATA[parser]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=151</guid>
		<description><![CDATA[Evaluate Expressions &#8211; Part 1: The Approaches Evaluate Expressions &#8211; Part 2: Parse the Expression Evaluate Expressions &#8211; Part 3: Building the Abstract Syntax Tree Evaluate Expressions &#8211; Part 4: Evaluate the Abstract Syntax Tree So far we have managed to parse the text representing an expression and build an abstract syntax tree. The only [...]]]></description>
			<content:encoded><![CDATA[<p>
<b><a href="http://mariusbancila.ro/blog/?p=148">Evaluate Expressions &#8211; Part 1: The Approaches</a></b><br />
<b><a href="http://mariusbancila.ro/blog/?p=149">Evaluate Expressions &#8211; Part 2: Parse the Expression</a></b><br />
<b><a href="http://mariusbancila.ro/blog/?p=150">Evaluate Expressions &#8211; Part 3: Building the Abstract Syntax Tree</a></b><br />
<b>Evaluate Expressions &#8211; Part 4: Evaluate the Abstract Syntax Tree</b>
</p>
<p>So far we have managed to parse the text representing an expression and build an abstract syntax tree. The only thing left, and the simplest of them all, is traversing this abstract syntax tree and evaluating the expression is represents.</p>
<p>In pseudo code, this would look like this:</p>
<pre class="prettyprint">
double Evaluate(subtree)
{
   if(subtree is numeric)
      return value;
   else
   {
      op = subtree.operator
      v1 = Evaluate(subtree.left)
      v2 = Evaluate(subtree.right)
      return v1 op v2;
   }
}
</pre>
<p>We actually have to check for one more type of node, the one representing an unary expression. However, the evaluation function is as simple as this:</p>
<pre class="prettyprint">
class Evaluator
{
   double EvaluateSubtree(ASTNode* ast)
   {
      if(ast == NULL)
         throw EvaluatorException("Incorrect syntax tree!");

      if(ast->Type == NumberValue)
         return ast->Value;
      else if(ast->Type == UnaryMinus)
         return -EvaluateSubtree(ast->Left);
      else
      {
         double v1 = EvaluateSubtree(ast->Left);
         double v2 = EvaluateSubtree(ast->Right);
         switch(ast->Type)
         {
         case OperatorPlus:  return v1 + v2;
         case OperatorMinus: return v1 - v2;
         case OperatorMul:   return v1 * v2;
         case OperatorDiv:   return v1 / v2;
         }
      }

      throw EvaluatorException("Incorrect syntax tree!");
   }

public:
   double Evaluate(ASTNode* ast)
   {
      if(ast == NULL)
         throw EvaluatorException("Incorrect abstract syntax tree");

      return EvaluateSubtree(ast);
   }
};
</pre>
<p>The exception class is defined as:</p>
<pre class="prettyprint">
class EvaluatorException : public std::exception
{
public:
   EvaluatorException(const std::string&amp; message):
      std::exception(message.c_str())
      {
      }
};
</pre>
<p>So let&#8217;s try it:</p>
<pre class="prettyprint">
void Test(const char* text)
{
   Parser parser;

   try
   {
      ASTNode* ast = parser.Parse(text);

      try
      {
         Evaluator eval;
         double val = eval.Evaluate(ast);

         std::cout << text << " = " << val << std::endl;
      }
      catch(EvaluatorException&amp; ex)
      {
		  std::cout << text << " t " << ex.what() << std::endl;
      }

      delete ast;
   }
   catch(ParserException&amp; ex)
   {
      std::cout << text << " t " << ex.what() << std::endl;
   }
}

int main()
{
   Test("1+2+3+4");
   Test("1*2*3*4");
   Test("1-2-3-4");
   Test("1/2/3/4");
   Test("1*2+3*4");
   Test("1+2*3+4");
   Test("(1+2)*(3+4)");
   Test("1+(2*3)*(4+5)");
   Test("1+(2*3)/4+5");
   Test("5/(4+3)/2");
   Test("1 + 2.5");
   Test("125");
   Test("-1");
   Test("-1+(-2)");
   Test("-1+(-2.0)");

   Test("   1*2,5");
   Test("   1*2.5e2");
   Test("M1 + 2.5");
   Test("1 + 2&amp;5");
   Test("1 * 2.5.6");
   Test("1 ** 2.5");
   Test("*1 / 2.5");

   return 0;
}
</pre>
<p>The output of this test program is:</p>
<pre class="prettyprint">
1+2+3+4 = 10
1*2*3*4 = 24
1-2-3-4 = -8
1/2/3/4 = 0.0416667
1*2+3*4 = 14
1+2*3+4 = 11
(1+2)*(3+4) = 21
1+(2*3)*(4+5) = 55
1+(2*3)/4+5 = 7.5
5/(4+3)/2 = 0.357143
1 + 2.5 = 3.5
125 = 125
-1 = -1
-1+(-2) = -3
-1+(-2.0) = -3
   1*2,5         Unexpected token ',' at position 6
   1*2.5e2       Unexpected token 'e' at position 8
M1 + 2.5         Unexpected token 'M' at position 0
1 + 2&amp;5          Unexpected token '&amp;' at position 5
1 * 2.5.6        Unexpected token '.' at position 7
1 ** 2.5         Unexpected token '*' at position 4
*1 / 2.5         Unexpected token '*' at position 1
</pre>
<p>And that's it. Define the grammar, build the parser, insert semantic actions and build the abstract syntax tree and then traverse it and evaluate the expression. If you are interested in understanding the grammar, and the parsing in a deeper manner than I presented in this posts, I suggest you read more articles. The purpose was not to teach compilers theory, but put it to a practical purpose.</p>
<p><a href="http://www.mariusbancila.ro/archives/cpp/EvalExpression.zip">Here</a> you can download a Visual Studio 2008 project with the code contained in this tutorial.</p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2009/02/06/evaluate-expressions-%e2%80%93-part-4-evaluate-the-abstract-syntax-tree/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

