$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r69323 - in trunk/libs/spirit/example/qi/compiler_tutorial: . calc7
From: joel_at_[hidden]
Date: 2011-02-27 06:58:22
Author: djowel
Date: 2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
New Revision: 69323
URL: http://svn.boost.org/trac/boost/changeset/69323
Log:
statement grammar plus various updates
Added:
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement_def.hpp   (contents, props changed)
Text files modified: 
   trunk/libs/spirit/example/qi/compiler_tutorial/Jamfile                  |     1                                         
   trunk/libs/spirit/example/qi/compiler_tutorial/calc6.cpp                |    32 +++++++++++-----------                  
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/annotation.hpp     |    25 +++++++++++++-----                      
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/ast.hpp            |    55 ++++++++++++++++++++++++++++++--------- 
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.cpp       |    31 +++++++++++++++++++--                   
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/compiler.hpp       |     9 ++++--                                  
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression.hpp     |    14 +++++-----                              
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression_def.hpp |    16 ++++++++--                              
   trunk/libs/spirit/example/qi/compiler_tutorial/calc7/main.cpp           |    16 +++++-----                              
   9 files changed, 137 insertions(+), 62 deletions(-)
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/Jamfile
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/Jamfile	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/Jamfile	2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -23,6 +23,7 @@
     calc7/vm.cpp
     calc7/compiler.cpp
     calc7/expression.cpp
+    calc7/statement.cpp
     calc7/main.cpp
     ;
 
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/calc6.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/calc6.cpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc6.cpp	2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -49,13 +49,13 @@
     ///////////////////////////////////////////////////////////////////////////
     struct nil {};
     struct signed_;
-    struct program;
+    struct expression;
 
     typedef boost::variant<
             nil
           , unsigned int
           , boost::recursive_wrapper<signed_>
-          , boost::recursive_wrapper<program>
+          , boost::recursive_wrapper<expression>
         >
     operand;
 
@@ -71,7 +71,7 @@
         operand operand_;
     };
 
-    struct program
+    struct expression
     {
         operand first;
         std::list<operation> rest;
@@ -91,7 +91,7 @@
 )
 
 BOOST_FUSION_ADAPT_STRUCT(
-    client::ast::program,
+    client::ast::expression,
     (client::ast::operand, first)
     (std::list<client::ast::operation>, rest)
 )
@@ -212,7 +212,7 @@
             }
         }
 
-        void operator()(ast::program const& x) const
+        void operator()(ast::expression const& x) const
         {
             boost::apply_visitor(*this, x.first);
             BOOST_FOREACH(ast::operation const& oper, x.rest)
@@ -256,7 +256,7 @@
     //  The calculator grammar
     ///////////////////////////////////////////////////////////////////////////////
     template <typename Iterator>
-    struct calculator : qi::grammar<Iterator, ast::program(), ascii::space_type>
+    struct calculator : qi::grammar<Iterator, ast::expression(), ascii::space_type>
     {
         calculator() : calculator::base_type(expression)
         {
@@ -298,8 +298,8 @@
             on_error<fail>(expression, error_handler(_4, _3, _2));
         }
 
-        qi::rule<Iterator, ast::program(), ascii::space_type> expression;
-        qi::rule<Iterator, ast::program(), ascii::space_type> term;
+        qi::rule<Iterator, ast::expression(), ascii::space_type> expression;
+        qi::rule<Iterator, ast::expression(), ascii::space_type> term;
         qi::rule<Iterator, ast::operand(), ascii::space_type> factor;
     };
 }
@@ -317,7 +317,7 @@
 
     typedef std::string::const_iterator iterator_type;
     typedef client::calculator<iterator_type> calculator;
-    typedef client::ast::program ast_program;
+    typedef client::ast::expression ast_expression;
     typedef client::compiler compiler;
 
     std::string str;
@@ -326,22 +326,22 @@
         if (str.empty() || str[0] == 'q' || str[0] == 'Q')
             break;
 
-        client::vmachine mach;  // Our virtual machine
-        std::vector<int> code;  // Our VM code
-        calculator calc;        // Our grammar
-        ast_program program;    // Our program (AST)
-        compiler compile(code); // Compiles the program
+        client::vmachine mach;      // Our virtual machine
+        std::vector<int> code;      // Our VM code
+        calculator calc;            // Our grammar
+        ast_expression expression;  // Our program (AST)
+        compiler compile(code);     // Compiles the program
 
         std::string::const_iterator iter = str.begin();
         std::string::const_iterator end = str.end();
         boost::spirit::ascii::space_type space;
