1/*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6=============================================================================*/
7#if !defined(BOOST_SPIRIT_CALC8_AST_HPP)
8#define BOOST_SPIRIT_CALC8_AST_HPP
9
10#include <boost/variant/recursive_variant.hpp>
11#include <boost/fusion/include/adapt_struct.hpp>
12#include <boost/fusion/include/io.hpp>
13#include <boost/optional.hpp>
14#include <list>
15
16namespace client { namespace ast
17{
18 ///////////////////////////////////////////////////////////////////////////
19 // The AST
20 ///////////////////////////////////////////////////////////////////////////
21 struct tagged
22 {
23 int id; // Used to annotate the AST with the iterator position.
24 // This id is used as a key to a map<int, Iterator>
25 // (not really part of the AST.)
26 };
27
28 struct nil {};
29 struct unary;
30 struct expression;
31
32 struct variable : tagged
33 {
34 variable(std::string const& name = "") : name(name) {}
35 std::string name;
36 };
37
38 typedef boost::variant<
39 nil
40 , bool
41 , unsigned int
42 , variable
43 , boost::recursive_wrapper<unary>
44 , boost::recursive_wrapper<expression>
45 >
46 operand;
47
48 enum optoken
49 {
50 op_plus,
51 op_minus,
52 op_times,
53 op_divide,
54 op_positive,
55 op_negative,
56 op_not,
57 op_equal,
58 op_not_equal,
59 op_less,
60 op_less_equal,
61 op_greater,
62 op_greater_equal,
63 op_and,
64 op_or
65 };
66
67 struct unary
68 {
69 optoken operator_;
70 operand operand_;
71 };
72
73 struct operation
74 {
75 optoken operator_;
76 operand operand_;
77 };
78
79 struct expression
80 {
81 operand first;
82 std::list<operation> rest;
83 };
84
85 struct assignment
86 {
87 variable lhs;
88 expression rhs;
89 };
90
91 struct variable_declaration
92 {
93 assignment assign;
94 };
95
96 struct if_statement;
97 struct while_statement;
98 struct statement_list;
99
100 typedef boost::variant<
101 variable_declaration
102 , assignment
103 , boost::recursive_wrapper<if_statement>
104 , boost::recursive_wrapper<while_statement>
105 , boost::recursive_wrapper<statement_list>
106 >
107 statement;
108
109 struct statement_list : std::list<statement> {};
110
111 struct if_statement
112 {
113 expression condition;
114 statement then;
115 boost::optional<statement> else_;
116 };
117
118 struct while_statement
119 {
120 expression condition;
121 statement body;
122 };
123
124 // print functions for debugging
125 inline std::ostream& operator<<(std::ostream& out, nil) { out << "nil"; return out; }
126 inline std::ostream& operator<<(std::ostream& out, variable const& var) { out << var.name; return out; }
127}}
128
129BOOST_FUSION_ADAPT_STRUCT(
130 client::ast::unary,
131 (client::ast::optoken, operator_)
132 (client::ast::operand, operand_)
133)
134
135BOOST_FUSION_ADAPT_STRUCT(
136 client::ast::operation,
137 (client::ast::optoken, operator_)
138 (client::ast::operand, operand_)
139)
140
141BOOST_FUSION_ADAPT_STRUCT(
142 client::ast::expression,
143 (client::ast::operand, first)
144 (std::list<client::ast::operation>, rest)
145)
146
147BOOST_FUSION_ADAPT_STRUCT(
148 client::ast::variable_declaration,
149 (client::ast::assignment, assign)
150)
151
152BOOST_FUSION_ADAPT_STRUCT(
153 client::ast::assignment,
154 (client::ast::variable, lhs)
155 (client::ast::expression, rhs)
156)
157
158BOOST_FUSION_ADAPT_STRUCT(
159 client::ast::if_statement,
160 (client::ast::expression, condition)
161 (client::ast::statement, then)
162 (boost::optional<client::ast::statement>, else_)
163)
164
165BOOST_FUSION_ADAPT_STRUCT(
166 client::ast::while_statement,
167 (client::ast::expression, condition)
168 (client::ast::statement, body)
169)
170
171#endif
172

source code of boost/libs/spirit/example/qi/compiler_tutorial/calc8/ast.hpp