Changes in src/Parser/ParseNode.cc [d1625f8:4e05d27]
- File:
-
- 1 edited
-
src/Parser/ParseNode.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/ParseNode.cc
rd1625f8 r4e05d27 10 10 // Created On : Sat May 16 13:26:29 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Aug 7 23:32:47201613 // Update Count : 9 412 // Last Modified On : Sun Jul 24 02:17:01 2016 13 // Update Count : 90 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 Type::Qualifiers emptyQualifiers; // no qualifiers on constants 33 34 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 35 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 36 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; } 37 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; } 38 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; } 39 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 40 41 ConstantNode *makeConstantInteger( std::string & str ) { 42 static const BasicType::Kind kind[2][3] = { 43 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt }, 44 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt }, 45 }; 46 bool dec = true, Unsigned = false; // decimal, unsigned constant 47 int size; // 0 => int, 1 => long, 2 => long long 48 unsigned long long v; // converted integral value 49 size_t last = str.length() - 1; // last character of constant 50 51 if ( str[0] == '0' ) { // octal/hex constant ? 52 dec = false; 53 if ( last != 0 && checkX( str[1] ) ) { // hex constant ? 54 sscanf( (char *)str.c_str(), "%llx", &v ); 55 //printf( "%llx %llu\n", v, v ); 56 } else { // octal constant 57 sscanf( (char *)str.c_str(), "%llo", &v ); 58 //printf( "%llo %llu\n", v, v ); 59 } // if 60 } else { // decimal constant ? 61 sscanf( (char *)str.c_str(), "%llu", &v ); 62 //printf( "%llu %llu\n", v, v ); 63 } // if 64 65 if ( v <= INT_MAX ) { // signed int 66 size = 0; 67 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 68 size = 0; 69 Unsigned = true; // unsigned 70 } else if ( v <= LONG_MAX ) { // signed long int 71 size = 1; 72 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 73 size = 1; 74 Unsigned = true; // unsigned long int 75 } else if ( v <= LLONG_MAX ) { // signed long long int 76 size = 2; 77 } else { // unsigned long long int 78 size = 2; 79 Unsigned = true; // unsigned long long int 80 } // if 81 82 if ( checkU( str[last] ) ) { // suffix 'u' ? 83 Unsigned = true; 84 if ( last > 0 && checkL( str[last - 1] ) ) { // suffix 'l' ? 85 size = 1; 86 if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ? 87 size = 2; 88 } // if 89 } // if 90 } else if ( checkL( str[ last ] ) ) { // suffix 'l' ? 91 size = 1; 92 if ( last > 0 && checkL( str[last - 1] ) ) { // suffix 'll' ? 93 size = 2; 94 if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ? 95 Unsigned = true; 96 } // if 97 } else { 98 if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ? 99 Unsigned = true; 100 } // if 101 } // if 102 } // if 103 104 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str ), nullptr ) ); 105 } // makeConstantInteger 106 107 ConstantNode *makeConstantFloat( std::string & str ) { 108 static const BasicType::Kind kind[2][3] = { 109 { BasicType::Float, BasicType::Double, BasicType::LongDouble }, 110 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 111 }; 112 113 bool complx = false; // real, complex 114 int size = 1; // 0 => float, 1 => double (default), 2 => long double 115 // floating-point constant has minimum of 2 characters: 1. or .1 116 size_t last = str.length() - 1; 117 118 if ( checkI( str[last] ) ) { // imaginary ? 119 complx = true; 120 last -= 1; // backup one character 121 } // if 122 123 if ( checkF( str[last] ) ) { // float ? 124 size = 0; 125 } else if ( checkD( str[last] ) ) { // double ? 126 size = 1; 127 } else if ( checkL( str[last] ) ) { // long double ? 128 size = 2; 129 } // if 130 if ( ! complx && checkI( str[last - 1] ) ) { // imaginary ? 131 complx = true; 132 } // if 133 134 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str ), nullptr ) ); 135 } // makeConstantFloat 136 137 ConstantNode *makeConstantChar( std::string & str ) { 138 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ), nullptr ) ); 139 } // makeConstantChar 140 141 ConstantNode *makeConstantStr( std::string & str ) { 142 // string should probably be a primitive type 143 ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ), 144 new ConstantExpr( 145 Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ), 146 toString( str.size()+1-2 ) ) ), // +1 for '\0' and -2 for '"' 147 false, false ); 148 return new ConstantNode( new ConstantExpr( Constant( at, str ), nullptr ) ); 149 } // makeConstantStr 150 18 151 19 152 // Builder
Note:
See TracChangeset
for help on using the changeset viewer.