Boost logo

Boost-Commit :

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));
     }
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk