]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/qi/compiler_tutorial/conjure3/ast.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / example / qi / compiler_tutorial / conjure3 / ast.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2001-2011 Hartmut Kaiser
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #if !defined(BOOST_SPIRIT_CONJURE_AST_HPP)
9 #define BOOST_SPIRIT_CONJURE_AST_HPP
10
11 #include <boost/config/warning_disable.hpp>
12 #include <boost/variant/recursive_variant.hpp>
13 #include <boost/fusion/include/adapt_struct.hpp>
14 #include <boost/fusion/include/io.hpp>
15 #include <boost/spirit/include/support_extended_variant.hpp>
16 #include <boost/spirit/include/support_attributes.hpp>
17 #include <boost/optional.hpp>
18 #include <list>
19
20 #include "ids.hpp"
21
22 namespace client { namespace ast
23 {
24 ///////////////////////////////////////////////////////////////////////////
25 // The AST
26 ///////////////////////////////////////////////////////////////////////////
27 struct tagged
28 {
29 int id; // Used to annotate the AST with the iterator position.
30 // This id is used as a key to a map<int, Iterator>
31 // (not really part of the AST.)
32 };
33
34 struct nil {};
35 struct unary_expr;
36 struct function_call;
37 struct expression;
38
39 struct identifier : tagged
40 {
41 identifier(std::string const& name = "") : name(name) {}
42 std::string name;
43 };
44
45 struct primary_expr :
46 tagged,
47 boost::spirit::extended_variant<
48 nil
49 , bool
50 , unsigned int
51 , identifier
52 , boost::recursive_wrapper<expression>
53 >
54 {
55 primary_expr() : base_type() {}
56 primary_expr(bool val) : base_type(val) {}
57 primary_expr(unsigned int val) : base_type(val) {}
58 primary_expr(identifier const& val) : base_type(val) {}
59 primary_expr(expression const& val) : base_type(val) {}
60 primary_expr(primary_expr const& rhs)
61 : base_type(rhs.get()) {}
62 };
63
64 struct operand :
65 tagged,
66 boost::spirit::extended_variant<
67 nil
68 , primary_expr
69 , boost::recursive_wrapper<unary_expr>
70 , boost::recursive_wrapper<function_call>
71 >
72 {
73 operand() : base_type() {}
74 operand(primary_expr const& val) : base_type(val) {}
75 operand(unary_expr const& val) : base_type(val) {}
76 operand(function_call const& val) : base_type(val) {}
77 operand(operand const& rhs)
78 : base_type(rhs.get()) {}
79 };
80
81 struct unary_expr : tagged
82 {
83 token_ids::type operator_;
84 operand operand_;
85 };
86
87 struct operation
88 {
89 token_ids::type operator_;
90 operand operand_;
91 };
92
93 struct function_call
94 {
95 identifier function_name;
96 std::list<expression> args;
97 };
98
99 struct expression
100 {
101 operand first;
102 std::list<operation> rest;
103 };
104
105 struct assignment
106 {
107 identifier lhs;
108 token_ids::type operator_;
109 expression rhs;
110 };
111
112 struct variable_declaration
113 {
114 identifier lhs;
115 boost::optional<expression> rhs;
116 };
117
118 struct if_statement;
119 struct while_statement;
120 struct statement_list;
121 struct return_statement;
122
123 typedef boost::variant<
124 nil
125 , variable_declaration
126 , assignment
127 , boost::recursive_wrapper<if_statement>
128 , boost::recursive_wrapper<while_statement>
129 , boost::recursive_wrapper<return_statement>
130 , boost::recursive_wrapper<statement_list>
131 , boost::recursive_wrapper<expression>
132 >
133 statement;
134
135 struct statement_list : std::list<statement> {};
136
137 struct if_statement
138 {
139 expression condition;
140 statement then;
141 boost::optional<statement> else_;
142 };
143
144 struct while_statement
145 {
146 expression condition;
147 statement body;
148 };
149
150 struct return_statement : tagged
151 {
152 boost::optional<expression> expr;
153 };
154
155 struct function
156 {
157 std::string return_type;
158 identifier function_name;
159 std::list<identifier> args;
160 boost::optional<statement_list> body;
161 };
162
163 typedef std::list<function> function_list;
164
165 // print functions for debugging
166 inline std::ostream& operator<<(std::ostream& out, nil)
167 {
168 out << "nil"; return out;
169 }
170
171 inline std::ostream& operator<<(std::ostream& out, identifier const& id)
172 {
173 out << id.name; return out;
174 }
175 }}
176
177 BOOST_FUSION_ADAPT_STRUCT(
178 client::ast::unary_expr,
179 (client::token_ids::type, operator_)
180 (client::ast::operand, operand_)
181 )
182
183 BOOST_FUSION_ADAPT_STRUCT(
184 client::ast::operation,
185 (client::token_ids::type, operator_)
186 (client::ast::operand, operand_)
187 )
188
189 BOOST_FUSION_ADAPT_STRUCT(
190 client::ast::function_call,
191 (client::ast::identifier, function_name)
192 (std::list<client::ast::expression>, args)
193 )
194
195 BOOST_FUSION_ADAPT_STRUCT(
196 client::ast::expression,
197 (client::ast::operand, first)
198 (std::list<client::ast::operation>, rest)
199 )
200
201 BOOST_FUSION_ADAPT_STRUCT(
202 client::ast::variable_declaration,
203 (client::ast::identifier, lhs)
204 (boost::optional<client::ast::expression>, rhs)
205 )
206
207 BOOST_FUSION_ADAPT_STRUCT(
208 client::ast::assignment,
209 (client::ast::identifier, lhs)
210 (client::token_ids::type, operator_)
211 (client::ast::expression, rhs)
212 )
213
214 BOOST_FUSION_ADAPT_STRUCT(
215 client::ast::if_statement,
216 (client::ast::expression, condition)
217 (client::ast::statement, then)
218 (boost::optional<client::ast::statement>, else_)
219 )
220
221 BOOST_FUSION_ADAPT_STRUCT(
222 client::ast::while_statement,
223 (client::ast::expression, condition)
224 (client::ast::statement, body)
225 )
226
227 BOOST_FUSION_ADAPT_STRUCT(
228 client::ast::return_statement,
229 (boost::optional<client::ast::expression>, expr)
230 )
231
232 BOOST_FUSION_ADAPT_STRUCT(
233 client::ast::function,
234 (std::string, return_type)
235 (client::ast::identifier, function_name)
236 (std::list<client::ast::identifier>, args)
237 (boost::optional<client::ast::statement_list>, body)
238 )
239
240 #endif