]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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" | |
1e59de90 | 10 | #include <boost/phoenix/function.hpp> |
7c673cae FG |
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_op.add | |
43 | ("&&", ast::op_and) | |
44 | ("||", ast::op_or) | |
45 | ; | |
46 | ||
47 | equality_op.add | |
48 | ("==", ast::op_equal) | |
49 | ("!=", ast::op_not_equal) | |
50 | ; | |
51 | ||
52 | relational_op.add | |
53 | ("<", ast::op_less) | |
54 | ("<=", ast::op_less_equal) | |
55 | (">", ast::op_greater) | |
56 | (">=", ast::op_greater_equal) | |
57 | ; | |
58 | ||
59 | additive_op.add | |
60 | ("+", ast::op_plus) | |
61 | ("-", ast::op_minus) | |
62 | ; | |
63 | ||
64 | multiplicative_op.add | |
65 | ("*", ast::op_times) | |
66 | ("/", ast::op_divide) | |
67 | ; | |
68 | ||
69 | unary_op.add | |
70 | ("+", ast::op_positive) | |
71 | ("-", ast::op_negative) | |
72 | ("!", ast::op_not) | |
73 | ; | |
74 | ||
75 | keywords.add | |
76 | ("var") | |
77 | ("true") | |
78 | ("false") | |
79 | ("if") | |
80 | ("else") | |
81 | ("while") | |
82 | ; | |
83 | ||
84 | /////////////////////////////////////////////////////////////////////// | |
85 | // Main expression grammar | |
86 | expr = | |
87 | logical_expr.alias() | |
88 | ; | |
89 | ||
90 | logical_expr = | |
91 | equality_expr | |
92 | >> *(logical_op > equality_expr) | |
93 | ; | |
94 | ||
95 | equality_expr = | |
96 | relational_expr | |
97 | >> *(equality_op > relational_expr) | |
98 | ; | |
99 | ||
100 | relational_expr = | |
101 | additive_expr | |
102 | >> *(relational_op > additive_expr) | |
103 | ; | |
104 | ||
105 | additive_expr = | |
106 | multiplicative_expr | |
107 | >> *(additive_op > multiplicative_expr) | |
108 | ; | |
109 | ||
110 | multiplicative_expr = | |
111 | unary_expr | |
112 | >> *(multiplicative_op > unary_expr) | |
113 | ; | |
114 | ||
115 | unary_expr = | |
116 | primary_expr | |
117 | | (unary_op > primary_expr) | |
118 | ; | |
119 | ||
120 | primary_expr = | |
121 | uint_ | |
122 | | identifier | |
123 | | bool_ | |
124 | | '(' > expr > ')' | |
125 | ; | |
126 | ||
127 | identifier = | |
128 | !keywords | |
129 | >> raw[lexeme[(alpha | '_') >> *(alnum | '_')]] | |
130 | ; | |
131 | ||
132 | /////////////////////////////////////////////////////////////////////// | |
133 | // Debugging and error handling and reporting support. | |
134 | BOOST_SPIRIT_DEBUG_NODES( | |
135 | (expr) | |
136 | (equality_expr) | |
137 | (relational_expr) | |
138 | (logical_expr) | |
139 | (additive_expr) | |
140 | (multiplicative_expr) | |
141 | (unary_expr) | |
142 | (primary_expr) | |
143 | (identifier) | |
144 | ); | |
145 | ||
146 | /////////////////////////////////////////////////////////////////////// | |
147 | // Error handling: on error in expr, call error_handler. | |
148 | on_error<fail>(expr, | |
149 | error_handler_function(error_handler)( | |
150 | "Error! Expecting ", _4, _3)); | |
151 | ||
152 | /////////////////////////////////////////////////////////////////////// | |
153 | // Annotation: on success in primary_expr, call annotation. | |
154 | on_success(primary_expr, | |
155 | annotation_function(error_handler.iters)(_val, _1)); | |
156 | } | |
157 | }} | |
158 | ||
159 |