|
Boost-Commit : |
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));
+ }
+}
+
+
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