$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r69298 - in trunk/libs/spirit/example/qi: . compiler_tutorial/calc7
From: joel_at_[hidden]
Date: 2011-02-26 04:54:24
Author: djowel
Date: 2011-02-26 04:54:14 EST (Sat, 26 Feb 2011)
New Revision: 69298
URL: http://svn.boost.org/trac/boost/changeset/69298
Log:
calc7 updates: tagging the AST
Added:
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/annotation.hpp   (contents, props changed)
Text files modified: 
   trunk/libs/spirit/example/qi/calc_utree_naive.cpp                       |    12 +++++++-----                            
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/ast.hpp            |    34 +++++++++++++++++++---------------      
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.cpp       |    20 +++++---------------                    
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.hpp       |     4 +---                                    
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression_def.hpp |     1 +                                       
   5 files changed, 33 insertions(+), 38 deletions(-)
Modified: trunk/libs/spirit/example/qi/calc_utree_naive.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/calc_utree_naive.cpp	(original)
+++ trunk/libs/spirit/example/qi/calc_utree_naive.cpp	2011-02-26 04:54:14 EST (Sat, 26 Feb 2011)
@@ -16,13 +16,13 @@
 //
 ///////////////////////////////////////////////////////////////////////////////
 
-// This rather naive example demonstrates that you can pass an instance of a 
+// This rather naive example demonstrates that you can pass an instance of a
 // utree as the attribute for almost any grammar. As the result the utree will
-// be filled with the parse tree as generated during the parsing. This is most 
+// be filled with the parse tree as generated during the parsing. This is most
 // of the time not what's desired, but is usually a good first step in order to
 // prepare your grammar to generate a customized AST. See the calc_utree_ast
 // example for a modified version of this grammar filling the attribute with a
-// AST (abstract syntax tree) representing the math expression as matched from 
+// AST (abstract syntax tree) representing the math expression as matched from
 // the input.
 
 // #define BOOST_SPIRIT_DEBUG
@@ -67,7 +67,7 @@
 
             factor =
                 uint_
-                |   char_('(') >> expression >> char_(')')
+                |   '(' >> expression >> ')'
                 |   (char_('-') >> factor)
                 |   (char_('+') >> factor)
                 ;
@@ -77,7 +77,9 @@
             BOOST_SPIRIT_DEBUG_NODE(factor);
         }
 
-        qi::rule<Iterator, ascii::space_type, spirit::utree()> expression, term, factor;
+        qi::rule<Iterator, ascii::space_type, spirit::utree()> expression;
+        qi::rule<Iterator, ascii::space_type, spirit::utree::list_type()> term;
+        qi::rule<Iterator, ascii::space_type, spirit::utree::list_type()> factor;
     };
 }
 
Added: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/annotation.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/annotation.hpp	2011-02-26 04:54:14 EST (Sat, 26 Feb 2011)
@@ -0,0 +1,56 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_CALC7_ANNOTATION_HPP)
+#define BOOST_SPIRIT_CALC7_ANNOTATION_HPP
+
+#include <map>
+#include <boost/variant/apply_visitor.hpp>
+#include "ast.hpp"
+
+namespace client
+{
+    ///////////////////////////////////////////////////////////////////////////////
+    //  The annotation handler links the AST to a map of iterator positions
+    //  for the purpose of subsequent semantic error handling when the
+    //  program is being compiled.
+    ///////////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    struct annotation
+    {
+        template <typename, typename>
+        struct result { typedef void type; };
+
+        std::map<int, Iterator>& iters;
+        int& current_id;
+        annotation(int& current_id, std::map<int, Iterator>& iters)
+          : current_id(current_id), iters(iters) {}
+
+        struct set_id
+        {
+            typedef void result_type;
+
+            int id;
+            set_id(int id) : id(id) {}
+
+            template <typename T>
+            void operator()(T& x) const
+            {
+                x.id = id;
+            }
+        };
+
+        void operator()(ast::operand& ast, Iterator pos) const
+        {
+            int id = current_id++;
+            iters[id] = pos;
+            boost::apply_visitor(set_id(id), ast);
+        }
+    };
+}
+
+#endif
+
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/ast.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/calc7/ast.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/ast.hpp	2011-02-26 04:54:14 EST (Sat, 26 Feb 2011)
@@ -17,45 +17,49 @@
     ///////////////////////////////////////////////////////////////////////////
     //  The AST
     ///////////////////////////////////////////////////////////////////////////
