Changeset b3c7963 for src/Parser


Ignore:
Timestamp:
Sep 12, 2017, 5:55:31 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
4639b0d
Parents:
a506df4 (diff), a46478a (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:/u/cforall/software/cfa/cfa-cc

Location:
src/Parser
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    ra506df4 rb3c7963  
    77// ExpressionNode.cc --
    88//
    9 // Author           : Rodolfo G. Esteves
     9// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Sep  1 15:07:09 2017
    13 // Update Count     : 618
     12// Last Modified On : Tue Sep 12 10:00:29 2017
     13// Update Count     : 672
    1414//
    1515
     
    4949// type.
    5050
    51 extern const Type::Qualifiers noQualifiers;             // no qualifiers on constants
    52 
     51extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
     52
     53static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
     54static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
     55static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
    5356static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
    54 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
    5557static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
    5658static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     
    6668} // sepNumeric
    6769
    68 Expression * build_constantInteger( std::string & str ) {
    69         static const BasicType::Kind kind[2][3] = {
    70                 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
    71                 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
     70Expression * build_constantInteger( string & str ) {
     71        static const BasicType::Kind kind[2][5] = {
     72                // short (h) must be before char (hh)
     73                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
     74                { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
    7275        };
    7376
     
    7679
    7780        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    78         int size;                                                                                       // 0 => int, 1 => long, 2 => long long
     81        int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => size_t
    7982        unsigned long long int v;                                                       // converted integral value
    8083        size_t last = str.length() - 1;                                         // last character of constant
    8184        Expression * ret;
    8285
    83         // ROB: what do we do with units on 0 and 1?
    8486        // special constants
    8587        if ( str == "0" ) {
     
    107109
    108110        if ( v <= INT_MAX ) {                                                           // signed int
    109                 size = 0;
     111                size = 2;
    110112        } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
    111                 size = 0;
     113                size = 2;
    112114                Unsigned = true;                                                                // unsigned
    113115        } else if ( v <= LONG_MAX ) {                                           // signed long int
    114                 size = 1;
     116                size = 3;
    115117        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
    116                 size = 1;
     118                size = 3;
    117119                Unsigned = true;                                                                // unsigned long int
    118120        } else if ( v <= LLONG_MAX ) {                                          // signed long long int
    119                 size = 2;
     121                size = 4;
    120122        } else {                                                                                        // unsigned long long int
    121                 size = 2;
     123                size = 4;
    122124                Unsigned = true;                                                                // unsigned long long int
    123125        } // if
     126
     127        // At least one digit in integer constant, so safe to backup while looking for suffix.
    124128
    125129        if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
    126130                Unsigned = true;
    127                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'l' ?
    128                         size = 1;
    129                         if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ?
    130                                 size = 2;
     131                if ( checkL( str[last - 1] ) ) {                                // suffix 'l' ?
     132                        size = 3;
     133                        if ( checkL( str[last - 2] ) ) {                        // suffix "ll" ?
     134                                size = 4;
    131135                        } // if
     136                } else if ( checkH( str[last - 1] ) ) {                 // suffix 'h' ?
     137                        size = 0;
     138                        if ( checkH( str[last - 2] ) ) {                        // suffix "hh" ?
     139                                size = 1;
     140                        } // if
     141                        str.erase( last - size - 1, size + 1 );         // remove 'h'/"hh"
    132142                } // if
    133143        } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
    134                 size = 1;
    135                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'll' ?
    136                         size = 2;
    137                         if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ?
     144                size = 3;
     145                if ( checkL( str[last - 1] ) ) {                                // suffix 'll' ?
     146                        size = 4;
     147                        if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
    138148                                Unsigned = true;
    139149                        } // if
    140                 } else {
    141                         if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
     150                } else if ( checkU( str[last - 1] ) ) {                 // suffix 'u' ?
     151                        Unsigned = true;
     152                } // if
     153        } else if ( checkH( str[ last ] ) ) {                           // suffix 'h' ?
     154                size = 0;
     155                if ( checkH( str[last - 1] ) ) {                                // suffix "hh" ?
     156                        size = 1;
     157                        if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
    142158                                Unsigned = true;
    143159                        } // if
    144                 } // if
     160                } else if ( checkU( str[last - 1] ) ) {                 // suffix 'u' ?
     161                        Unsigned = true;
     162                } // if
     163                str.erase( last - size, size + 1 );                             // remove 'h'/"hh"
     164        } else if ( checkZ( str[last] ) ) {                                     // suffix 'z' ?
     165                size = 5;
     166                str.erase( last, 1 );                                                   // remove 'z'
    145167        } // if
    146168
    147169        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
     170        if ( Unsigned && size < 2 ) {                                           // less than int ?
     171                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which eliminates warnings for large values.
     172                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
     173        } else if ( size == 5 ) {                                                       // explicit cast to size_t
     174                ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), "size_t", false ) );
     175        } // if
    148176  CLEANUP:
    149177        if ( units.length() != 0 ) {
    150                 ret = new UntypedExpr( new NameExpr( units, ret ) );
     178                ret = new UntypedExpr( new NameExpr( units ), { ret } );
    151179        } // if
    152180
     
    155183} // build_constantInteger
    156184
    157 Expression * build_constantFloat( std::string & str ) {
     185Expression * build_constantFloat( string & str ) {
    158186        static const BasicType::Kind kind[2][3] = {
    159187                { BasicType::Float, BasicType::Double, BasicType::LongDouble },
     
    190218        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) );
    191219        if ( units.length() != 0 ) {
    192                 ret = new UntypedExpr( new NameExpr( units, ret ) );
     220                ret = new UntypedExpr( new NameExpr( units ), { ret } );
    193221        } // if
    194222
     
    205233} // sepString
    206234
    207 Expression * build_constantChar( std::string & str ) {
     235Expression * build_constantChar( string & str ) {
    208236        string units;                                                                           // units
    209237        sepString( str, units, '\'' );                                          // separate constant from units
     
    211239        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
    212240        if ( units.length() != 0 ) {
    213                 ret = new UntypedExpr( new NameExpr( units, ret ) );
     241                ret = new UntypedExpr( new NameExpr( units ), { ret } );
    214242        } // if
    215243
     
    218246} // build_constantChar
    219247
    220 ConstantExpr * build_constantStr( std::string & str ) {
     248Expression * build_constantStr( string & str ) {
    221249        string units;                                                                           // units
    222250        sepString( str, units, '"' );                                           // separate constant from units
    223251
    224         ArrayType * at = new ArrayType( noQualifiers, new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ),
     252        BasicType::Kind strtype = BasicType::Char;                      // default string type
     253        switch ( str[0] ) {                                                                     // str has >= 2 characters, i.e, null string ""
     254          case 'u':
     255                if ( str[1] == '8' ) break;                                             // utf-8 characters
     256                strtype = BasicType::ShortUnsignedInt;
     257                break;
     258          case 'U':
     259                strtype = BasicType::UnsignedInt;
     260                break;
     261          case 'L':
     262                strtype = BasicType::SignedInt;
     263                break;
     264        } // switch
     265        ArrayType * at = new ArrayType( noQualifiers, new BasicType( Type::Qualifiers( Type::Const ), strtype ),
    225266                                                                        new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
    226267                                                                        false, false );
    227         ConstantExpr * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
    228 // ROB: type mismatch
    229         // if ( units.length() != 0 ) {
    230         //      ret = new UntypedExpr( new NameExpr( units, ret ) );
    231         // } // if
     268        Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
     269        if ( units.length() != 0 ) {
     270                ret = new UntypedExpr( new NameExpr( units ), { ret } );
     271        } // if
    232272
    233273        delete &str;                                                                            // created by lex
     
    235275} // build_constantStr
    236276
    237 Expression * build_field_name_FLOATINGconstant( const std::string & str ) {
     277Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
     278        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
     279        Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
     280        delete &str;
     281        return ret;
     282} // build_field_name_FLOATING_FRACTIONconstant
     283
     284Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
     285        if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
     286        Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
     287        delete &str;
     288        return ret;
     289} // build_field_name_FLOATING_DECIMALconstant
     290
     291Expression * build_field_name_FLOATINGconstant( const string & str ) {
    238292        // str is of the form A.B -> separate at the . and return member expression
    239293        int a, b;
    240294        char dot;
    241         std::stringstream ss( str );
     295        stringstream ss( str );
    242296        ss >> a >> dot >> b;
    243297        UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
     
    253307                } else {
    254308                        return new UntypedMemberExpr( fracts, fieldName );
    255                 }
    256         }
     309                } // if
     310        } // if
    257311        return fieldName;
    258312} // make_field_name_fraction_constants
     
    261315        return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
    262316} // build_field_name_fraction_constants
    263 
    264 Expression * build_field_name_REALFRACTIONconstant( const std::string & str ) {
    265         if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
    266         Expression * ret = build_constantInteger( *new std::string( str.substr(1) ) );
    267         delete &str;
    268         return ret;
    269 } // build_field_name_REALFRACTIONconstant
    270 
    271 Expression * build_field_name_REALDECIMALconstant( const std::string & str ) {
    272         if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
    273         Expression * ret = build_constantInteger( *new std::string( str.substr( 0, str.size()-1 ) ) );
    274         delete &str;
    275         return ret;
    276 } // build_field_name_REALDECIMALconstant
    277317
    278318NameExpr * build_varref( const string * name ) {
     
    353393
    354394Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) {
    355         std::list< Expression * > args;
     395        list< Expression * > args;
    356396        args.push_back( maybeMoveBuild< Expression >(expr_node) );
    357397        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     
    359399
    360400Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) {
    361         std::list< Expression * > args;
     401        list< Expression * > args;
    362402        args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
    363403        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     
    365405
    366406Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    367         std::list< Expression * > args;
     407        list< Expression * > args;
    368408        args.push_back( maybeMoveBuild< Expression >(expr_node1) );
    369409        args.push_back( maybeMoveBuild< Expression >(expr_node2) );
     
    372412
    373413Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    374         std::list< Expression * > args;
     414        list< Expression * > args;
    375415        args.push_back( maybeMoveBuild< Expression >(expr_node1) );
    376416        args.push_back( maybeMoveBuild< Expression >(expr_node2) );
     
    395435
    396436Expression * build_tuple( ExpressionNode * expr_node ) {
    397         std::list< Expression * > exprs;
     437        list< Expression * > exprs;
    398438        buildMoveList( expr_node, exprs );
    399439        return new UntypedTupleExpr( exprs );;
     
    401441
    402442Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
    403         std::list< Expression * > args;
     443        list< Expression * > args;
    404444        buildMoveList( expr_node, args );
    405445        return new UntypedExpr( maybeMoveBuild< Expression >(function), args, nullptr );
     
    410450} // build_range
    411451
    412 Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand ) {
     452Expression * build_asmexpr( ExpressionNode * inout, Expression * constraint, ExpressionNode * operand ) {
    413453        return new AsmExpr( maybeMoveBuild< Expression >( inout ), constraint, maybeMoveBuild< Expression >(operand) );
    414454} // build_asmexpr
  • src/Parser/ParseNode.h

    ra506df4 rb3c7963  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 31 17:42:49 2017
    13 // Update Count     : 797
     12// Last Modified On : Sun Sep 10 09:56:32 2017
     13// Update Count     : 801
    1414//
    1515
     
    165165Expression * build_constantFloat( std::string &str );
    166166Expression * build_constantChar( std::string &str );
    167 ConstantExpr * build_constantStr( std::string &str );
     167Expression * build_constantStr( std::string &str );
     168Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
     169Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
    168170Expression * build_field_name_FLOATINGconstant( const std::string & str );
    169171Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
    170 Expression * build_field_name_REALFRACTIONconstant( const std::string & str );
    171 Expression * build_field_name_REALDECIMALconstant( const std::string & str );
    172172
    173173NameExpr * build_varref( const std::string * name );
     
    197197Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
    198198Expression * build_range( ExpressionNode * low, ExpressionNode * high );
    199 Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand );
     199Expression * build_asmexpr( ExpressionNode * inout, Expression * constraint, ExpressionNode * operand );
    200200Expression * build_valexpr( StatementNode * s );
    201201Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
     
    330330        bool hasEllipsis;
    331331        LinkageSpec::Spec linkage;
    332         ConstantExpr *asmName;
     332        Expression *asmName;
    333333        std::list< Attribute * > attributes;
    334334        InitializerNode * initializer;
     
    413413Statement * build_finally( StatementNode * stmt );
    414414Statement * build_compound( StatementNode * first );
    415 Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
     415Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
    416416WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
    417417WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
  • src/Parser/StatementNode.cc

    ra506df4 rb3c7963  
    1010// Created On       : Sat May 16 14:59:41 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 17 16:01:31 2017
    13 // Update Count     : 345
     12// Last Modified On : Fri Sep  1 23:25:23 2017
     13// Update Count     : 346
    1414//
    1515
     
    300300}
    301301
    302 Statement *build_asmstmt( bool voltile, ConstantExpr *instruction, ExpressionNode *output, ExpressionNode *input, ExpressionNode *clobber, LabelNode *gotolabels ) {
     302Statement *build_asmstmt( bool voltile, Expression *instruction, ExpressionNode *output, ExpressionNode *input, ExpressionNode *clobber, LabelNode *gotolabels ) {
    303303        std::list< Expression * > out, in;
    304304        std::list< ConstantExpr * > clob;
  • src/Parser/TypeData.cc

    ra506df4 rb3c7963  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:12:51 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Aug 14 10:41:00 2017
    13 // Update Count     : 568
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Sep  1 23:13:38 2017
     13// Update Count     : 569
    1414//
    1515
     
    814814} // buildTypeof
    815815
    816 Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, ConstantExpr *asmName, Initializer * init, std::list< Attribute * > attributes ) {
     816Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) {
    817817        if ( td->kind == TypeData::Function ) {
    818818                if ( td->function.idList ) {                                    // KR function ?
  • src/Parser/TypeData.h

    ra506df4 rb3c7963  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:18:36 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Aug 14 10:38:00 2017
    13 // Update Count     : 189
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Sep  1 23:33:45 2017
     13// Update Count     : 190
    1414//
    1515
     
    118118TupleType * buildTuple( const TypeData * );
    119119TypeofType * buildTypeof( const TypeData * );
    120 Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, ConstantExpr *asmName, Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
     120Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName, Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
    121121FunctionType * buildFunction( const TypeData * );
    122122void buildKRFunction( const TypeData::Function_t & function );
  • src/Parser/lex.ll

    ra506df4 rb3c7963  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Aug 31 21:30:10 2017
    13  * Update Count     : 598
     12 * Last Modified On : Sun Sep 10 22:29:15 2017
     13 * Update Count     : 620
    1414 */
    1515
     
    9393                                // numeric constants, CFA: '_' in constant
    9494hex_quad {hex}("_"?{hex}){3}
    95 integer_suffix_opt ("_"?(([uU](("ll"|"LL"|[lL])[iI]|[iI]?("ll"|"LL"|[lL])?))|([iI](("ll"|"LL"|[lL])[uU]|[uU]?("ll"|"LL"|[lL])?))|(("ll"|"LL"|[lL])([iI][uU]|[uU]?[iI]?))))?
     95length ("ll"|"LL"|[lL])|("hh"|"HH"|[hH])
     96integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))?{user_suffix_opt}
    9697
    9798octal_digits ({octal})|({octal}({octal}|"_")*{octal})
    9899octal_prefix "0""_"?
    99 octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix_opt}{user_suffix_opt}
     100octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix_opt}
    100101
    101102nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
    102 decimal_constant {nonzero_digits}{integer_suffix_opt}{user_suffix_opt}
     103decimal_constant {nonzero_digits}{integer_suffix_opt}
    103104
    104105hex_digits ({hex})|({hex}({hex}|"_")*{hex})
    105106hex_prefix "0"[xX]"_"?
    106 hex_constant {hex_prefix}{hex_digits}{integer_suffix_opt}{user_suffix_opt}
     107hex_constant {hex_prefix}{hex_digits}{integer_suffix_opt}
    107108
    108109                                // GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
    109 floating_suffix_opt ("_"?([fFdDlL][iI]?|[iI][lLfFdD]?|"DL"))?
     110exponent "_"?[eE]"_"?[+-]?{decimal_digits}
     111floating_suffix ([fFdDlL]?[iI]?)|([iI][lLfFdD])
     112floating_suffix_opt ("_"?({floating_suffix}|"DL"))?{user_suffix_opt}
    110113decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal})
    111 real_decimal {decimal_digits}"."{exponent}?{floating_suffix_opt}{user_suffix_opt}
    112 real_fraction "."{decimal_digits}{exponent}?{floating_suffix_opt}{user_suffix_opt}
    113 real_constant {decimal_digits}{real_fraction}
    114 exponent "_"?[eE]"_"?[+-]?{decimal_digits}
    115 floating_constant (({real_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix_opt}{user_suffix_opt}
     114floating_decimal {decimal_digits}"."{exponent}?{floating_suffix_opt}
     115floating_fraction "."{decimal_digits}{exponent}?{floating_suffix_opt}
     116floating_constant ({decimal_digits}{exponent}{floating_suffix_opt})|({decimal_digits}{floating_fraction})
    116117
    117118binary_exponent "_"?[pP]"_"?[+-]?{decimal_digits}
    118 hex_fractional_constant ({hex_digits}?"."{hex_digits})|({hex_digits}".")
    119 hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix_opt}
     119hex_floating_suffix_opt ("_"?({floating_suffix}))?{user_suffix_opt}
     120hex_floating_fraction ({hex_digits}?"."{hex_digits})|({hex_digits}".")
     121hex_floating_constant {hex_prefix}(({hex_floating_fraction}{binary_exponent})|({hex_digits}{binary_exponent})){hex_floating_suffix_opt}
    120122
    121123                                // character escape sequence, GCC: \e => esc character
    122124simple_escape "\\"[abefnrtv'"?\\]
    123                                 // ' stop highlighting
     125                                // ' stop editor highlighting
    124126octal_escape "\\"{octal}("_"?{octal}){0,2}
    125127hex_escape "\\""x""_"?{hex_digits}
     
    154156                                /* line directives */
    155157^{h_white}*"#"{h_white}*[0-9]+{h_white}*["][^"\n]+["].*"\n" {
    156         /* " stop highlighting */
     158        /* " stop editor highlighting */
    157159        static char filename[FILENAME_MAX];                                     // temporarily store current source-file name
    158160        char *end_num;
     
    310312{octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
    311313{hex_constant}  { NUMERIC_RETURN(INTEGERconstant); }
    312 {real_decimal}  { NUMERIC_RETURN(REALDECIMALconstant); } // must appear before floating_constant
    313 {real_fraction} { NUMERIC_RETURN(REALFRACTIONconstant); } // must appear before floating_constant
     314{floating_decimal}      { NUMERIC_RETURN(FLOATING_DECIMALconstant); } // must appear before floating_constant
     315{floating_fraction}     { NUMERIC_RETURN(FLOATING_FRACTIONconstant); } // must appear before floating_constant
    314316{floating_constant}     { NUMERIC_RETURN(FLOATINGconstant); }
    315317{hex_floating_constant} { NUMERIC_RETURN(FLOATINGconstant); }
     
    319321<QUOTE>[^'\\\n]* { strtext->append( yytext, yyleng ); }
    320322<QUOTE>['\n]{user_suffix_opt}   { BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(CHARACTERconstant); }
    321                                 /* ' stop highlighting */
     323                                /* ' stop editor highlighting */
    322324
    323325                                /* string constant */
     
    325327<STRING>[^"\\\n]* { strtext->append( yytext, yyleng ); }
    326328<STRING>["\n]{user_suffix_opt}  { BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(STRINGliteral); }
    327                                 /* " stop highlighting */
     329                                /* " stop editor highlighting */
    328330
    329331                                /* common character/string constant */
  • src/Parser/parser.yy

    ra506df4 rb3c7963  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 30 07:04:19 2017
    13 // Update Count     : 2740
     12// Last Modified On : Mon Sep 11 18:12:00 2017
     13// Update Count     : 2787
    1414//
    1515
     
    4343#define YYDEBUG_LEXER_TEXT (yylval)                                             // lexer loads this up each time
    4444#define YYDEBUG 1                                                                               // get the pretty debugging code to compile
     45#define YYERROR_VERBOSE
    4546
    4647#undef __GNUC_MINOR__
     
    6263stack< LinkageSpec::Spec > linkageStack;
    6364
    64 void appendStr( string *to, string *from ) {
    65         // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
    66         to->insert( to->length() - 1, from->substr( 1, from->length() - 2 ) );
     65bool appendStr( string & to, string & from ) {
     66        // 1. Multiple strings are concatenated into a single string but not combined internally. The reason is that
     67        //    "\x12" "3" is treated as 2 characters versus 1 because "escape sequences are converted into single members of
     68        //    the execution character set just prior to adjacent string literal concatenation" (C11, Section 6.4.5-8). It is
     69        //    easier to let the C compiler handle this case.
     70        //
     71        // 2. String encodings are transformed into canonical form (one encoding at start) so the encoding can be found
     72        //    without searching the string, e.g.: "abc" L"def" L"ghi" => L"abc" "def" "ghi". Multiple encodings must match,
     73        //    i.e., u"a" U"b" L"c" is disallowed.
     74
     75        if ( from[0] != '"' ) {                                                         // encoding ?
     76                if ( to[0] != '"' ) {                                                   // encoding ?
     77                        if ( to[0] != from[0] || to[1] != from[1] ) { // different encodings ?
     78                                yyerror( "non-matching string encodings for string-literal concatenation" );
     79                                return false;                                                   // parse error, must call YYERROR in action
     80                        } else if ( from[1] == '8' ) {
     81                                from.erase( 0, 1 );                                             // remove 2nd encoding
     82                        } // if
     83                } else {
     84                        if ( from[1] == '8' ) {                                         // move encoding to start
     85                                to = "u8" + to;
     86                                from.erase( 0, 1 );                                             // remove 2nd encoding
     87                        } else {
     88                                to = from[0] + to;
     89                        } // if
     90                } // if
     91                from.erase( 0, 1 );                                                             // remove 2nd encoding
     92        } // if
     93        to += " " + from;                                                                       // concatenated into single string
     94        return true;
    6795} // appendStr
    6896
     
    89117%}
    90118
     119%define parse.error verbose
     120
    91121// Types declaration
    92122%union
     
    100130        StatementNode * sn;
    101131        WaitForStmt * wfs;
    102         ConstantExpr * constant;
     132        Expression * constant;
    103133        IfCtl * ifctl;
    104134        ForCtl * fctl;
     
    146176// overloading constants 0/1, e.g., x.1 is lexed as (x)(.1), where (.1) is a factional constant, but is semantically
    147177// converted into the tuple index (.)(1). e.g., 3.x
    148 %token<tok>     REALDECIMALconstant     REALFRACTIONconstant    FLOATINGconstant
     178%token<tok>     FLOATING_DECIMALconstant        FLOATING_FRACTIONconstant       FLOATINGconstant
    149179
    150180// multi-character operators
     
    315345%precedence ELSE        // token precedence for start of else clause in IF/WAITFOR statement
    316346
     347
    317348%start translation_unit                                                                 // parse-tree root
    318349
     
    321352
    322353// The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal symbols
    323 // "identifier" and "TYPEDEFname" that are lexically identical.  While it is possible to write a purely context-free
    324 // grammar, such a grammar would obscure the relationship between syntactic and semantic constructs.  Hence, this
    325 // grammar uses the ANSI style.
     354// "identifier", "TYPEDEFname", and "TYPEGENname" that are lexically identical.  While it is possible to write a purely
     355// context-free grammar, such a grammar would obscure the relationship between syntactic and semantic constructs.
     356// Hence, this grammar uses the ANSI style.
    326357//
    327358// Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, those
     
    360391                // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
    361392        INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }
    362         | REALDECIMALconstant                                           { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    363         | REALFRACTIONconstant                                          { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
     393        | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
     394        | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    364395        | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    365396        | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( *$1 ) ); }
     
    390421        | string_literal_list STRINGliteral
    391422                {
    392                         appendStr( $1, $2 );                                            // append 2nd juxtaposed string to 1st
     423                        if ( ! appendStr( *$1, *$2 ) ) YYERROR;         // append 2nd juxtaposed string to 1st
    393424                        delete $2;                                                                      // allocated by lexer
    394425                        $$ = $1;                                                                        // conversion from tok to str
     
    434465        | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
    435466                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
    436         | postfix_expression REALFRACTIONconstant                       // CFA, tuple index
    437                 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_REALFRACTIONconstant( *$2 ) ) ); }
     467        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
     468                { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
    438469        | postfix_expression ARROW no_attr_identifier
    439470                {
     
    479510field:                                                                                                  // CFA, tuple field selector
    480511        field_name
    481         | REALDECIMALconstant field
    482                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
    483         | REALDECIMALconstant '[' push field_list pop ']'
    484                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_REALDECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); }
     512        | FLOATING_DECIMALconstant field
     513                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
     514        | FLOATING_DECIMALconstant '[' push field_list pop ']'
     515                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); }
    485516        | field_name '.' field
    486517                { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     
    507538        // empty
    508539                { $$ = nullptr; }
    509         | fraction_constants REALFRACTIONconstant
    510                 {
    511                         Expression * constant = build_field_name_REALFRACTIONconstant( *$2 );
     540        | fraction_constants FLOATING_FRACTIONconstant
     541                {
     542                        Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
    512543                        $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1,  constant ) ) : new ExpressionNode( constant );
    513544                }
Note: See TracChangeset for help on using the changeset viewer.