Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ParseNode.cc

    re869d663 rca35c51  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:26:29 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Aug 12 13:26:00 2015
    13 // Update Count     : 36
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jun 30 13:30:43 2016
     13// Update Count     : 50
    1414//
    1515
     16#include <climits>
    1617#include "ParseNode.h"
    1718using 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
     32static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
     33static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
     34static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
     35static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     36static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
     37static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
     38
     39BasicType::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
     159ConstantNode *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
     164ConstantNode *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
    18175
    19176// Builder
Note: See TracChangeset for help on using the changeset viewer.