-        bool r = phrase_parse(iter, end, calc, space, program);
+        bool r = phrase_parse(iter, end, calc, space, expression);
 
         if (r && iter == end)
         {
             std::cout << "-------------------------\n";
             std::cout << "Parsing succeeded\n";
-            compile(program);
+            compile(expression);
             mach.execute(code);
             std::cout << "\nResult: " << mach.top() << std::endl;
             std::cout << "-------------------------\n";
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/annotation.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/calc7/annotation.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/annotation.hpp	2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -24,10 +24,9 @@
         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) {}
+        std::vector<Iterator>& iters;
+        annotation(std::vector<Iterator>& iters)
+          : iters(iters) {}
 
         struct set_id
         {
@@ -36,19 +35,31 @@
             int id;
             set_id(int id) : id(id) {}
 
+            void operator()(ast::tagged& x) const
+            {
+                x.id = id;
+            }
+
             template <typename T>
             void operator()(T& x) const
             {
-                x.id = id;
+                // no need for tags
             }
         };
 
         void operator()(ast::operand& ast, Iterator pos) const
         {
-            int id = current_id++;
-            iters[id] = pos;
+            int id = iters.size();
+            iters.push_back(pos);
             boost::apply_visitor(set_id(id), ast);
         }
+
+        void operator()(ast::assignment& ast, Iterator pos) const
+        {
+            int id = iters.size();
+            iters.push_back(pos);
+            ast.lhs.id = id;
+        }
     };
 }
 
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-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -17,49 +17,67 @@
     ///////////////////////////////////////////////////////////////////////////
     //  The AST
     ///////////////////////////////////////////////////////////////////////////
-    struct base
+    struct tagged
     {
         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 nil {};
     struct signed_;
-    struct program;
+    struct expression;
 
-    struct unsigned_ : base
+    struct variable : tagged
     {
-        unsigned_(unsigned int n = 0) : n(n) {}
-        unsigned int n;
+        variable(std::string const& name = "") : name(name) {}
+        std::string name;
     };
 
     typedef boost::variant<
             nil
-          , unsigned_
+          , unsigned int
+          , variable
           , boost::recursive_wrapper<signed_>
-          , boost::recursive_wrapper<program>
+          , boost::recursive_wrapper<expression>
         >
     operand;
 
-    struct signed_ : base
+    struct signed_
     {
         char sign;
         operand operand_;
     };
 
-    struct operation : base
+    struct operation
     {
         char operator_;
         operand operand_;
     };
 
-    struct program : base
+    struct expression
     {
         operand first;
         std::list<operation> rest;
     };
+
+    struct assignment
+    {
+        variable lhs;
+        expression rhs;
+    };
+
+    struct variable_declaration
+    {
+        assignment assign;
+    };
+
+    typedef std::list<
+        boost::variant<
+            variable_declaration,
+            assignment>
+        >
+    statement;
 }}
 
 BOOST_FUSION_ADAPT_STRUCT(
@@ -75,9 +93,20 @@
 )
 
 BOOST_FUSION_ADAPT_STRUCT(
-    client::ast::program,
+    client::ast::expression,
     (client::ast::operand, first)
     (std::list<client::ast::operation>, rest)
 )
 
+BOOST_FUSION_ADAPT_STRUCT(
+    client::ast::variable_declaration,
+    (client::ast::assignment, assign)
+)
+
+BOOST_FUSION_ADAPT_STRUCT(
+    client::ast::assignment,
+    (client::ast::variable, lhs)
+    (client::ast::expression, rhs)
+)
+
 #endif
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-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -11,10 +11,33 @@
 
 namespace client
 {
-    void compiler::operator()(ast::unsigned_ const& x) const
+    void compiler::op(int a) const
     {
-        op(op_int);
-        op(x.n);
+        code.push_back(a);
+    }
+
+    void compiler::op(int a, int b) const
+    {
+        code.push_back(a);
+        code.push_back(b);
+    }
+
+    void compiler::op(int a, int b, int c) const
+    {
+        code.push_back(a);
+        code.push_back(b);
+        code.push_back(c);
+    }
+
+    void compiler::operator()(unsigned int x) const
+    {
+        op(op_int, x);
+    }
+
+    void compiler::operator()(ast::variable const& x) const
+    {
+        // $$$ TODO $$$
+        op(op_int, 555); // for now
     }
 
     void compiler::operator()(ast::operation const& x) const
@@ -41,7 +64,7 @@
         }
     }
 
