1 /*============================================================================= 2 Copyright (c) 2001-2014 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_X3_CALC9_EXPRESSION_DEF_HPP) 8 #define BOOST_SPIRIT_X3_CALC9_EXPRESSION_DEF_HPP 9 10 #include <boost/spirit/home/x3.hpp> 11 #include <boost/spirit/home/x3/support/utility/annotate_on_success.hpp> 12 #include "ast.hpp" 13 #include "ast_adapted.hpp" 14 #include "expression.hpp" 15 #include "common.hpp" 16 #include "error_handler.hpp" 17 18 namespace client { namespace parser 19 { 20 using x3::uint_; 21 using x3::char_; 22 using x3::bool_; 23 using x3::raw; 24 using x3::lexeme; 25 using namespace x3::ascii; 26 27 //////////////////////////////////////////////////////////////////////////// 28 // Tokens 29 //////////////////////////////////////////////////////////////////////////// 30 31 x3::symbols<ast::optoken> equality_op; 32 x3::symbols<ast::optoken> relational_op; 33 x3::symbols<ast::optoken> logical_op; 34 x3::symbols<ast::optoken> additive_op; 35 x3::symbols<ast::optoken> multiplicative_op; 36 x3::symbols<ast::optoken> unary_op; 37 x3::symbols<> keywords; 38 add_keywords()39 void add_keywords() 40 { 41 static bool once = false; 42 if (once) 43 return; 44 once = true; 45 46 logical_op.add 47 ("&&", ast::op_and) 48 ("||", ast::op_or) 49 ; 50 51 equality_op.add 52 ("==", ast::op_equal) 53 ("!=", ast::op_not_equal) 54 ; 55 56 relational_op.add 57 ("<", ast::op_less) 58 ("<=", ast::op_less_equal) 59 (">", ast::op_greater) 60 (">=", ast::op_greater_equal) 61 ; 62 63 additive_op.add 64 ("+", ast::op_plus) 65 ("-", ast::op_minus) 66 ; 67 68 multiplicative_op.add 69 ("*", ast::op_times) 70 ("/", ast::op_divide) 71 ; 72 73 unary_op.add 74 ("+", ast::op_positive) 75 ("-", ast::op_negative) 76 ("!", ast::op_not) 77 ; 78 79 keywords.add 80 ("var") 81 ("true") 82 ("false") 83 ("if") 84 ("else") 85 ("while") 86 ; 87 } 88 89 //////////////////////////////////////////////////////////////////////////// 90 // Main expression grammar 91 //////////////////////////////////////////////////////////////////////////// 92 93 struct equality_expr_class; 94 struct relational_expr_class; 95 struct logical_expr_class; 96 struct additive_expr_class; 97 struct multiplicative_expr_class; 98 struct unary_expr_class; 99 struct primary_expr_class; 100 101 typedef x3::rule<equality_expr_class, ast::expression> equality_expr_type; 102 typedef x3::rule<relational_expr_class, ast::expression> relational_expr_type; 103 typedef x3::rule<logical_expr_class, ast::expression> logical_expr_type; 104 typedef x3::rule<additive_expr_class, ast::expression> additive_expr_type; 105 typedef x3::rule<multiplicative_expr_class, ast::expression> multiplicative_expr_type; 106 typedef x3::rule<unary_expr_class, ast::operand> unary_expr_type; 107 typedef x3::rule<primary_expr_class, ast::operand> primary_expr_type; 108 109 expression_type const expression = "expression"; 110 equality_expr_type const equality_expr = "equality_expr"; 111 relational_expr_type const relational_expr = "relational_expr"; 112 logical_expr_type const logical_expr = "logical_expr"; 113 additive_expr_type const additive_expr = "additive_expr"; 114 multiplicative_expr_type const multiplicative_expr = "multiplicative_expr"; 115 unary_expr_type const unary_expr = "unary_expr"; 116 primary_expr_type const primary_expr = "primary_expr"; 117 118 auto const logical_expr_def = 119 equality_expr 120 >> *(logical_op > equality_expr) 121 ; 122 123 auto const equality_expr_def = 124 relational_expr 125 >> *(equality_op > relational_expr) 126 ; 127 128 auto const relational_expr_def = 129 additive_expr 130 >> *(relational_op > additive_expr) 131 ; 132 133 auto const additive_expr_def = 134 multiplicative_expr 135 >> *(additive_op > multiplicative_expr) 136 ; 137 138 auto const multiplicative_expr_def = 139 unary_expr 140 >> *(multiplicative_op > unary_expr) 141 ; 142 143 auto const unary_expr_def = 144 primary_expr 145 | (unary_op > primary_expr) 146 ; 147 148 auto const primary_expr_def = 149 uint_ 150 | bool_ 151 | (!keywords >> identifier) 152 | '(' > expression > ')' 153 ; 154 155 auto const expression_def = logical_expr; 156 157 BOOST_SPIRIT_DEFINE( 158 expression 159 , logical_expr 160 , equality_expr 161 , relational_expr 162 , additive_expr 163 , multiplicative_expr 164 , unary_expr 165 , primary_expr 166 ); 167 168 struct unary_expr_class : x3::annotate_on_success {}; 169 struct primary_expr_class : x3::annotate_on_success {}; 170 171 }} 172 173 namespace client 174 { expression()175 parser::expression_type const& expression() 176 { 177 parser::add_keywords(); 178 return parser::expression; 179 } 180 } 181 182 #endif 183