expression_def.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. =============================================================================*/
  6. #include "expression.hpp"
  7. #include "error_handler.hpp"
  8. #include "annotation.hpp"
  9. #include <boost/spirit/include/phoenix_function.hpp>
  10. namespace client { namespace parser
  11. {
  12. template <typename Iterator>
  13. expression<Iterator>::expression(error_handler<Iterator>& error_handler)
  14. : expression::base_type(expr)
  15. {
  16. qi::_1_type _1;
  17. qi::_2_type _2;
  18. qi::_3_type _3;
  19. qi::_4_type _4;
  20. qi::char_type char_;
  21. qi::uint_type uint_;
  22. qi::_val_type _val;
  23. qi::raw_type raw;
  24. qi::lexeme_type lexeme;
  25. qi::alpha_type alpha;
  26. qi::alnum_type alnum;
  27. qi::bool_type bool_;
  28. using qi::on_error;
  29. using qi::on_success;
  30. using qi::fail;
  31. using boost::phoenix::function;
  32. typedef function<client::error_handler<Iterator> > error_handler_function;
  33. typedef function<client::annotation<Iterator> > annotation_function;
  34. ///////////////////////////////////////////////////////////////////////
  35. // Tokens
  36. logical_op.add
  37. ("&&", ast::op_and)
  38. ("||", ast::op_or)
  39. ;
  40. equality_op.add
  41. ("==", ast::op_equal)
  42. ("!=", ast::op_not_equal)
  43. ;
  44. relational_op.add
  45. ("<", ast::op_less)
  46. ("<=", ast::op_less_equal)
  47. (">", ast::op_greater)
  48. (">=", ast::op_greater_equal)
  49. ;
  50. additive_op.add
  51. ("+", ast::op_plus)
  52. ("-", ast::op_minus)
  53. ;
  54. multiplicative_op.add
  55. ("*", ast::op_times)
  56. ("/", ast::op_divide)
  57. ;
  58. unary_op.add
  59. ("+", ast::op_positive)
  60. ("-", ast::op_negative)
  61. ("!", ast::op_not)
  62. ;
  63. keywords.add
  64. ("var")
  65. ("true")
  66. ("false")
  67. ("if")
  68. ("else")
  69. ("while")
  70. ;
  71. ///////////////////////////////////////////////////////////////////////
  72. // Main expression grammar
  73. expr =
  74. logical_expr.alias()
  75. ;
  76. logical_expr =
  77. equality_expr
  78. >> *(logical_op > equality_expr)
  79. ;
  80. equality_expr =
  81. relational_expr
  82. >> *(equality_op > relational_expr)
  83. ;
  84. relational_expr =
  85. additive_expr
  86. >> *(relational_op > additive_expr)
  87. ;
  88. additive_expr =
  89. multiplicative_expr
  90. >> *(additive_op > multiplicative_expr)
  91. ;
  92. multiplicative_expr =
  93. unary_expr
  94. >> *(multiplicative_op > unary_expr)
  95. ;
  96. unary_expr =
  97. primary_expr
  98. | (unary_op > primary_expr)
  99. ;
  100. primary_expr =
  101. uint_
  102. | identifier
  103. | bool_
  104. | '(' > expr > ')'
  105. ;
  106. identifier =
  107. !keywords
  108. >> raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
  109. ;
  110. ///////////////////////////////////////////////////////////////////////
  111. // Debugging and error handling and reporting support.
  112. BOOST_SPIRIT_DEBUG_NODES(
  113. (expr)
  114. (equality_expr)
  115. (relational_expr)
  116. (logical_expr)
  117. (additive_expr)
  118. (multiplicative_expr)
  119. (unary_expr)
  120. (primary_expr)
  121. (identifier)
  122. );
  123. ///////////////////////////////////////////////////////////////////////
  124. // Error handling: on error in expr, call error_handler.
  125. on_error<fail>(expr,
  126. error_handler_function(error_handler)(
  127. "Error! Expecting ", _4, _3));
  128. ///////////////////////////////////////////////////////////////////////
  129. // Annotation: on success in primary_expr, call annotation.
  130. on_success(primary_expr,
  131. annotation_function(error_handler.iters)(_val, _1));
  132. }
  133. }}