Skip to content

Commit

Permalink
Semantic analysis of floating literals OK
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian Goujeon committed Jun 10, 2011
1 parent ed970a1 commit f098ec6
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 26 deletions.
3 changes: 3 additions & 0 deletions cpp2xml/src/cpp2xml/semantic_graph.cpp
Expand Up @@ -531,6 +531,9 @@ operator()(const TYPE) \
EXPRESSION_TYPE(unsigned int)
EXPRESSION_TYPE(unsigned long int)
EXPRESSION_TYPE(unsigned long long int)
EXPRESSION_TYPE(float)
EXPRESSION_TYPE(double)
EXPRESSION_TYPE(long double)
} get_expression_type_visitor;

#undef EXPRESSION_TYPE
Expand Down
2 changes: 2 additions & 0 deletions cpp2xml/src/cpp2xml/syntax_tree.hpp
Expand Up @@ -142,9 +142,11 @@ GET_TYPE_SPECIALIZATION(exception_specification)
GET_TYPE_SPECIALIZATION(exclusive_or_expression)
GET_TYPE_SPECIALIZATION(explicit_instantiation)
GET_TYPE_SPECIALIZATION(explicit_specialization)
GET_TYPE_SPECIALIZATION(exponent_part)
GET_TYPE_SPECIALIZATION(expression)
GET_TYPE_SPECIALIZATION(expression_statement)
GET_TYPE_SPECIALIZATION(floating_literal)
GET_TYPE_SPECIALIZATION(floating_suffix)
GET_TYPE_SPECIALIZATION(for_init_statement)
GET_TYPE_SPECIALIZATION(for_statement)
GET_TYPE_SPECIALIZATION(function_definition)
Expand Down
Expand Up @@ -35,6 +35,8 @@ create_expression(const syntax_nodes::literal& literal_node)
return create_value(*opt_integer_literal_node);
if(const boost::optional<const boolean_literal&>& opt_boolean_literal_node = get<boolean_literal>(&literal_node))
return create_boolean_value(*opt_boolean_literal_node);
if(const boost::optional<const floating_literal&>& opt_floating_literal_node = get<floating_literal>(&literal_node))
return create_floating_value(*opt_floating_literal_node);

assert(false);

Expand Down
75 changes: 75 additions & 0 deletions src/scalpel/cpp/semantic_analysis/detail/value_construction.cpp
Expand Up @@ -476,5 +476,80 @@ create_boolean_value(const syntax_nodes::boolean_literal& boolean_literal_node)
return true;
}



namespace
{
template<typename Float>
Float
string_to_float(const syntax_nodes::floating_literal& floating_literal_node)
{
Float integer_part = 0;
if(get_integer_part(floating_literal_node))
{
const std::string& integer_part_str = get_integer_part(floating_literal_node)->value();
std::istringstream integer_part_iss(integer_part_str);
integer_part_iss >> integer_part;
}

Float fractional_part = 0;
if(get_fractional_part(floating_literal_node))
{
const std::string& fractional_part_str = get_fractional_part(floating_literal_node)->value();

for(int i = fractional_part_str.size() - 1; i >= 0; --i)
{
const unsigned char current_digit_char = fractional_part_str[i];
const unsigned int current_digit = current_digit_char - '0';

fractional_part += current_digit;
fractional_part /= 10;
}
}

Float value = integer_part + fractional_part;

if(const optional_node<exponent_part>& opt_exponent_part_node = get_exponent_part(floating_literal_node))
{
const exponent_part& exponent_part_node = *opt_exponent_part_node;
const std::string& exponent_str = get_digit_sequence(exponent_part_node).value();
const unsigned int exponent = decimal_string_to_integer_converter::convert<unsigned int>(exponent_str);

bool negative_exponent = false;
if(const optional_node<sign>& opt_sign_node = get_sign(exponent_part_node))
{
const std::string& sign = opt_sign_node->value();
negative_exponent = (sign == "-");
}

if(negative_exponent)
for(unsigned int i = 0; i < exponent; ++i)
value /= 10;
else
for(unsigned int i = 0; i < exponent; ++i)
value *= 10;
}

return value;
}
}

semantic_entities::expression_t
create_floating_value(const syntax_nodes::floating_literal& floating_literal_node)
{
if(const optional_node<floating_suffix>& opt_floating_suffix_node = get_floating_suffix(floating_literal_node))
{
const floating_suffix& floating_suffix_node = *opt_floating_suffix_node;

if(get<float_floating_suffix>(&floating_suffix_node))
return string_to_float<float>(floating_literal_node);
else
return string_to_float<long double>(floating_literal_node);
}

//double by default
return string_to_float<double>(floating_literal_node);
}

}}}} //namespace scalpel::cpp::semantic_analysis::detail

Expand Up @@ -33,6 +33,9 @@ create_value(const syntax_nodes::integer_literal& integer_literal_node);
semantic_entities::expression_t
create_boolean_value(const syntax_nodes::boolean_literal& boolean_literal_node);

semantic_entities::expression_t
create_floating_value(const syntax_nodes::floating_literal& floating_literal_node);

}}}} //namespace scalpel::cpp::semantic_analysis::detail