-    void compiler::operator()(ast::program const& x) const
+    void compiler::operator()(ast::expression const& x) const
     {
         boost::apply_visitor(*this, x.first);
         BOOST_FOREACH(ast::operation const& oper, x.rest)
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-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -23,13 +23,16 @@
         compiler(std::vector<int>& code)
           : code(code) {}
 
-        void op(int opcode) const { code.push_back(opcode); }
+        void op(int a) const;
+        void op(int a, int b) const;
+        void op(int a, int b, int c) const;
 
         void operator()(ast::nil) const { BOOST_ASSERT(0); }
-        void operator()(ast::unsigned_ const& x) const;
+        void operator()(unsigned int x) const;
+        void operator()(ast::variable 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::expression const& x) const;
     };
 }
 
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/expression.hpp	2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -23,7 +23,7 @@
 
 #include <boost/spirit/include/qi.hpp>
 #include "ast.hpp"
-#include <map>
+#include <vector>
 
 namespace client
 {
@@ -34,18 +34,18 @@
     //  The expression grammar
     ///////////////////////////////////////////////////////////////////////////////
     template <typename Iterator>
-    struct expression : qi::grammar<Iterator, ast::program(), ascii::space_type>
+    struct expression : qi::grammar<Iterator, ast::expression(), ascii::space_type>
     {
         expression();
 
-        qi::rule<Iterator, ast::program(), ascii::space_type> expr;
-        qi::rule<Iterator, ast::program(), ascii::space_type> additive_expr;
-        qi::rule<Iterator, ast::program(), ascii::space_type> multiplicative_expr;
+        qi::rule<Iterator, ast::expression(), ascii::space_type> expr;
+        qi::rule<Iterator, ast::expression(), ascii::space_type> additive_expr;
+        qi::rule<Iterator, ast::expression(), ascii::space_type> multiplicative_expr;
         qi::rule<Iterator, ast::operand(), ascii::space_type> unary_expr;
         qi::rule<Iterator, ast::operand(), ascii::space_type> primary_expr;
+        qi::rule<Iterator, std::string(), ascii::space_type> identifier;
 
-        std::map<int, Iterator> iters;
-        int current_id;
+        std::vector<Iterator> iters;
     };
 }
 
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-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -13,7 +13,6 @@
     template <typename Iterator>
     expression<Iterator>::expression()
       : expression::base_type(expr)
-      , current_id(0)
     {
         qi::char_type char_;
         qi::uint_type uint_;
@@ -21,6 +20,10 @@
         qi::_2_type _2;
         qi::_3_type _3;
         qi::_4_type _4;
+        qi::raw_type raw;
+        qi::lexeme_type lexeme;
+        qi::alpha_type alpha;
+        qi::alnum_type alnum;
 
         using qi::on_error;
         using qi::on_success;
@@ -51,10 +54,15 @@
             ;
 
         primary_expr =
-            uint_
+                uint_
+            |   identifier
             |   '(' > expr > ')'
             ;
 
+        identifier =
+            raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
+            ;
+
         // Debugging and error handling and reporting support.
         BOOST_SPIRIT_DEBUG_NODES(
             (expr)
@@ -62,6 +70,7 @@
             (multiplicative_expr)
             (unary_expr)
             (primary_expr)
+            (identifier)
         );
 
         // Error handling: on error in expr, call error_handler.
@@ -70,9 +79,8 @@
         // Annotation: on success in primary_expr, call annotation.
         typedef client::annotation<Iterator> annotation_;
         typename function<annotation_>
-            annotation = annotation_(current_id, iters);
+            annotation = annotation_(iters);
         on_success(primary_expr, annotation(_val, _3));
-        on_success(unary_expr, annotation(_val, _3));
     }
 }
 
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/main.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/calc7/main.cpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/main.cpp	2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -35,7 +35,7 @@
 
     typedef std::string::const_iterator iterator_type;
     typedef client::expression<iterator_type> expression;
-    typedef client::ast::program ast_program;
+    typedef client::ast::expression ast_expression;
     typedef client::compiler compiler;
 
     std::string str;
@@ -44,22 +44,22 @@
         if (str.empty() || str[0] == 'q' || str[0] == 'Q')
             break;
 
