]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/qi/compiler_tutorial/mini_c/expression_def.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / example / qi / compiler_tutorial / mini_c / expression_def.hpp
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 #include "expression.hpp"
8 #include "error_handler.hpp"
9 #include "annotation.hpp"
10 #include <boost/spirit/include/phoenix_function.hpp>
11
12 namespace client { namespace parser
13 {
14 template <typename Iterator>
15 expression<Iterator>::expression(error_handler<Iterator>& error_handler)
16 : expression::base_type(expr)
17 {
18 qi::_1_type _1;
19 qi::_2_type _2;
20 qi::_3_type _3;
21 qi::_4_type _4;
22
23 qi::char_type char_;
24 qi::uint_type uint_;
25 qi::_val_type _val;
26 qi::raw_type raw;
27 qi::lexeme_type lexeme;
28 qi::alpha_type alpha;
29 qi::alnum_type alnum;
30 qi::bool_type bool_;
31
32 using qi::on_error;
33 using qi::on_success;
34 using qi::fail;
35 using boost::phoenix::function;
36
37 typedef function<client::error_handler<Iterator> > error_handler_function;
38 typedef function<client::annotation<Iterator> > annotation_function;
39
40 ///////////////////////////////////////////////////////////////////////
41 // Tokens
42 logical_or_op.add
43 ("||", ast::op_or)
44 ;
45
46 logical_and_op.add
47 ("&&", ast::op_and)
48 ;
49
50 equality_op.add
51 ("==", ast::op_equal)
52 ("!=", ast::op_not_equal)
53 ;
54
55 relational_op.add
56 ("<", ast::op_less)
57 ("<=", ast::op_less_equal)
58 (">", ast::op_greater)
59 (">=", ast::op_greater_equal)
60 ;
61
62 additive_op.add
63 ("+", ast::op_plus)
64 ("-", ast::op_minus)
65 ;
66
67 multiplicative_op.add
68 ("*", ast::op_times)
69 ("/", ast::op_divide)
70 ;
71
72 unary_op.add
73 ("+", ast::op_positive)
74 ("-", ast::op_negative)
75 ("!", ast::op_not)
76 ;
77
78 keywords.add
79 ("true")
80 ("false")
81 ("if")
82 ("else")
83 ("while")
84 ("int")
85 ("void")
86 ("return")
87 ;
88
89 ///////////////////////////////////////////////////////////////////////
90 // Main expression grammar
91 expr =
92 logical_or_expr.alias()
93 ;
94
95 logical_or_expr =
96 logical_and_expr
97 >> *(logical_or_op > logical_and_expr)
98 ;
99
100 logical_and_expr =
101 equality_expr
102 >> *(logical_and_op > equality_expr)
103 ;
104
105 equality_expr =
106 relational_expr
107 >> *(equality_op > relational_expr)
108 ;
109
110 relational_expr =
111 additive_expr
112 >> *(relational_op > additive_expr)
113 ;
114
115 additive_expr =
116 multiplicative_expr
117 >> *(additive_op > multiplicative_expr)
118 ;
119
120 multiplicative_expr =
121 unary_expr
122 >> *(multiplicative_op > unary_expr)
123 ;
124
125 unary_expr =
126 primary_expr
127 | (unary_op > unary_expr)
128 ;
129
130 primary_expr =
131 uint_
132 | function_call
133 | identifier
134 | bool_
135 | '(' > expr > ')'
136 ;
137
138 function_call =
139 (identifier >> '(')
140 > argument_list
141 > ')'
142 ;
143
144 argument_list = -(expr % ',');
145
146 identifier =
147 !lexeme[keywords >> !(alnum | '_')]
148 >> raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
149 ;
150
151 ///////////////////////////////////////////////////////////////////////
152 // Debugging and error handling and reporting support.
153 BOOST_SPIRIT_DEBUG_NODES(
154 (expr)
155 (logical_or_expr)
156 (logical_and_expr)
157 (equality_expr)
158 (relational_expr)
159 (additive_expr)
160 (multiplicative_expr)
161 (unary_expr)
162 (primary_expr)
163 (function_call)
164 (argument_list)
165 (identifier)
166 );
167
168 ///////////////////////////////////////////////////////////////////////
169 // Error handling: on error in expr, call error_handler.
170 on_error<fail>(expr,
171 error_handler_function(error_handler)(
172 "Error! Expecting ", _4, _3));
173
174 ///////////////////////////////////////////////////////////////////////
175 // Annotation: on success in primary_expr, call annotation.
176 on_success(primary_expr,
177 annotation_function(error_handler.iters)(_val, _1));
178 }
179 }}
180
181