Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ParseNode.cc

    rca35c51 re869d663  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:26:29 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 30 13:30:43 2016
    13 // Update Count     : 50
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Aug 12 13:26:00 2015
     13// Update Count     : 36
    1414//
    1515
    16 #include <climits>
    1716#include "ParseNode.h"
    1817using 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 
    17518
    17619// Builder
Note: See TracChangeset for help on using the changeset viewer.