blob: 2d46b73026af227ef21bc265466f012dccdb1e4e [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CALC9_EXPRESSION_DEF_HPP)
#define BOOST_SPIRIT_X3_CALC9_EXPRESSION_DEF_HPP
#include <boost/spirit/home/x3.hpp>
#include "ast.hpp"
#include "ast_adapted.hpp"
#include "expression.hpp"
#include "common.hpp"
#include "error_handler.hpp"
#include "annotation.hpp"
namespace client { namespace parser
{
using x3::uint_;
using x3::char_;
using x3::bool_;
using x3::raw;
using x3::lexeme;
using namespace x3::ascii;
////////////////////////////////////////////////////////////////////////////
// Tokens
////////////////////////////////////////////////////////////////////////////
x3::symbols<char, ast::optoken> equality_op;
x3::symbols<char, ast::optoken> relational_op;
x3::symbols<char, ast::optoken> logical_op;
x3::symbols<char, ast::optoken> additive_op;
x3::symbols<char, ast::optoken> multiplicative_op;
x3::symbols<char, ast::optoken> unary_op;
x3::symbols<char> keywords;
void add_keywords()
{
static bool once = false;
if (once)
return;
once = true;
logical_op.add
("&&", ast::op_and)
("||", ast::op_or)
;
equality_op.add
("==", ast::op_equal)
("!=", ast::op_not_equal)
;
relational_op.add
("<", ast::op_less)
("<=", ast::op_less_equal)
(">", ast::op_greater)
(">=", ast::op_greater_equal)
;
additive_op.add
("+", ast::op_plus)
("-", ast::op_minus)
;
multiplicative_op.add
("*", ast::op_times)
("/", ast::op_divide)
;
unary_op.add
("+", ast::op_positive)
("-", ast::op_negative)
("!", ast::op_not)
;
keywords.add
("var")
("true")
("false")
("if")
("else")
("while")
;
}
////////////////////////////////////////////////////////////////////////////
// Main expression grammar
////////////////////////////////////////////////////////////////////////////
struct expression_class;
struct equality_expr_class;
struct relational_expr_class;
struct logical_expr_class;
struct additive_expr_class;
struct multiplicative_expr_class;
struct unary_expr_class;
struct primary_expr_class;
typedef x3::rule<expression_class, ast::expression> expression_type;
typedef x3::rule<equality_expr_class, ast::expression> equality_expr_type;
typedef x3::rule<relational_expr_class, ast::expression> relational_expr_type;
typedef x3::rule<logical_expr_class, ast::expression> logical_expr_type;
typedef x3::rule<additive_expr_class, ast::expression> additive_expr_type;
typedef x3::rule<multiplicative_expr_class, ast::expression> multiplicative_expr_type;
typedef x3::rule<unary_expr_class, ast::operand> unary_expr_type;
typedef x3::rule<primary_expr_class, ast::operand> primary_expr_type;
expression_type const expression = "expression";
equality_expr_type const equality_expr = "equality_expr";
relational_expr_type const relational_expr = "relational_expr";
logical_expr_type const logical_expr = "logical_expr";
additive_expr_type const additive_expr = "additive_expr";
multiplicative_expr_type const multiplicative_expr = "multiplicative_expr";
unary_expr_type unary_expr = "unary_expr";
primary_expr_type primary_expr = "primary_expr";
auto const logical_expr_def =
equality_expr
>> *(logical_op > equality_expr)
;
auto const equality_expr_def =
relational_expr
>> *(equality_op > relational_expr)
;
auto const relational_expr_def =
additive_expr
>> *(relational_op > additive_expr)
;
auto const additive_expr_def =
multiplicative_expr
>> *(additive_op > multiplicative_expr)
;
auto const multiplicative_expr_def =
unary_expr
>> *(multiplicative_op > unary_expr)
;
auto const unary_expr_def =
primary_expr
| (unary_op > primary_expr)
;
auto const primary_expr_def =
uint_
| bool_
| (!keywords >> identifier)
| '(' > expression > ')'
;
BOOST_SPIRIT_DEFINE(
expression = logical_expr
, logical_expr = logical_expr_def
, equality_expr = equality_expr_def
, relational_expr = relational_expr_def
, additive_expr = additive_expr_def
, multiplicative_expr = multiplicative_expr_def
, unary_expr = unary_expr_def
, primary_expr = primary_expr_def
);
struct unary_expr_class : annotation_base {};
struct primary_expr_class : annotation_base {};
}}
namespace client
{
parser::expression_type const& expression()
{
parser::add_keywords();
return parser::expression;
}
}
#endif