-        client::vmachine mach;  // Our virtual machine
-        std::vector<int> code;  // Our VM code
-        expression calc;        // Our grammar
-        ast_program program;    // Our program (AST)
-        compiler compile(code); // Our compiler
+        client::vmachine mach;      // Our virtual machine
+        std::vector<int> code;      // Our VM code
+        expression calc;            // Our grammar
+        ast_expression expression;  // Our program (AST)
+        compiler compile(code);     // Our compiler
 
         std::string::const_iterator iter = str.begin();
         std::string::const_iterator end = str.end();
         boost::spirit::ascii::space_type space;
-        bool r = phrase_parse(iter, end, calc, space, program);
+        bool r = phrase_parse(iter, end, calc, space, expression);
 
         if (r && iter == end)
         {
             std::cout << "-------------------------\n";
             std::cout << "Parsing succeeded\n";
-            compile(program);
+            compile(expression);
             mach.execute(code);
             std::cout << "\nResult: " << mach.top() << std::endl;
             std::cout << "-------------------------\n";
Added: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement.cpp	2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -0,0 +1,10 @@
+/*=============================================================================
+    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)
+=============================================================================*/
+#include "statement_def.hpp"
+
+typedef std::string::const_iterator iterator_type;
+template struct client::statement<iterator_type>;
Added: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement.hpp	2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -0,0 +1,39 @@
+/*=============================================================================
+    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_STATEMENT_HPP)
+#define BOOST_SPIRIT_CALC7_STATEMENT_HPP
+
+#include "expression.hpp"
+
+namespace client
+{
+    ///////////////////////////////////////////////////////////////////////////////
+    //  The statement grammar
+    ///////////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    struct statement : qi::grammar<Iterator, ast::statement(), ascii::space_type>
+    {
+        statement();
+
+        expression<Iterator> expr;
+        qi::rule<Iterator, ast::statement(), ascii::space_type> start;
+        qi::rule<Iterator, ast::variable_declaration(), ascii::space_type> variable_declaration;
+        qi::rule<Iterator, ast::assignment(), ascii::space_type> assignment;
+        qi::rule<Iterator, std::string(), ascii::space_type> identifier;
+
+
+        //~ variable_declaration;
+        //~ qi::rule<Iterator, std::string(), ascii::space_type> identifier;
+        //~ qi::rule<Iterator, int(), ascii::space_type> var_ref;
+        //~ qi::rule<Iterator, qi::locals<int>, ascii::space_type> assignment;
+        //~ qi::rule<Iterator, void(int), ascii::space_type> assignment_rhs;
+    };
+}
+
+#endif
+
+
Added: trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement_def.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/calc7/statement_def.hpp	2011-02-27 06:58:18 EST (Sun, 27 Feb 2011)
@@ -0,0 +1,69 @@
+/*=============================================================================
+    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)
+=============================================================================*/
+#include "statement.hpp"
+#include "error_handler.hpp"
+#include "annotation.hpp"
+
+namespace client
+{
+    template <typename Iterator>
+    statement<Iterator>::statement()
+      : statement::base_type(start)
+    {
+        qi::_val_type _val;
+        qi::_2_type _2;
+        qi::_3_type _3;
+        qi::_4_type _4;
+        qi::raw_type raw;
+        qi::lexeme_type lexeme;
+        qi::alpha_type alpha;
+        qi::alnum_type alnum;
+
+        using qi::on_error;
+        using qi::on_success;
+        using qi::fail;
+
+        start =
+            +(variable_declaration | assignment)
+            ;
+
+        identifier =
+            raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
+            ;
+
+        variable_declaration =
+                ("var" >> !(alnum | '_'))   // make sure we have whole words
+            >   assignment
+            ;
+
+        assignment =
+                identifier
+            >   '='
+            >   expr
+            >   ';'
+            ;
+
+        // Debugging and error handling and reporting support.
+        BOOST_SPIRIT_DEBUG_NODES(
+            (start)
+            (identifier)
+            (variable_declaration)
+            (assignment)
+        );
+
+        // Error handling: on error in start, call error_handler.
+        on_error<fail>(start, error_handler(_4, _3, _2));
+
+        // Annotation: on success in variable, call annotation.
+        typedef client::annotation<Iterator> annotation_;
+        typename function<annotation_>
+            annotation = annotation_(expr.iters);
+        on_success(assignment, annotation(_val, _3));
+    }
+}
+
+