#endif
Expand Down
9 changes: 7 additions & 2 deletions src/scalpel/cpp/semantic_entities/expression.hpp
Expand Up @@ -31,13 +31,18 @@ typedef
<
bool,

//integer values
//integer types
int,
long int,
long long int,
unsigned int,
unsigned long int,
unsigned long long int
unsigned long long int,

//floating types
float,
double,
long double
>
expression_t
;
Expand Down
34 changes: 18 additions & 16 deletions src/scalpel/cpp/syntax_analysis/detail/grammar.cpp
Expand Up @@ -261,32 +261,34 @@ grammar::grammar()
;

floating_literal
= token_node_d
[
fractional_constant >> !exponent_part >> !floating_suffix
| digit_sequence >> exponent_part >> !floating_suffix
]
= !digit_sequence >> no_node_d[ch_p('.')] >> digit_sequence >> !exponent_part >> !floating_suffix
| digit_sequence >> no_node_d[ch_p('.')] >> !exponent_part >> !floating_suffix
| digit_sequence >> exponent_part >> !floating_suffix
;

fractional_constant
= !digit_sequence >> '.' >> digit_sequence
| digit_sequence >> '.'
exponent_part
= no_node_d[ch_p('e') | ch_p('E')] >> !sign >> digit_sequence
;

exponent_part
= ch_p('e') >> !sign_p >> digit_sequence
| ch_p('E') >> !sign_p >> digit_sequence
sign
= token_node_d[sign_p]
;

digit_sequence
= +digit_p
= token_node_d[+digit_p]
;

floating_suffix
= ch_p('f')
| 'l'
| 'F'
| 'L'
= float_floating_suffix
| long_floating_suffix
;

float_floating_suffix
= token_node_d[ch_p('f') | 'F']
;

long_floating_suffix
= token_node_d[ch_p('l') | 'L']
;

string_literal
Expand Down
13 changes: 9 additions & 4 deletions src/scalpel/cpp/syntax_analysis/detail/grammar.hpp
Expand Up @@ -66,8 +66,11 @@ class grammar
FLOATING_LITERAL,
FRACTIONAL_CONSTANT,
EXPONENT_PART,
SIGN,
DIGIT_SEQUENCE,
FLOATING_SUFFIX,
FLOAT_FLOATING_SUFFIX,
LONG_FLOATING_SUFFIX,
STRING_LITERAL,
S_CHAR_SEQUENCE,
S_CHAR,
Expand Down Expand Up @@ -368,10 +371,12 @@ class grammar
boost::spirit::rule<lexeme_scanner_t> octal_escape_sequence;
boost::spirit::rule<lexeme_scanner_t> hexadecimal_escape_sequence;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::FLOATING_LITERAL>> floating_literal;
boost::spirit::rule<lexeme_scanner_t> fractional_constant;
boost::spirit::rule<lexeme_scanner_t> exponent_part;
boost::spirit::rule<lexeme_scanner_t> digit_sequence;
boost::spirit::rule<lexeme_scanner_t> floating_suffix;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::EXPONENT_PART>> exponent_part;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::SIGN>> sign;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::DIGIT_SEQUENCE>> digit_sequence;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::FLOATING_SUFFIX>> floating_suffix;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::FLOAT_FLOATING_SUFFIX>> float_floating_suffix;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::LONG_FLOATING_SUFFIX>> long_floating_suffix;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::STRING_LITERAL>> string_literal;
boost::spirit::rule<lexeme_scanner_t> single_string_literal;
boost::spirit::rule<lexeme_scanner_t> s_char_sequence;
Expand Down
Expand Up @@ -1228,6 +1228,36 @@ SCALPEL_CPP_SYNTAX_ANALYSIS_DETAIL_ID_TYPE_PAIR
floating_literal
)
SCALPEL_CPP_SYNTAX_ANALYSIS_DETAIL_ID_TYPE_PAIR
(
DIGIT_SEQUENCE,
digit_sequence
)
SCALPEL_CPP_SYNTAX_ANALYSIS_DETAIL_ID_TYPE_PAIR
(
EXPONENT_PART,
exponent_part
)
SCALPEL_CPP_SYNTAX_ANALYSIS_DETAIL_ID_TYPE_PAIR
(
SIGN,
sign
)
SCALPEL_CPP_SYNTAX_ANALYSIS_DETAIL_ID_TYPE_PAIR
(
FLOATING_SUFFIX,
floating_suffix
)
SCALPEL_CPP_SYNTAX_ANALYSIS_DETAIL_ID_TYPE_PAIR
(
FLOAT_FLOATING_SUFFIX,
float_floating_suffix
)
SCALPEL_CPP_SYNTAX_ANALYSIS_DETAIL_ID_TYPE_PAIR
(
LONG_FLOATING_SUFFIX,
long_floating_suffix
)
SCALPEL_CPP_SYNTAX_ANALYSIS_DETAIL_ID_TYPE_PAIR
(
INTEGER_LITERAL,
integer_literal
Expand Down

0 comments on commit f098ec6

Please sign in to comment.