Changeset 930f69e


Ignore:
Timestamp:
Sep 10, 2017, 5:35:59 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
de9285f
Parents:
0cc818b
Message:

fix lexing issue for floating-point numbers, and add "h", "hh", and "z" integral suffixes

Location:
src
Files:
4 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r0cc818b r930f69e  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 22:21:21 2017
    13 // Update Count     : 639
     12// Last Modified On : Sun Sep 10 09:56:06 2017
     13// Update Count     : 655
    1414//
    1515
     
    5151extern const Type::Qualifiers noQualifiers;             // no qualifiers on constants
    5252
     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'; }
     
    6769
    6870Expression * build_constantInteger( string & str ) {
    69         static const BasicType::Kind kind[2][3] = {
    70                 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
    71                 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
     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
     
    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                str.erase( last, 1 );                                                   // remove 'z'
    145166        } // if
    146167
     
    247268} // build_constantStr
    248269
     270Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
     271        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
     272        Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
     273        delete &str;
     274        return ret;
     275} // build_field_name_FLOATING_FRACTIONconstant
     276
     277Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
     278        if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
     279        Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
     280        delete &str;
     281        return ret;
     282} // build_field_name_FLOATING_DECIMALconstant
     283
    249284Expression * build_field_name_FLOATINGconstant( const string & str ) {
    250285        // str is of the form A.B -> separate at the . and return member expression
     
    273308        return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
    274309} // build_field_name_fraction_constants
    275 
    276 Expression * build_field_name_REALFRACTIONconstant( const string & str ) {
    277         if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
    278         Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
    279         delete &str;
    280         return ret;
    281 } // build_field_name_REALFRACTIONconstant
    282 
    283 Expression * build_field_name_REALDECIMALconstant( const string & str ) {
    284         if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
    285         Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
    286         delete &str;
    287         return ret;
    288 } // build_field_name_REALDECIMALconstant
    289310
    290311NameExpr * build_varref( const string * name ) {
  • src/Parser/ParseNode.h

    r0cc818b r930f69e  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 19:24:34 2017
    13 // Update Count     : 799
     12// Last Modified On : Sun Sep 10 09:56:32 2017
     13// Update Count     : 801
    1414//
    1515
     
    166166Expression * build_constantChar( std::string &str );
    167167Expression * 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 );
  • src/Parser/lex.ll

    r0cc818b r930f69e  
    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 11:15:37 2017
     13 * Update Count     : 617
    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"))?
     110floating_suffix_opt ("_"?(([fFdDlL]?[iI]?)|([iI][lLfFdD])|"DL"))?{user_suffix_opt}
    110111decimal_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}
    114112exponent "_"?[eE]"_"?[+-]?{decimal_digits}
    115 floating_constant (({real_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix_opt}{user_suffix_opt}
     113floating_decimal {decimal_digits}"."{exponent}?{floating_suffix_opt}
     114floating_fraction "."{decimal_digits}{exponent}?{floating_suffix_opt}
     115floating_constant ({decimal_digits}{exponent}{floating_suffix_opt})|({decimal_digits}{floating_fraction})
    116116
    117117binary_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}
     118hex_floating_fraction ({hex_digits}?"."{hex_digits})|({hex_digits}".")
     119hex_floating_constant {hex_prefix}(({hex_floating_fraction}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix_opt}
    120120
    121121                                // character escape sequence, GCC: \e => esc character
    122122simple_escape "\\"[abefnrtv'"?\\]
    123                                 // ' stop highlighting
     123                                // ' stop editor highlighting
    124124octal_escape "\\"{octal}("_"?{octal}){0,2}
    125125hex_escape "\\""x""_"?{hex_digits}
     
    154154                                /* line directives */
    155155^{h_white}*"#"{h_white}*[0-9]+{h_white}*["][^"\n]+["].*"\n" {
    156         /* " stop highlighting */
     156        /* " stop editor highlighting */
    157157        static char filename[FILENAME_MAX];                                     // temporarily store current source-file name
    158158        char *end_num;
     
    310310{octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
    311311{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
     312{floating_decimal}      { NUMERIC_RETURN(FLOATING_DECIMALconstant); } // must appear before floating_constant
     313{floating_fraction}     { NUMERIC_RETURN(FLOATING_FRACTIONconstant); } // must appear before floating_constant
    314314{floating_constant}     { NUMERIC_RETURN(FLOATINGconstant); }
    315315{hex_floating_constant} { NUMERIC_RETURN(FLOATINGconstant); }
     
    319319<QUOTE>[^'\\\n]* { strtext->append( yytext, yyleng ); }
    320320<QUOTE>['\n]{user_suffix_opt}   { BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(CHARACTERconstant); }
    321                                 /* ' stop highlighting */
     321                                /* ' stop editor highlighting */
    322322
    323323                                /* string constant */
     
    325325<STRING>[^"\\\n]* { strtext->append( yytext, yyleng ); }
    326326<STRING>["\n]{user_suffix_opt}  { BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(STRINGliteral); }
    327                                 /* " stop highlighting */
     327                                /* " stop editor highlighting */
    328328
    329329                                /* common character/string constant */
  • src/Parser/parser.yy

    r0cc818b r930f69e  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 20:43:19 2017
    13 // Update Count     : 2742
     12// Last Modified On : Sun Sep 10 10:07:10 2017
     13// Update Count     : 2752
    1414//
    1515
     
    146146// overloading constants 0/1, e.g., x.1 is lexed as (x)(.1), where (.1) is a factional constant, but is semantically
    147147// converted into the tuple index (.)(1). e.g., 3.x
    148 %token<tok>     REALDECIMALconstant     REALFRACTIONconstant    FLOATINGconstant
     148%token<tok>     FLOATING_DECIMALconstant        FLOATING_FRACTIONconstant       FLOATINGconstant
    149149
    150150// multi-character operators
     
    315315%precedence ELSE        // token precedence for start of else clause in IF/WAITFOR statement
    316316
     317
    317318%start translation_unit                                                                 // parse-tree root
    318319
     
    321322
    322323// 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.
     324// "identifier", "TYPEDEFname", and "TYPEGENname" that are lexically identical.  While it is possible to write a purely
     325// context-free grammar, such a grammar would obscure the relationship between syntactic and semantic constructs.
     326// Hence, this grammar uses the ANSI style.
    326327//
    327328// Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, those
     
    360361                // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
    361362        INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }
    362         | REALDECIMALconstant                                           { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    363         | REALFRACTIONconstant                                          { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
     363        | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
     364        | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    364365        | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    365366        | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( *$1 ) ); }
     
    434435        | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
    435436                { $$ = 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 ) ) ); }
     437        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
     438                { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
    438439        | postfix_expression ARROW no_attr_identifier
    439440                {
     
    479480field:                                                                                                  // CFA, tuple field selector
    480481        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 ) ) ); }
     482        | FLOATING_DECIMALconstant field
     483                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
     484        | FLOATING_DECIMALconstant '[' push field_list pop ']'
     485                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); }
    485486        | field_name '.' field
    486487                { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     
    507508        // empty
    508509                { $$ = nullptr; }
    509         | fraction_constants REALFRACTIONconstant
    510                 {
    511                         Expression * constant = build_field_name_REALFRACTIONconstant( *$2 );
     510        | fraction_constants FLOATING_FRACTIONconstant
     511                {
     512                        Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
    512513                        $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1,  constant ) ) : new ExpressionNode( constant );
    513514                }
Note: See TracChangeset for help on using the changeset viewer.