Changes in src/Parser/ExpressionNode.cc [0caaa6a:ca35c51]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/ExpressionNode.cc
r0caaa6a rca35c51 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jun 13 14:46:17201613 // Update Count : 3 0712 // Last Modified On : Thu Jun 30 13:33:16 2016 13 // Update Count : 319 14 14 // 15 15 … … 19 19 #include <sstream> 20 20 #include <cstdio> 21 #include <climits>22 21 23 22 #include "ParseNode.h" … … 90 89 //############################################################################## 91 90 92 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 93 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 94 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; } 95 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; } 96 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; } 97 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 98 99 // Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns: 100 // 101 // prefix action constant action suffix 102 // 103 // Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty: 104 // 105 // constant BEGIN CONT ... 106 // <CONT>(...)? BEGIN 0 ... // possible empty suffix 107 // 108 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their 109 // type. 110 111 ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) { 112 // lexing divides constants into 4 kinds 113 switch ( type ) { 114 case Integer: 115 { 116 static const BasicType::Kind kind[2][3] = { 117 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt }, 118 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt }, 119 }; 120 bool dec = true, Unsigned = false; // decimal, unsigned constant 121 int size; // 0 => int, 1 => long, 2 => long long 122 unsigned long long v; // converted integral value 123 size_t last = value.length() - 1; // last character of constant 124 125 if ( value[0] == '0' ) { // octal constant ? 126 dec = false; 127 if ( last != 0 && checkX( value[1] ) ) { // hex constant ? 128 sscanf( (char *)value.c_str(), "%llx", &v ); 129 //printf( "%llx %llu\n", v, v ); 130 } else { 131 sscanf( (char *)value.c_str(), "%llo", &v ); 132 //printf( "%llo %llu\n", v, v ); 133 } // if 134 } else { // decimal constant ? 135 sscanf( (char *)value.c_str(), "%llu", &v ); 136 //printf( "%llu %llu\n", v, v ); 137 } // if 138 139 if ( v <= INT_MAX ) { // signed int 140 size = 0; 141 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 142 size = 0; 143 Unsigned = true; // unsigned 144 } else if ( v <= LONG_MAX ) { // signed long int 145 size = 1; 146 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 147 size = 1; 148 Unsigned = true; // unsigned long int 149 } else if ( v <= LLONG_MAX ) { // signed long long int 150 size = 2; 151 } else { // unsigned long long int 152 size = 2; 153 Unsigned = true; // unsigned long long int 154 } // if 155 156 if ( checkU( value[last] ) ) { // suffix 'u' ? 157 Unsigned = true; 158 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ? 159 size = 1; 160 if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ? 161 size = 2; 162 } // if 163 } // if 164 } else if ( checkL( value[ last ] ) ) { // suffix 'l' ? 165 size = 1; 166 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ? 167 size = 2; 168 if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ? 169 Unsigned = true; 170 } // if 171 } else { 172 if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ? 173 Unsigned = true; 174 } // if 175 } // if 176 } // if 177 btype = kind[Unsigned][size]; // lookup constant type 178 break; 179 } 180 case Float: 181 { 182 static const BasicType::Kind kind[2][3] = { 183 { BasicType::Float, BasicType::Double, BasicType::LongDouble }, 184 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 185 }; 186 bool complx = false; // real, complex 187 int size = 1; // 0 => float, 1 => double (default), 2 => long double 188 // floating-point constant has minimum of 2 characters: 1. or .1 189 size_t last = value.length() - 1; 190 191 if ( checkI( value[last] ) ) { // imaginary ? 192 complx = true; 193 last -= 1; // backup one character 194 } // if 195 if ( checkF( value[last] ) ) { // float ? 196 size = 0; 197 } else if ( checkD( value[last] ) ) { // double ? 198 size = 1; 199 } else if ( checkL( value[last] ) ) { // long double ? 200 size = 2; 201 } // if 202 if ( ! complx && checkI( value[last - 1] ) ) { // imaginary ? 203 complx = true; 204 } // if 205 btype = kind[complx][size]; // lookup constant type 206 break; 207 } 208 case Character: 209 btype = BasicType::Char; // default 210 if ( string( "LUu" ).find( value[0] ) != string::npos ) { 211 // ??? 212 } // if 213 break; 214 case String: 215 // array of char 216 if ( string( "LUu" ).find( value[0] ) != string::npos ) { 217 if ( value[0] == 'u' && value[1] == '8' ) { 218 // ??? 219 } else { 220 // ??? 221 } // if 222 } // if 223 break; 224 } // switch 91 ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) { 225 92 } // ConstantNode::ConstantNode 226 93 227 94 ConstantNode *ConstantNode::appendstr( const std::string *newValue ) { 228 95 assert( newValue != 0 ); 229 assert( type == String);96 string value = expr->get_constant()->get_value(); 230 97 231 98 // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string. … … 237 104 238 105 void ConstantNode::printOneLine( std::ostream &os, int indent ) const { 239 os << string( indent, ' ' );240 printDesignation( os );241 242 switch ( type ) {243 case Integer:244 case Float:245 os << value ;246 break;247 case Character:248 os << "'" << value << "'";249 break;250 case String:251 os << '"' << value << '"';252 break;253 } // switch254 255 os << ' ';106 // os << string( indent, ' ' ); 107 // printDesignation( os ); 108 109 // switch ( type ) { 110 // case Integer: 111 // case Float: 112 // os << value ; 113 // break; 114 // case Character: 115 // os << "'" << value << "'"; 116 // break; 117 // case String: 118 // os << '"' << value << '"'; 119 // break; 120 // } // switch 121 122 // os << ' '; 256 123 } 257 124 … … 262 129 263 130 Expression *ConstantNode::build() const { 264 ::Type::Qualifiers q; // no qualifiers on constants 265 266 switch ( get_type() ) { 267 case String: 268 { 269 // string should probably be a primitive type 270 ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ), 271 new ConstantExpr( 272 Constant( new BasicType( q, BasicType::UnsignedInt ), 273 toString( value.size()+1-2 ) ) ), // +1 for '\0' and -2 for '"' 274 false, false ); 275 return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) ); 276 } 277 default: 278 return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) ); 279 } 131 return expr->clone(); 280 132 } 281 133
Note: See TracChangeset
for help on using the changeset viewer.