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_MINIC_AST_HPP)
8#define BOOST_SPIRIT_MINIC_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 function_call;
31 struct expression;
32
33 struct identifier : tagged
34 {
35 identifier(std::string const& name = "") : name(name) {}
36 std::string name;
37 };
38
39 typedef boost::variant<
40 nil
41 , bool
42 , unsigned int
43 , identifier
44 , boost::recursive_wrapper<unary>
45 , boost::recursive_wrapper<function_call>
46 , boost::recursive_wrapper<expression>
47 >
48 operand;
49
50 enum optoken
51 {
52 op_plus,
53 op_minus,
54 op_times,
55 op_divide,
56 op_positive,
57 op_negative,
58 op_not,
59 op_equal,
60 op_not_equal,
61 op_less,
62 op_less_equal,
63 op_greater,
64 op_greater_equal,
65 op_and,
66 op_or
67 };
68
69 struct unary
70 {
71 optoken operator_;
72 operand operand_;
73 };
74
75 struct operation
76 {
77 optoken operator_;
78 operand operand_;
79 };
80
81 struct function_call
82 {
83 identifier function_name;
84 std::list<expression> args;
85 };
86
87 struct expression
88 {
89 operand first;
90 std::list<operation> rest;
91 };
92
93 struct assignment
94 {
95 identifier lhs;
96 expression rhs;
97 };
98
99 struct variable_declaration
100 {
101 identifier lhs;
102 boost::optional<expression> rhs;
103 };
104
105 struct if_statement;
106 struct while_statement;
107 struct statement_list;
108 struct return_statement;
109
110 typedef boost::variant<
111 variable_declaration
112 , assignment
113 , boost::recursive_wrapper<if_statement>
114 , boost::recursive_wrapper<while_statement>
115 , boost::recursive_wrapper<return_statement>
116 , boost::recursive_wrapper<statement_list>
117 >
118 statement;
119
120 struct statement_list : std::list<statement> {};
121
122 struct if_statement
123 {
124 expression condition;
125 statement then;
126 boost::optional<statement> else_;
127 };
128
129 struct while_statement
130 {
131 expression condition;
132 statement body;
133 };
134
135 struct return_statement : tagged
136 {
137 boost::optional<expression> expr;
138 };
139
140 struct function
141 {
142 std::string return_type;
143 identifier function_name;
144 std::list<identifier> args;
145 statement_list body;
146 };
147
148 typedef std::list<function> function_list;
149
150 // print functions for debugging
151 inline std::ostream& operator<<(std::ostream& out, nil)
152 {
153 out << "nil"; return out;
154 }
155
156 inline std::ostream& operator<<(std::ostream& out, identifier const& id)
157 {
158 out << id.name; return out;
159 }
160}}
161
162BOOST_FUSION_ADAPT_STRUCT(
163 client::ast::unary,
164 (client::ast::optoken, operator_)
165 (client::ast::operand, operand_)
166)
167
168BOOST_FUSION_ADAPT_STRUCT(
169 client::ast::operation,
170 (client::ast::optoken, operator_)
171 (client::ast::operand, operand_)
172)
173
174BOOST_FUSION_ADAPT_STRUCT(
175 client::ast::function_call,
176 (client::ast::identifier, function_name)
177 (std::list<client::ast::expression>, args)
178)
179
180BOOST_FUSION_ADAPT_STRUCT(
181 client::ast::expression,
182 (client::ast::operand, first)
183 (std::list<client::ast::operation>, rest)
184)
185
186BOOST_FUSION_ADAPT_STRUCT(
187 client::ast::variable_declaration,
188 (client::ast::identifier, lhs)
189 (boost::optional<client::ast::expression>, rhs)
190)
191
192BOOST_FUSION_ADAPT_STRUCT(
193 client::ast::assignment,
194 (client::ast::identifier, lhs)
195 (client::ast::expression, rhs)
196)
197
198BOOST_FUSION_ADAPT_STRUCT(
199 client::ast::if_statement,
200 (client::ast::expression, condition)
201 (client::ast::statement, then)
202 (boost::optional<client::ast::statement>, else_)
203)
204
205BOOST_FUSION_ADAPT_STRUCT(
206 client::ast::while_statement,
207 (client::ast::expression, condition)
208 (client::ast::statement, body)
209)
210
211BOOST_FUSION_ADAPT_STRUCT(
212 client::ast::return_statement,
213 (boost::optional<client::ast::expression>, expr)
214)
215
216BOOST_FUSION_ADAPT_STRUCT(
217 client::ast::function,
218 (std::string, return_type)
219 (client::ast::identifier, function_name)
220 (std::list<client::ast::identifier>, args)
221 (client::ast::statement_list, body)
222)
223
224#endif
225

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