Changeset ca35c51 for src/Parser/ParseNode.cc
- Timestamp:
- Jun 30, 2016, 1:47:52 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 1bc1bb2
- Parents:
- 84d4d6f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/ParseNode.cc
r84d4d6f rca35c51 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:26:29 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Aug 12 13:26:00 201513 // Update Count : 3611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 30 13:30:43 2016 13 // Update Count : 50 14 14 // 15 15 16 #include <climits> 16 17 #include "ParseNode.h" 17 18 using namespace std; 19 20 // Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns: 21 // 22 // prefix action constant action suffix 23 // 24 // Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty: 25 // 26 // constant BEGIN CONT ... 27 // <CONT>(...)? BEGIN 0 ... // possible empty suffix 28 // 29 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their 30 // type. 31 32 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 33 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 34 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; } 35 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; } 36 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; } 37 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 38 39 BasicType::Kind literalType( ConstantNode::Type type, string &value ) { 40 BasicType::Kind btype; 41 42 // lexing divides constants into 4 kinds 43 switch ( type ) { 44 case ConstantNode::Integer: 45 { 46 static const BasicType::Kind kind[2][3] = { 47 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt }, 48 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt }, 49 }; 50 bool dec = true, Unsigned = false; // decimal, unsigned constant 51 int size; // 0 => int, 1 => long, 2 => long long 52 unsigned long long v; // converted integral value 53 size_t last = value.length() - 1; // last character of constant 54 55 if ( value[0] == '0' ) { // octal constant ? 56 dec = false; 57 if ( last != 0 && checkX( value[1] ) ) { // hex constant ? 58 sscanf( (char *)value.c_str(), "%llx", &v ); 59 //printf( "%llx %llu\n", v, v ); 60 } else { 61 sscanf( (char *)value.c_str(), "%llo", &v ); 62 //printf( "%llo %llu\n", v, v ); 63 } // if 64 } else { // decimal constant ? 65 sscanf( (char *)value.c_str(), "%llu", &v ); 66 //printf( "%llu %llu\n", v, v ); 67 } // if 68 69 if ( v <= INT_MAX ) { // signed int 70 size = 0; 71 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 72 size = 0; 73 Unsigned = true; // unsigned 74 } else if ( v <= LONG_MAX ) { // signed long int 75 size = 1; 76 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 77 size = 1; 78 Unsigned = true; // unsigned long int 79 } else if ( v <= LLONG_MAX ) { // signed long long int 80 size = 2; 81 } else { // unsigned long long int 82 size = 2; 83 Unsigned = true; // unsigned long long int 84 } // if 85 86 if ( checkU( value[last] ) ) { // suffix 'u' ? 87 Unsigned = true; 88 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ? 89 size = 1; 90 if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ? 91 size = 2; 92 } // if 93 } // if 94 } else if ( checkL( value[ last ] ) ) { // suffix 'l' ? 95 size = 1; 96 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ? 97 size = 2; 98 if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ? 99 Unsigned = true; 100 } // if 101 } else { 102 if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ? 103 Unsigned = true; 104 } // if 105 } // if 106 } // if 107 btype = kind[Unsigned][size]; // lookup constant type 108 break; 109 } 110 case ConstantNode::Float: 111 { 112 static const BasicType::Kind kind[2][3] = { 113 { BasicType::Float, BasicType::Double, BasicType::LongDouble }, 114 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 115 }; 116 bool complx = false; // real, complex 117 int size = 1; // 0 => float, 1 => double (default), 2 => long double 118 // floating-point constant has minimum of 2 characters: 1. or .1 119 size_t last = value.length() - 1; 120 121 if ( checkI( value[last] ) ) { // imaginary ? 122 complx = true; 123 last -= 1; // backup one character 124 } // if 125 if ( checkF( value[last] ) ) { // float ? 126 size = 0; 127 } else if ( checkD( value[last] ) ) { // double ? 128 size = 1; 129 } else if ( checkL( value[last] ) ) { // long double ? 130 size = 2; 131 } // if 132 if ( ! complx && checkI( value[last - 1] ) ) { // imaginary ? 133 complx = true; 134 } // if 135 btype = kind[complx][size]; // lookup constant type 136 break; 137 } 138 case ConstantNode::Character: 139 btype = BasicType::Char; // default 140 if ( string( "LUu" ).find( value[0] ) != string::npos ) { 141 // ??? 142 } // if 143 break; 144 case ConstantNode::String: 145 assert( false ); 146 // array of char 147 if ( string( "LUu" ).find( value[0] ) != string::npos ) { 148 if ( value[0] == 'u' && value[1] == '8' ) { 149 // ??? 150 } else { 151 // ??? 152 } // if 153 } // if 154 break; 155 } // switch 156 return btype; 157 } // literalType 158 159 ConstantNode *makeConstant( ConstantNode::Type type, std::string *str ) { 160 ::Type::Qualifiers emptyQualifiers; // no qualifiers on constants 161 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, literalType( type, *str ) ), *str ), nullptr ) ); 162 } 163 164 ConstantNode *makeConstantStr( ConstantNode::Type type, std::string *str ) { 165 ::Type::Qualifiers emptyQualifiers; // no qualifiers on constants 166 // string should probably be a primitive type 167 ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ), 168 new ConstantExpr( 169 Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ), 170 toString( str->size()+1-2 ) ) ), // +1 for '\0' and -2 for '"' 171 false, false ); 172 return new ConstantNode( new ConstantExpr( Constant( at, *str ), nullptr ) ); 173 } 174 18 175 19 176 // Builder
Note: See TracChangeset
for help on using the changeset viewer.