Ignore:
Timestamp:
Aug 16, 2016, 3:20:06 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
1f6d4624
Parents:
950f7a7 (diff), 7880579 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ParseNode.cc

    r950f7a7 r7527e63  
    1010// Created On       : Sat May 16 13:26:29 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 15 18:49:25 2016
    13 // Update Count     : 62
     12// Last Modified On : Tue Aug 16 08:42:29 2016
     13// Update Count     : 107
    1414//
    1515
    16 #include <climits>
    1716#include "ParseNode.h"
    1817using namespace std;
    1918
    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/hex 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 {                                                                // octal constant
    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                         //long double v;
    113                         static const BasicType::Kind kind[2][3] = {
    114                                 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
    115                                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
    116                         };
    117                         bool complx = false;                                            // real, complex
    118                         int size = 1;                                                           // 0 => float, 1 => double (default), 2 => long double
    119                         // floating-point constant has minimum of 2 characters: 1. or .1
    120                         size_t last = value.length() - 1;
    121 
    122                         if ( checkI( value[last] ) ) {                          // imaginary ?
    123                                 complx = true;
    124                                 last -= 1;                                                              // backup one character
    125                         } // if
    126 
    127                         //sscanf( (char *)value.c_str(), "%Lf", &v );
    128                         //printf( "%s %24.22Lf %Lf\n", value.c_str(), v, v );
    129 
    130                         if ( checkF( value[last] ) ) {                          // float ?
    131                                 size = 0;
    132                         } else if ( checkD( value[last] ) ) {           // double ?
    133                                 size = 1;
    134                         } else if ( checkL( value[last] ) ) {           // long double ?
    135                                 size = 2;
    136                         } // if
    137                         if ( ! complx && checkI( value[last - 1] ) ) { // imaginary ?
    138                                 complx = true;
    139                         } // if
    140                         btype = kind[complx][size];                                     // lookup constant type
    141                         break;
    142                 }
    143           case ConstantNode::Character:
    144                 btype = BasicType::Char;                                                // default
    145                 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
    146                         // ???
    147                 } // if
    148                 break;
    149           case ConstantNode::String:
    150                 assert( false );
    151                 // array of char
    152                 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
    153                         if ( value[0] == 'u' && value[1] == '8' ) {
    154                                 // ???
    155                         } else {
    156                                 // ???
    157                         } // if
    158                 } // if
    159                 break;
    160         } // switch
    161         return btype;
    162 } // literalType
    163 
    164 
    165 ConstantNode *makeConstant( ConstantNode::Type type, std::string *str ) {
    166         ::Type::Qualifiers emptyQualifiers;                                     // no qualifiers on constants
    167         return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, literalType( type, *str ) ), *str ), nullptr ) );
    168 }
    169 
    170 ConstantNode *makeConstantStr( ConstantNode::Type type, std::string *str ) {
    171         ::Type::Qualifiers emptyQualifiers;                                     // no qualifiers on constants
    172         // string should probably be a primitive type
    173         ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ),
    174                                                                    new ConstantExpr(
    175                                                                            Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ),
    176                                                                                                  toString( str->size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
    177                                                                    false, false );
    178         return new ConstantNode( new ConstantExpr( Constant( at, *str ), nullptr ) );
    179 }
    180 
    181 
    182 // Builder
    18319int ParseNode::indent_by = 4;
    18420
    185 ParseNode::ParseNode() : next( 0 ) {};
    186 ParseNode::ParseNode( const string *name ) : name( *name ), next( 0 ) { delete name; }
    187 ParseNode::ParseNode( const string &name ) : name( name ), next( 0 ) { }
     21ParseNode::ParseNode() : next( nullptr ) {};
     22ParseNode::ParseNode( const string *name ) : name( *name ), next( nullptr ) { delete name; }
     23ParseNode::ParseNode( const string &name ) : name( name ), next( nullptr ) { }
    18824
    18925ParseNode::~ParseNode() {
     
    19430        ParseNode *current = this;
    19531
    196         while ( current->get_link() != 0 )
    197         current = current->get_link();
    198 
     32        while ( current->get_next() != 0 )
     33        current = current->get_next();
    19934        return current;
    20035}
    20136
    202 ParseNode *ParseNode::set_link( ParseNode *next_ ) {
     37ParseNode *ParseNode::set_last( ParseNode *next_ ) {
    20338        if ( next_ != 0 ) get_last()->next = next_;
    20439        return this;
    20540}
    206 
    207 void ParseNode::print( std::ostream &os, int indent ) const {}
    208 
    20941
    21042void ParseNode::printList( std::ostream &os, int indent ) const {
     
    21648}
    21749
    218 ParseNode &ParseNode::operator,( ParseNode &p ) {
    219         set_link( &p );
    220 
    221         return *this;
    222 }
    223 
    224 ParseNode *mkList( ParseNode &pn ) {
    225         // it just relies on `operator,' to take care of the "arguments" and provides a nice interface to an awful-looking
    226         // address-of, rendering, for example (StatementNode *)(&(*$5 + *$7)) into (StatementNode *)mkList(($5, $7))
    227         // (although "nice" is probably not the word)
    228         return &pn;
    229 }
    230 
    23150// Local Variables: //
    23251// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.