Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ParseNode.cc

    rd1625f8 r4e05d27  
    1010// Created On       : Sat May 16 13:26:29 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug  7 23:32:47 2016
    13 // Update Count     : 94
     12// Last Modified On : Sun Jul 24 02:17:01 2016
     13// Update Count     : 90
    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 Type::Qualifiers emptyQualifiers;                                // no qualifiers on constants
     33
     34static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
     35static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
     36static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
     37static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     38static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
     39static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
     40
     41ConstantNode *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
     107ConstantNode *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
     137ConstantNode *makeConstantChar( std::string & str ) {
     138        return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ), nullptr ) );
     139} // makeConstantChar
     140
     141ConstantNode *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
    18151
    19152// Builder
Note: See TracChangeset for help on using the changeset viewer.