Permalink
Browse files

Semantic analysis of character literals OK, except for

universal character names.
  • Loading branch information...
1 parent f098ec6 commit 1bfc0bf4e544cad8c1e888ac48e7f042a0432e9b Florian Goujeon committed Jun 15, 2011
@@ -525,6 +525,8 @@ operator()(const TYPE) \
struct: scalpel::utility::static_visitor<std::string>
{
EXPRESSION_TYPE(bool)
+ EXPRESSION_TYPE(char)
+ EXPRESSION_TYPE(wchar_t)
EXPRESSION_TYPE(int)
EXPRESSION_TYPE(long int)
EXPRESSION_TYPE(long long int)
@@ -553,6 +555,12 @@ operator()(const TYPE) \
output_ << t;
}
+ void
+ operator()(const char c)
+ {
+ output_ << static_cast<int>(c);
+ }
+
void
operator()(const bool b)
{
@@ -81,6 +81,8 @@ GET_TYPE_SPECIALIZATION(boolean_literal)
GET_TYPE_SPECIALIZATION(bracketed_abstract_declarator)
GET_TYPE_SPECIALIZATION(bracketed_declarator)
GET_TYPE_SPECIALIZATION(break_statement)
+GET_TYPE_SPECIALIZATION(c_char)
+GET_TYPE_SPECIALIZATION(c_char_sequence)
GET_TYPE_SPECIALIZATION(case_statement)
GET_TYPE_SPECIALIZATION(cast_expression)
GET_TYPE_SPECIALIZATION(cast_expression_first_part)
@@ -135,6 +137,7 @@ GET_TYPE_SPECIALIZATION(enumerator_list)
GET_TYPE_SPECIALIZATION(equal_initializer)
GET_TYPE_SPECIALIZATION(equality_expression)
GET_TYPE_SPECIALIZATION(equality_operator)
+GET_TYPE_SPECIALIZATION(escape_sequence)
GET_TYPE_SPECIALIZATION(exception_abstract_declarator)
GET_TYPE_SPECIALIZATION(exception_declaration)
GET_TYPE_SPECIALIZATION(exception_declarator)
@@ -241,13 +244,15 @@ GET_TYPE_SPECIALIZATION(shift_expression)
GET_TYPE_SPECIALIZATION(shift_operator)
GET_TYPE_SPECIALIZATION(simple_declaration)
GET_TYPE_SPECIALIZATION(simple_delete_expression)
+GET_TYPE_SPECIALIZATION(simple_escape_sequence)
GET_TYPE_SPECIALIZATION(simple_function_definition)
GET_TYPE_SPECIALIZATION(simple_operator)
GET_TYPE_SPECIALIZATION(simple_ptr_ptr_operator)
GET_TYPE_SPECIALIZATION(simple_template_id)
GET_TYPE_SPECIALIZATION(simple_template_type_specifier)
GET_TYPE_SPECIALIZATION(simple_type_specifier)
GET_TYPE_SPECIALIZATION(simple_type_specifier_postfix_expression)
+GET_TYPE_SPECIALIZATION(source_character_set)
GET_TYPE_SPECIALIZATION(square_bracketed_expression)
GET_TYPE_SPECIALIZATION(statement)
GET_TYPE_SPECIALIZATION(statement_seq)
@@ -37,14 +37,13 @@ create_expression(const syntax_nodes::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);
+ if(const boost::optional<const character_literal&>& opt_character_literal_node = get<character_literal>(&literal_node))
+ return create_character_value(*opt_character_literal_node);
+ if(const boost::optional<const string_literal&>& opt_string_literal_node = get<string_literal>(&literal_node))
+ assert(false); //TODO
+ //return create_string_value(*opt_string_literal_node);
assert(false);
-
- /*
- character_literal
- string_literal
- floating_literal
- */
}
}}}} //namespace scalpel::cpp::semantic_analysis::detail
@@ -66,52 +66,77 @@ namespace
return oss.str();
}
+ template<unsigned int Base>
+ unsigned int
+ convert_char_to_digit(const char c)
+ {
+ return c - '0';
+ }
+
+ template<>
+ unsigned int
+ convert_char_to_digit<16>(const char c)
+ {
+ if(c <= '9')
+ return c - '0';
+ else if(c <= 'F')
+ return c - 'A' + 10;
+ else
+ return c - 'a' + 10;
+ }
+
+ template<typename Integer, unsigned int Base>
+ Integer
+ convert_string_to_integer(const std::string& str)
+ {
+ Integer value = 0;
+
+ for(unsigned int i = 0; i < str.size(); ++i)
+ {
+ value *= Base;
+
+ const char current_digit_char = str[i];
+ const unsigned int current_digit = convert_char_to_digit<Base>(current_digit_char);
+
+ value += current_digit;
+ }
+
+ return value;
+ }
+
struct decimal_string_to_integer_converter
{
template<typename Integer>
+ inline
static
Integer
convert(const std::string& str)
{
- std::istringstream iss(str);
- Integer i;
- iss >> i;
- return i;
+ return convert_string_to_integer<Integer, 10>(str);
}
};
struct hexadecimal_string_to_integer_converter
{
template<typename Integer>
+ inline
static
Integer
convert(const std::string& str)
{
- std::istringstream iss(str);
- Integer i;
- iss >> std::hex >> i;
- return i;
+ return convert_string_to_integer<Integer, 16>(str);
}
};
struct octal_string_to_integer_converter
{
template<typename Integer>
+ inline
static
Integer
convert(const std::string& str)
{
- if(str.empty())
- {
- return 0;
- }
- else
- {
- std::istringstream iss(str);
- Integer i;
- iss >> std::oct >> i;
- return i;
- }
+ return convert_string_to_integer<Integer, 8>(str);
}
};
@@ -551,5 +576,108 @@ create_floating_value(const syntax_nodes::floating_literal& floating_literal_nod
return string_to_float<double>(floating_literal_node);
}
+
+
+namespace
+{
+ template<typename Char>
+ Char
+ convert_c_char_to_char(const c_char& c_char_node)
+ {
+ if(const boost::optional<const source_character_set&>& opt_source_character_set_node = get<source_character_set>(&c_char_node))
+ {
+ const source_character_set& source_character_set_node = *opt_source_character_set_node;
+ const std::string& str = source_character_set_node.value();
+ assert(str.size() == 1);
+ return str.front();
+ }
+ else if(const boost::optional<const escape_sequence&>& opt_escape_sequence_node = get<escape_sequence>(&c_char_node))
+ {
+ const escape_sequence& escape_sequence_node = *opt_escape_sequence_node;
+
+ if(const boost::optional<const simple_escape_sequence&>& opt_simple_escape_sequence_node = get<simple_escape_sequence>(&escape_sequence_node))
+ {
+ const simple_escape_sequence& simple_escape_sequence_node = *opt_simple_escape_sequence_node;
+ const std::string& str = simple_escape_sequence_node.value();
+
+ if(str == "\\'") return '\'';
+ if(str == "\\\"") return '"';
+ if(str == "\\?") return '?';
+ if(str == "\\\\") return '\\';
+ if(str == "\\a") return '\a';
+ if(str == "\\b") return '\b';
+ if(str == "\\f") return '\f';
+ if(str == "\\n") return '\n';
+ if(str == "\\r") return '\r';
+ if(str == "\\t") return '\t';
+ if(str == "\\v") return '\v';
+ }
+ else if(const boost::optional<const octal_escape_sequence&>& opt_octal_escape_sequence_node = get<octal_escape_sequence>(&escape_sequence_node))
+ {
+ const octal_escape_sequence& octal_escape_sequence_node = *opt_octal_escape_sequence_node;
+ const std::string& str = octal_escape_sequence_node.value();
+ return octal_string_to_integer_converter::convert<char>(str);
+ }
+ else if(const boost::optional<const hexadecimal_escape_sequence&>& opt_hexadecimal_escape_sequence_node = get<hexadecimal_escape_sequence>(&escape_sequence_node))
+ {
+ const hexadecimal_escape_sequence& hexadecimal_escape_sequence_node = *opt_hexadecimal_escape_sequence_node;
+ const std::string& str = hexadecimal_escape_sequence_node.value();
+ return hexadecimal_string_to_integer_converter::convert<char>(str);
+ }
+ }
+ else if(get<universal_character_name>(&c_char_node))
+ {
+ assert(false); //TODO
+ }
+
+ assert(false);
+ }
+
+ template<typename SingleChar, typename MultipleChar>
+ semantic_entities::expression_t
+ convert_c_char_sequence_to_char(const c_char_sequence& c_char_sequence_node)
+ {
+ if(c_char_sequence_node.size() == 1) //character literal containing a single c_char -> SingleChar
+ {
+ const c_char& c_char_node = c_char_sequence_node.front();
+ return convert_c_char_to_char<SingleChar>(c_char_node);
+ }
+ else //character literal containing multiple c_chars -> MultipleChar
+ {
+ MultipleChar value = 0;
+
+ //read the last N chars, where Nmax = sizeof(MultipleChar)
+ const unsigned int char_sequence_size = c_char_sequence_node.size();
+ const unsigned int max_char_count = sizeof(MultipleChar);
+ const unsigned int begin_index = (char_sequence_size > max_char_count) ? char_sequence_size - max_char_count : 0;
+ for(unsigned int i = begin_index; i < c_char_sequence_node.size(); ++i)
+ {
+ const c_char& c_char_node = c_char_sequence_node[i];
+ const SingleChar c = convert_c_char_to_char<SingleChar>(c_char_node);
+
+ value <<= 8;
+ value += c;
+ }
+
+ return value;
+ }
+ }
+}
+
+semantic_entities::expression_t
+create_character_value(const syntax_nodes::character_literal& character_literal_node)
+{
+ const c_char_sequence& c_char_sequence_node = get_char_sequence(character_literal_node);
+ if(has_leading_l(character_literal_node))
+ return convert_c_char_sequence_to_char<wchar_t, wchar_t>(c_char_sequence_node);
+ else
+ return convert_c_char_sequence_to_char<char, int>(c_char_sequence_node);
+}
+
+//semantic_entities::expression_t
+//create_string_value(const syntax_nodes::string_literal& string_literal_node)
+//{
+//}
+
}}}} //namespace scalpel::cpp::semantic_analysis::detail
@@ -36,6 +36,12 @@ 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);
+semantic_entities::expression_t
+create_character_value(const syntax_nodes::character_literal& character_literal_node);
+
+//semantic_entities::expression_t
+//create_string_value(const syntax_nodes::string_literal& string_literal_node);
+
}}}} //namespace scalpel::cpp::semantic_analysis::detail
#endif
@@ -29,8 +29,13 @@ namespace scalpel { namespace cpp { namespace semantic_entities
typedef
utility::variant
<
+ //boolean type
bool,
+ //char types
+ char,
+ wchar_t,
+
//integer types
int,
long int,
@@ -37,7 +37,7 @@ grammar::grammar()
;
source_character_set
- = no_node_d
+ = token_node_d
[
anychar_p
| '\t' //horizontal tab
@@ -219,7 +219,7 @@ grammar::grammar()
;
character_literal
- = token_node_d[!ch_p('L') >> '\'' >> c_char_sequence >> '\'']
+ = !ch_p('L') >> no_node_d[ch_p('\'')] >> c_char_sequence >> no_node_d[ch_p('\'')]
;
c_char_sequence
@@ -253,11 +253,11 @@ grammar::grammar()
;
octal_escape_sequence
- = '\\' >> octal_digit >> !octal_digit >> !octal_digit
+ = no_node_d[ch_p('\\')] >> token_node_d[octal_digit >> !octal_digit >> !octal_digit]
;
hexadecimal_escape_sequence
- = "\\x" >> +hexadecimal_digit
+ = no_node_d[str_p("\\x")] >> token_node_d[+hexadecimal_digit]
;
floating_literal
@@ -342,12 +342,12 @@ class grammar
*/
//
boost::spirit::rule<scanner_t> file;
- boost::spirit::rule<scanner_t> source_character_set;
+ boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::SOURCE_CHARACTER_SET>> source_character_set;
boost::spirit::rule<lexeme_scanner_t> keyword;
//1.2 - Lexical conventions [gram.lex]
boost::spirit::rule<lexeme_scanner_t> hex_quad;
- boost::spirit::rule<lexeme_scanner_t> universal_character_name;
+ boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::UNIVERSAL_CHARACTER_NAME>> universal_character_name;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::IDENTIFIER>> identifier;
boost::spirit::rule<lexeme_scanner_t> nondigit;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::LITERAL>> literal;
@@ -364,12 +364,12 @@ class grammar
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::LONG_SUFFIX>> long_suffix;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::LONG_LONG_SUFFIX>> long_long_suffix;
boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::CHARACTER_LITERAL>> character_literal;
- boost::spirit::rule<lexeme_scanner_t> c_char_sequence;
- boost::spirit::rule<lexeme_scanner_t> c_char;
- boost::spirit::rule<lexeme_scanner_t> escape_sequence;
- boost::spirit::rule<lexeme_scanner_t> simple_escape_sequence;
- 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::C_CHAR_SEQUENCE>> c_char_sequence;
+ boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::C_CHAR>> c_char;
+ boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::ESCAPE_SEQUENCE>> escape_sequence;
+ boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::SIMPLE_ESCAPE_SEQUENCE>> simple_escape_sequence;
+ boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::OCTAL_ESCAPE_SEQUENCE>> octal_escape_sequence;
+ boost::spirit::rule<lexeme_scanner_t, boost::spirit::parser_context<>, boost::spirit::parser_tag<grammar::HEXADECIMAL_ESCAPE_SEQUENCE>> 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, 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;
Oops, something went wrong.

0 comments on commit 1bfc0bf

Please sign in to comment.