-    struct nil {};
+    struct base
+    {
+        int id; // Used to annotate the AST with the iterator position.
+                // This id is used as a key to a map<int, Iterator>
+                // (not really part of the AST.)
+    };
+
+    struct nil : base {};
+
     struct signed_;
     struct program;
-    struct tagged;
+
+    struct unsigned_ : base
+    {
+        unsigned_(unsigned int n = 0) : n(n) {}
+        unsigned int n;
+    };
 
     typedef boost::variant<
             nil
-          , unsigned int
+          , unsigned_
           , boost::recursive_wrapper<signed_>
           , boost::recursive_wrapper<program>
-          , boost::recursive_wrapper<tagged>
         >
     operand;
 
-    struct signed_
+    struct signed_ : base
     {
         char sign;
         operand operand_;
     };
 
-    struct operation
+    struct operation : base
     {
         char operator_;
         operand operand_;
     };
 
-    struct program
+    struct program : base
     {
         operand first;
         std::list<operation> rest;
     };
-
-    struct tagged
-    {
-        operand operand_;
-        int id; // Used to annotate the iterator position. This
-                // id is used as a key to a map<int, Iterator>
-                // (not really part of the AST.)
-    };
 }}
 
 BOOST_FUSION_ADAPT_STRUCT(
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.cpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.cpp	2011-02-26 04:54:14 EST (Sat, 26 Feb 2011)
@@ -11,20 +11,15 @@
 
 namespace client
 {
-    void compiler::operator()(unsigned int n) const
+    void compiler::operator()(ast::unsigned_ const& x) const
     {
         op(op_int);
-        op(n);
-    }
-
-    void compiler::operator()(ast::operand const& x) const
-    {
-        boost::apply_visitor(*this, x);
+        op(x.n);
     }
 
     void compiler::operator()(ast::operation const& x) const
     {
-        (*this)(x.operand_);
+        boost::apply_visitor(*this, x.operand_);
         switch (x.operator_)
         {
             case '+': op(op_add); break;
@@ -37,7 +32,7 @@
 
     void compiler::operator()(ast::signed_ const& x) const
     {
-        (*this)(x.operand_);
+        boost::apply_visitor(*this, x.operand_);
         switch (x.sign)
         {
             case '-': op(op_neg); break;
@@ -48,16 +43,11 @@
 
     void compiler::operator()(ast::program const& x) const
     {
-        (*this)(x.first);
+        boost::apply_visitor(*this, x.first);
         BOOST_FOREACH(ast::operation const& oper, x.rest)
         {
             (*this)(oper);
         }
     }
-
-    void compiler::operator()(ast::tagged const& x) const
-    {
-        (*this)(x.operand_);
-    }
 }
 
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.hpp	2011-02-26 04:54:14 EST (Sat, 26 Feb 2011)
@@ -26,12 +26,10 @@
         void op(int opcode) const { code.push_back(opcode); }
 
         void operator()(ast::nil) const { BOOST_ASSERT(0); }
-        void operator()(unsigned int n) const;
-        void operator()(ast::operand const& x) const;
+        void operator()(ast::unsigned_ const& x) const;
         void operator()(ast::operation const& x) const;
         void operator()(ast::signed_ const& x) const;
         void operator()(ast::program const& x) const;
-        void operator()(ast::tagged const& x) const;
     };
 }
 
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression_def.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression_def.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression_def.hpp	2011-02-26 04:54:14 EST (Sat, 26 Feb 2011)
@@ -72,6 +72,7 @@
         typename function<annotation_>
             annotation = annotation_(current_id, iters);
         on_success(primary_expr, annotation(_val, _3));
+        on_success(unary_expr, annotation(_val, _3));
     }
 }