Changeset 28f3a19 for src/Parser
- Timestamp:
- Jun 27, 2018, 3:28:41 PM (6 years ago)
- Branches:
- new-env, with_gc
- Children:
- b21c77a
- Parents:
- 0182bfa (diff), 63238a4 (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. - Location:
- src/Parser
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
r0182bfa r28f3a19 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue May 22 08:39:29201813 // Update Count : 107 412 // Last Modified On : Thu Jun 7 12:08:55 2018 13 // Update Count : 1079 14 14 // 15 15 … … 173 173 } 174 174 175 DeclarationNode * DeclarationNode::newFunction( string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) {175 DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) { 176 176 DeclarationNode * newnode = new DeclarationNode; 177 177 newnode->name = name; … … 244 244 } // DeclarationNode::newForall 245 245 246 DeclarationNode * DeclarationNode::newFromTypedef( string * name ) {246 DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) { 247 247 DeclarationNode * newnode = new DeclarationNode; 248 248 newnode->type = new TypeData( TypeData::SymbolicInst ); … … 267 267 } // DeclarationNode::newAggregate 268 268 269 DeclarationNode * DeclarationNode::newEnum( string * name, DeclarationNode * constants, bool body ) {269 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) { 270 270 assert( name ); 271 271 DeclarationNode * newnode = new DeclarationNode; … … 277 277 } // DeclarationNode::newEnum 278 278 279 DeclarationNode * DeclarationNode::newEnumConstant( string * name, ExpressionNode * constant ) {279 DeclarationNode * DeclarationNode::newEnumConstant( const string * name, ExpressionNode * constant ) { 280 280 DeclarationNode * newnode = new DeclarationNode; 281 281 newnode->name = name; … … 284 284 } // DeclarationNode::newEnumConstant 285 285 286 DeclarationNode * DeclarationNode::newName( string * name ) {286 DeclarationNode * DeclarationNode::newName( const string * name ) { 287 287 DeclarationNode * newnode = new DeclarationNode; 288 288 newnode->name = name; … … 290 290 } // DeclarationNode::newName 291 291 292 DeclarationNode * DeclarationNode::newFromTypeGen( string * name, ExpressionNode * params ) {292 DeclarationNode * DeclarationNode::newFromTypeGen( const string * name, ExpressionNode * params ) { 293 293 DeclarationNode * newnode = new DeclarationNode; 294 294 newnode->type = new TypeData( TypeData::SymbolicInst ); … … 299 299 } // DeclarationNode::newFromTypeGen 300 300 301 DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, string * name ) {301 DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, const string * name ) { 302 302 DeclarationNode * newnode = new DeclarationNode; 303 303 newnode->type = nullptr; … … 330 330 } // DeclarationNode::newTraitUse 331 331 332 DeclarationNode * DeclarationNode::newTypeDecl( string * name, DeclarationNode * typeParams ) {332 DeclarationNode * DeclarationNode::newTypeDecl( const string * name, DeclarationNode * typeParams ) { 333 333 DeclarationNode * newnode = new DeclarationNode; 334 334 newnode->name = name; … … 405 405 } // DeclarationNode::newBuiltinType 406 406 407 DeclarationNode * DeclarationNode::newAttr( string * name, ExpressionNode * expr ) {407 DeclarationNode * DeclarationNode::newAttr( const string * name, ExpressionNode * expr ) { 408 408 DeclarationNode * newnode = new DeclarationNode; 409 409 newnode->type = nullptr; … … 414 414 } 415 415 416 DeclarationNode * DeclarationNode::newAttr( string * name, DeclarationNode * type ) {416 DeclarationNode * DeclarationNode::newAttr( const string * name, DeclarationNode * type ) { 417 417 DeclarationNode * newnode = new DeclarationNode; 418 418 newnode->type = nullptr; … … 423 423 } 424 424 425 DeclarationNode * DeclarationNode::newAttribute( string * name, ExpressionNode * expr ) {425 DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) { 426 426 DeclarationNode * newnode = new DeclarationNode; 427 427 newnode->type = nullptr; … … 544 544 type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier 545 545 } else { // not polymorphic 546 type->aggregate.params = q->type->forall; // make polymorphic type 547 // change implicit typedef from TYPEDEFname to TYPEGENname 548 typedefTable.changeKind( *type->aggregate.name, TYPEGENname ); 546 type->aggregate.params = q->type->forall; // set forall qualifier 549 547 } // if 550 548 } else { // not polymorphic … … 1065 1063 SemanticError( this, "invalid function specifier for " ); 1066 1064 } // if 1067 return buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, maybeBuild< Initializer >(initializer), attributes )->set_extension( extension ); 1065 bool isDelete = initializer && initializer->get_isDelete(); 1066 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension ); 1067 if ( isDelete ) { 1068 DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl ); 1069 dwt->isDeleted = true; 1070 } 1071 return decl; 1068 1072 } // if 1069 1073 -
src/Parser/ExpressionNode.cc
r0182bfa r28f3a19 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 22 11:57:39201813 // Update Count : 80 112 // Last Modified On : Mon Jun 4 21:24:45 2018 13 // Update Count : 802 14 14 // 15 15 … … 314 314 315 315 Expression * build_constantStr( string & str ) { 316 assert( str.length() > 0 ); 316 317 string units; // units 317 318 sepString( str, units, '"' ); // separate constant from units -
src/Parser/InitializerNode.cc
r0182bfa r28f3a19 27 27 28 28 InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des ) 29 : expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ) {29 : expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) { 30 30 if ( aggrp ) 31 31 kids = dynamic_cast< InitializerNode * >( get_next() ); … … 36 36 37 37 InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des ) 38 : expr( nullptr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ) {38 : expr( nullptr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) { 39 39 if ( init ) 40 40 set_last( init ); … … 46 46 set_next( nullptr ); 47 47 } // InitializerNode::InitializerNode 48 49 InitializerNode::InitializerNode( bool isDelete ) : expr( nullptr ), aggregate( false ), designator( nullptr ), kids( nullptr ), maybeConstructed( false ), isDelete( isDelete ) {} 48 50 49 51 InitializerNode::~InitializerNode() { … … 84 86 85 87 Initializer * InitializerNode::build() const { 88 assertf( ! isDelete, "Should not build delete stmt InitializerNode" ); 86 89 if ( aggregate ) { 87 90 // steal designators from children -
src/Parser/ParseNode.h
r0182bfa r28f3a19 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 30 09:19:17201813 // Update Count : 8 3112 // Last Modified On : Wed Jun 6 16:17:18 2018 13 // Update Count : 843 14 14 // 15 15 … … 77 77 78 78 ParseNode * next = nullptr; 79 std::string * name = nullptr;79 const std::string * name = nullptr; 80 80 CodeLocation location = yylloc; 81 81 }; // ParseNode … … 87 87 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr ); 88 88 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr ); 89 InitializerNode( bool isDelete ); 89 90 ~InitializerNode(); 90 91 virtual InitializerNode * clone() const { assert( false ); return nullptr; } … … 97 98 InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; } 98 99 bool get_maybeConstructed() const { return maybeConstructed; } 100 101 bool get_isDelete() const { return isDelete; } 99 102 100 103 InitializerNode * next_init() const { return kids; } … … 110 113 InitializerNode * kids; 111 114 bool maybeConstructed; 115 bool isDelete; 112 116 }; // InitializerNode 113 117 … … 167 171 }; 168 172 169 Expression * build_constantInteger( std::string & str );170 Expression * build_constantFloat( std::string & str );171 Expression * build_constantChar( std::string & str );172 Expression * build_constantStr( std::string & str );173 Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string 174 Expression * build_constantFloat( std::string & str ); 175 Expression * build_constantChar( std::string & str ); 176 Expression * build_constantStr( std::string & str ); 173 177 Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str ); 174 178 Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str ); … … 226 230 static DeclarationNode * newBuiltinType( BuiltinType ); 227 231 static DeclarationNode * newForall( DeclarationNode * ); 228 static DeclarationNode * newFromTypedef( std::string * );229 static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );232 static DeclarationNode * newFromTypedef( const std::string * ); 233 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ); 230 234 static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ); 231 static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );232 static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );233 static DeclarationNode * newName( std::string * );234 static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );235 static DeclarationNode * newTypeParam( TypeClass, std::string * );235 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body ); 236 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant ); 237 static DeclarationNode * newName( const std::string * ); 238 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params ); 239 static DeclarationNode * newTypeParam( TypeClass, const std::string * ); 236 240 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts ); 237 241 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params ); 238 static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );242 static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams ); 239 243 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind ); 240 244 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic ); … … 243 247 static DeclarationNode * newTuple( DeclarationNode * members ); 244 248 static DeclarationNode * newTypeof( ExpressionNode * expr ); 245 static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes246 static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes247 static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes249 static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes 250 static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes 251 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes 248 252 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement 249 253 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message ); … … 399 403 }; 400 404 405 Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init ); 401 406 Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ); 402 407 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ); 403 408 Statement * build_case( ExpressionNode * ctl ); 404 409 Statement * build_default(); 405 Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false ); 410 Statement * build_while( IfCtl * ctl, StatementNode * stmt ); 411 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt ); 406 412 Statement * build_for( ForCtl * forctl, StatementNode * stmt ); 407 413 Statement * build_branch( BranchStmt::Type kind ); -
src/Parser/StatementNode.cc
r0182bfa r28f3a19 10 10 // Created On : Sat May 16 14:59:41 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 30 09:21:16201813 // Update Count : 3 5412 // Last Modified On : Tue Jun 5 08:58:34 2018 13 // Update Count : 362 14 14 // 15 15 … … 69 69 caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts ); 70 70 return this; 71 } 71 } // StatementNode::append_last_case 72 72 73 73 Statement * build_expr( ExpressionNode * ctl ) { 74 74 Expression * e = maybeMoveBuild< Expression >( ctl ); 75 75 76 if ( e ) 77 return new ExprStmt( e ); 78 else 79 return new NullStmt(); 80 } 81 82 Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) { 83 Statement * thenb, * elseb = 0; 84 std::list< Statement * > branches; 85 buildMoveList< Statement, StatementNode >( then_stmt, branches ); 86 assert( branches.size() == 1 ); 87 thenb = branches.front(); 88 89 if ( else_stmt ) { 90 std::list< Statement * > branches; 91 buildMoveList< Statement, StatementNode >( else_stmt, branches ); 92 assert( branches.size() == 1 ); 93 elseb = branches.front(); 94 } // if 95 96 std::list< Statement * > init; 76 if ( e ) return new ExprStmt( e ); 77 else return new NullStmt(); 78 } // build_expr 79 80 Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init ) { 97 81 if ( ctl->init != 0 ) { 98 82 buildMoveList( ctl->init, init ); … … 102 86 if ( ctl->condition ) { 103 87 // compare the provided condition against 0 104 cond = 88 cond = notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) ); 105 89 } else { 106 90 for ( Statement * stmt : init ) { … … 113 97 } 114 98 delete ctl; 99 return cond; 100 } // build_if_control 101 102 Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) { 103 Statement * thenb, * elseb = nullptr; 104 std::list< Statement * > branches; 105 buildMoveList< Statement, StatementNode >( then_stmt, branches ); 106 assert( branches.size() == 1 ); 107 thenb = branches.front(); 108 109 if ( else_stmt ) { 110 std::list< Statement * > branches; 111 buildMoveList< Statement, StatementNode >( else_stmt, branches ); 112 assert( branches.size() == 1 ); 113 elseb = branches.front(); 114 } // if 115 116 std::list< Statement * > init; 117 Expression * cond = build_if_control( ctl, init ); 115 118 return new IfStmt( cond, thenb, elseb, init ); 116 } 119 } // build_if 117 120 118 121 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) { … … 130 133 // branches.size() == 0 for switch (...) {}, i.e., no declaration or statements 131 134 return new SwitchStmt( maybeMoveBuild< Expression >(ctl), branches ); 132 } 135 } // build_switch 136 133 137 Statement * build_case( ExpressionNode * ctl ) { 134 138 std::list< Statement * > branches; 135 139 return new CaseStmt( maybeMoveBuild< Expression >(ctl), branches ); 136 } 140 } // build_case 141 137 142 Statement * build_default() { 138 143 std::list< Statement * > branches; 139 144 return new CaseStmt( nullptr, branches, true ); 140 } 141 142 Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind ) { 143 std::list< Statement * > branches; 144 buildMoveList< Statement, StatementNode >( stmt, branches ); 145 assert( branches.size() == 1 ); 146 return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind ); 147 } 145 } // build_default 146 147 Statement * build_while( IfCtl * ctl, StatementNode * stmt ) { 148 std::list< Statement * > branches; 149 buildMoveList< Statement, StatementNode >( stmt, branches ); 150 assert( branches.size() == 1 ); 151 152 std::list< Statement * > init; 153 Expression * cond = build_if_control( ctl, init ); 154 return new WhileStmt( cond, branches.front(), init, false ); 155 } // build_while 156 157 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt ) { 158 std::list< Statement * > branches; 159 buildMoveList< Statement, StatementNode >( stmt, branches ); 160 assert( branches.size() == 1 ); 161 162 std::list< Statement * > init; 163 return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), init, true ); 164 } // build_do_while 148 165 149 166 Statement * build_for( ForCtl * forctl, StatementNode * stmt ) { … … 167 184 delete forctl; 168 185 return new ForStmt( init, cond, incr, branches.front() ); 169 } 186 } // build_for 170 187 171 188 Statement * build_branch( BranchStmt::Type kind ) { 172 189 Statement * ret = new BranchStmt( "", kind ); 173 190 return ret; 174 } 191 } // build_branch 192 175 193 Statement * build_branch( std::string * identifier, BranchStmt::Type kind ) { 176 194 Statement * ret = new BranchStmt( * identifier, kind ); 177 195 delete identifier; // allocated by lexer 178 196 return ret; 179 } 197 } // build_branch 198 180 199 Statement * build_computedgoto( ExpressionNode * ctl ) { 181 200 return new BranchStmt( maybeMoveBuild< Expression >(ctl), BranchStmt::Goto ); 182 } 201 } // build_computedgoto 183 202 184 203 Statement * build_return( ExpressionNode * ctl ) { … … 186 205 buildMoveList( ctl, exps ); 187 206 return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr ); 188 } 207 } // build_return 189 208 190 209 Statement * build_throw( ExpressionNode * ctl ) { … … 193 212 assertf( exps.size() < 2, "This means we are leaking memory"); 194 213 return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr ); 195 } 214 } // build_throw 196 215 197 216 Statement * build_resume( ExpressionNode * ctl ) { … … 200 219 assertf( exps.size() < 2, "This means we are leaking memory"); 201 220 return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr ); 202 } 221 } // build_resume 203 222 204 223 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) { … … 206 225 (void)target; 207 226 assertf( false, "resume at (non-local throw) is not yet supported," ); 208 } 227 } // build_resume_at 209 228 210 229 Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt ) { … … 214 233 FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_stmt) ); 215 234 return new TryStmt( tryBlock, branches, finallyBlock ); 216 } 235 } // build_try 236 217 237 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) { 218 238 std::list< Statement * > branches; … … 220 240 assert( branches.size() == 1 ); 221 241 return new CatchStmt( kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), branches.front() ); 222 } 242 } // build_catch 243 223 244 Statement * build_finally( StatementNode * stmt ) { 224 245 std::list< Statement * > branches; … … 226 247 assert( branches.size() == 1 ); 227 248 return new FinallyStmt( dynamic_cast< CompoundStmt * >( branches.front() ) ); 228 } 249 } // build_finally 229 250 230 251 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) { … … 247 268 248 269 return node; 249 } 270 } // build_waitfor 250 271 251 272 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) { … … 266 287 267 288 return node; 268 } 289 } // build_waitfor 269 290 270 291 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ) { … … 275 296 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 276 297 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 277 } 278 else { 298 } else { 279 299 node->orelse.statement = maybeMoveBuild<Statement >( stmt ); 280 300 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 281 } 301 } // if 282 302 283 303 return node; 284 } 304 } // build_waitfor_timeout 285 305 286 306 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ) { … … 295 315 296 316 return node; 297 } 317 } // build_waitfor_timeout 298 318 299 319 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) { … … 302 322 Statement * s = maybeMoveBuild<Statement>( stmt ); 303 323 return new WithStmt( e, s ); 304 } 324 } // build_with 305 325 306 326 Statement * build_compound( StatementNode * first ) { … … 308 328 buildMoveList( first, cs->get_kids() ); 309 329 return cs; 310 } 330 } // build_compound 311 331 312 332 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) { … … 318 338 buildMoveList( clobber, clob ); 319 339 return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels ); 320 } 340 } // build_asm 321 341 322 342 Statement * build_directive( string * directive ) { 323 343 return new DirectiveStmt( *directive ); 324 } 344 } // build_directive 325 345 326 346 // Local Variables: // -
src/Parser/TypeData.cc
r0182bfa r28f3a19 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Apr 26 13:46:07201813 // Update Count : 60 312 // Last Modified On : Wed Jun 6 17:40:33 2018 13 // Update Count : 604 14 14 // 15 15 … … 65 65 case Aggregate: 66 66 // aggregate = new Aggregate_t; 67 aggregate.kind = DeclarationNode::NoAggregate; 67 68 aggregate.name = nullptr; 68 69 aggregate.params = nullptr; … … 70 71 aggregate.fields = nullptr; 71 72 aggregate.body = false; 73 aggregate.tagged = false; 74 aggregate.parent = nullptr; 72 75 break; 73 76 case AggregateInst: … … 198 201 break; 199 202 case Aggregate: 203 newtype->aggregate.kind = aggregate.kind; 200 204 newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr; 201 205 newtype->aggregate.params = maybeClone( aggregate.params ); 202 206 newtype->aggregate.actuals = maybeClone( aggregate.actuals ); 203 207 newtype->aggregate.fields = maybeClone( aggregate.fields ); 204 newtype->aggregate.kind = aggregate.kind;205 208 newtype->aggregate.body = aggregate.body; 206 209 newtype->aggregate.tagged = aggregate.tagged; … … 575 578 576 579 case DeclarationNode::Int128: 577 ret = td->signedness == 1? BasicType::UnsignedInt128 : BasicType::SignedInt128;580 ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128; 578 581 if ( td->length != DeclarationNode::NoLength ) { 579 582 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); … … 599 602 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 600 603 } // if 601 if ( td->basictype == DeclarationNode::Float&& td->length == DeclarationNode::Long ) {604 if ( td->basictype != DeclarationNode::Double && td->length == DeclarationNode::Long ) { 602 605 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 603 606 } // if … … 605 608 const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble; 606 609 } // if 610 611 if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) { 612 // if ( td->complextype != DeclarationNode::NoComplexType ) { 613 // genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype ); 614 // } 615 if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80; 616 else ret = BasicType::Float128; 617 break; 618 } 607 619 608 620 ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ]; -
src/Parser/TypedefTable.cc
r0182bfa r28f3a19 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 22 08:40:01201813 // Update Count : 12112 // Last Modified On : Fri Jun 22 06:14:39 2018 13 // Update Count : 206 14 14 // 15 15 … … 17 17 #include "TypedefTable.h" 18 18 #include <cassert> // for assert 19 #include <iostream> 19 20 20 21 #if 0 21 #include <iostream> 22 #define debugPrint( x ) cerr << x 22 #define debugPrint( code ) code 23 23 #else 24 #define debugPrint( x)24 #define debugPrint( code ) 25 25 #endif 26 26 27 27 using namespace std; // string, iostream 28 28 29 debugPrint( 30 static const char *kindName( int kind ) { 31 switch ( kind ) { 32 case IDENTIFIER: return "identifier"; 33 case TYPEDEFname: return "typedef"; 34 case TYPEGENname: return "typegen"; 35 default: 36 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl; 37 abort(); 38 } // switch 39 } // kindName 40 ) 41 29 42 TypedefTable::~TypedefTable() { 30 43 if ( ! SemanticErrorThrow && kindTable.currentScope() != 0 ) { 31 // std::cerr << "scope failure " << kindTable.currentScope() << endl; 44 cerr << "Error: cfa-cpp internal error, scope failure " << kindTable.currentScope() << endl; 45 abort(); 32 46 } // if 33 47 } // TypedefTable::~TypedefTable … … 44 58 } // TypedefTable::isKind 45 59 46 void TypedefTable::changeKind( const string & identifier, int kind ) {47 KindTable::iterator posn = kindTable.find( identifier );48 if ( posn != kindTable.end() ) posn->second = kind; // exists => update49 } // TypedefTable::changeKind50 51 60 // SKULLDUGGERY: Generate a typedef for the aggregate name so the aggregate does not have to be qualified by 52 61 // "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed if the 53 62 // name is explicitly used. 54 void TypedefTable::makeTypedef( const string & name ) { 63 void TypedefTable::makeTypedef( const string & name, int kind ) { 64 // Check for existence is necessary to handle: 65 // struct Fred {}; 66 // void Fred(); 67 // void fred() { 68 // struct Fred act; // do not add as type in this scope 69 // Fred(); 70 // } 55 71 if ( ! typedefTable.exists( name ) ) { 56 typedefTable.addToEnclosingScope( name, TYPEDEFname);72 typedefTable.addToEnclosingScope( name, kind, "MTD" ); 57 73 } // if 58 74 } // TypedefTable::makeTypedef 59 75 60 void TypedefTable::addToEnclosingScope( const std::string & identifier, int kind ) { 61 assert( kindTable.currentScope() >= 1 ); 62 auto scope = kindTable.currentScope() - 1; 63 debugPrint( "Adding " << identifier << " as kind " << kind << " scope " << scope << endl ); 76 void TypedefTable::addToScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 77 auto scope = kindTable.currentScope(); 78 debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl ); 79 auto ret = kindTable.insertAt( scope, identifier, kind ); 80 //if ( ! ret.second ) ret.first->second = kind; // exists => update 81 assert( ret.first->second == kind ); // exists 82 } // TypedefTable::addToScope 83 84 void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 85 assert( kindTable.currentScope() >= 1 + level ); 86 auto scope = kindTable.currentScope() - 1 - level; 87 debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << endl ); 64 88 auto ret = kindTable.insertAt( scope, identifier, kind ); 65 89 if ( ! ret.second ) ret.first->second = kind; // exists => update … … 68 92 void TypedefTable::enterScope() { 69 93 kindTable.beginScope(); 70 debugPrint( "Entering scope " << kindTable.currentScope() << endl);94 debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl; print() ); 71 95 } // TypedefTable::enterScope 72 96 73 97 void TypedefTable::leaveScope() { 74 debugPrint( "Leaving scope " << kindTable.currentScope() << endl);98 debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl; print() ); 75 99 kindTable.endScope(); 76 100 } // TypedefTable::leaveScope 77 101 78 // void TypedefTable::print( void ) const { 79 // for ( KindTable::const_iterator i = table.begin(); i != table.end(); i++) { 80 // debugPrint( (*i ).first << ": " ); 81 // list< Entry > declList = (*i).second; 82 // for ( list< Entry >::const_iterator j = declList.begin(); j != declList.end(); j++ ) { 83 // debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " ); 84 // } 85 // debugPrint( endl ); 86 // } // for 87 // } 102 void TypedefTable::print( void ) const { 103 KindTable::size_type scope = kindTable.currentScope(); 104 debugPrint( cerr << "[" << scope << "]" ); 105 for ( KindTable::const_iterator i = kindTable.begin(); i != kindTable.end(); i++ ) { 106 while ( i.get_level() != scope ) { 107 --scope; 108 debugPrint( cerr << endl << "[" << scope << "]" ); 109 } // while 110 debugPrint( cerr << " " << (*i).first << ":" << kindName( (*i).second ) ); 111 } // for 112 while ( scope > 0 ) { 113 --scope; 114 debugPrint( cerr << endl << "[" << scope << "]" ); 115 } // while 116 debugPrint( cerr << endl ); 117 } // TypedefTable::print 88 118 89 119 // Local Variables: // -
src/Parser/TypedefTable.h
r0182bfa r28f3a19 10 10 // Created On : Sat May 16 15:24:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 22 08:39:29201813 // Update Count : 7712 // Last Modified On : Fri Jun 22 05:29:58 2018 13 // Update Count : 86 14 14 // 15 15 … … 25 25 typedef ScopedMap< std::string, int > KindTable; 26 26 KindTable kindTable; 27 unsigned int level = 0; 27 28 public: 28 29 ~TypedefTable(); … … 30 31 bool exists( const std::string & identifier ); 31 32 int isKind( const std::string & identifier ) const; 32 void changeKind( const std::string & identifier, int kind);33 void makeTypedef( const std::string & name);34 void addToEnclosingScope( const std::string & identifier, int kind );33 void makeTypedef( const std::string & name, int kind = TYPEDEFname ); 34 void addToScope( const std::string & identifier, int kind, const char * ); 35 void addToEnclosingScope( const std::string & identifier, int kind, const char * ); 35 36 36 37 void enterScope(); 37 38 void leaveScope(); 39 40 void up() { level += 1; } 41 void down() { level -= 1; } 42 43 void print( void ) const; 38 44 }; // TypedefTable 39 45 -
src/Parser/lex.ll
r0182bfa r28f3a19 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Thu May 3 13:42:40201813 * Update Count : 6 7612 * Last Modified On : Wed Jun 20 09:08:28 2018 13 * Update Count : 682 14 14 */ 15 15 … … 25 25 //**************************** Includes and Defines **************************** 26 26 27 // trigger before each matching rule's action 28 #define YY_USER_ACTION \ 29 yylloc.first_line = yylineno; \ 30 yylloc.first_column = column; \ 31 column += yyleng; \ 32 yylloc.last_column = column; \ 33 yylloc.last_line = yylineno; \ 34 yylloc.filename = yyfilename ? yyfilename : ""; 27 35 unsigned int column = 0; // position of the end of the last token parsed 28 #define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : ""; // trigger before each matching rule's action29 36 30 37 #include <string> … … 49 56 #define NUMERIC_RETURN(x) rm_underscore(); RETURN_VAL( x ) // numeric constant 50 57 #define KEYWORD_RETURN(x) RETURN_CHAR( x ) // keyword 51 #define QKEYWORD_RETURN(x) typedefTable.isKind( yytext ); RETURN_VAL(x);// quasi-keyword58 #define QKEYWORD_RETURN(x) RETURN_VAL(x); // quasi-keyword 52 59 #define IDENTIFIER_RETURN() RETURN_VAL( typedefTable.isKind( yytext ) ) 53 60 #define ATTRIBUTE_RETURN() RETURN_VAL( ATTR_IDENTIFIER ) … … 232 239 finally { KEYWORD_RETURN(FINALLY); } // CFA 233 240 float { KEYWORD_RETURN(FLOAT); } 241 _Float32 { KEYWORD_RETURN(FLOAT); } // GCC 242 _Float32x { KEYWORD_RETURN(FLOAT); } // GCC 243 _Float64 { KEYWORD_RETURN(DOUBLE); } // GCC 244 _Float64x { KEYWORD_RETURN(DOUBLE); } // GCC 234 245 __float80 { KEYWORD_RETURN(FLOAT80); } // GCC 235 246 float80 { KEYWORD_RETURN(FLOAT80); } // GCC 247 _Float128 { KEYWORD_RETURN(FLOAT128); } // GCC 248 _Float128x { KEYWORD_RETURN(FLOAT128); } // GCC 236 249 __float128 { KEYWORD_RETURN(FLOAT128); } // GCC 237 250 float128 { KEYWORD_RETURN(FLOAT128); } // GCC … … 446 459 447 460 %% 461 448 462 // ----end of lexer---- 449 463 450 464 void yyerror( const char * errmsg ) { 465 SemanticErrorThrow = true; 451 466 cout << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1 452 467 << ": " << ErrorHelpers::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl; -
src/Parser/parser.yy
r0182bfa r28f3a19 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 24 18:11:59201813 // Update Count : 3 36912 // Last Modified On : Fri Jun 22 13:59:11 2018 13 // Update Count : 3586 14 14 // 15 15 … … 136 136 } // build_postfix_name 137 137 138 bool forall = false, xxx = false ;// aggregate have one or more forall qualifiers ?138 bool forall = false, xxx = false, yyy = false; // aggregate have one or more forall qualifiers ? 139 139 140 140 // https://www.gnu.org/software/bison/manual/bison.html#Location-Type … … 175 175 bool flag; 176 176 CatchStmt::Kind catch_kind; 177 GenericExpr * genexpr; 177 178 } 178 179 … … 259 260 %type<flag> asm_volatile_opt 260 261 %type<en> handler_predicate_opt 262 %type<genexpr> generic_association generic_assoc_list 261 263 262 264 // statements 263 265 %type<sn> statement labeled_statement compound_statement 264 266 %type<sn> statement_decl statement_decl_list statement_list_nodecl 265 %type<sn> selection_statement 267 %type<sn> selection_statement if_statement 266 268 %type<sn> switch_clause_list_opt switch_clause_list 267 269 %type<en> case_value … … 302 304 %type<en> enumerator_value_opt 303 305 304 %type<decl> exception_declaration external_definition external_definition_list external_definition_list_opt 306 %type<decl> external_definition external_definition_list external_definition_list_opt 307 308 %type<decl> exception_declaration 305 309 306 310 %type<decl> field_declaration field_declaration_list_opt field_declarator_opt field_declaring_list … … 324 328 %type<decl> cfa_identifier_parameter_declarator_tuple cfa_identifier_parameter_ptr 325 329 326 %type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_ type_list_opt330 %type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_ellipsis_list_opt 327 331 328 332 %type<decl> cfa_typedef_declaration cfa_variable_declaration cfa_variable_specifier … … 330 334 %type<decl> c_declaration static_assert 331 335 %type<decl> KR_function_declarator KR_function_no_ptr KR_function_ptr KR_function_array 332 %type<decl> KR_ declaration_list KR_declaration_list_opt336 %type<decl> KR_parameter_list KR_parameter_list_opt 333 337 334 338 %type<decl> parameter_declaration parameter_list parameter_type_list_opt … … 402 406 //************************* Namespace Management ******************************** 403 407 404 // The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal symbols 405 // "identifier", "TYPEDEFname", and "TYPEGENname" that are lexically identical. While it is possible to write a purely 406 // context-free grammar, such a grammar would obscure the relationship between syntactic and semantic constructs. 407 // Hence, this grammar uses the ANSI style. 408 // 409 // Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, those 410 // introduced through "forall" qualifiers), and by introducing "type generators" -- parameterized types. This latter 411 // type name creates a third class of identifiers that must be distinguished by the scanner. 412 // 413 // Since the scanner cannot distinguish among the different classes of identifiers without some context information, it 414 // accesses a data structure (TypedefTable) to allow classification of an identifier that it has just read. Semantic 415 // actions during the parser update this data structure when the class of identifiers change. 416 // 417 // Because the Cforall language is block-scoped, an identifier can change its class in a local scope; it must revert to 418 // its original class at the end of the block. Since type names can be local to a particular declaration, each 419 // declaration is itself a scope. This requires distinguishing between type names that are local to the current 420 // declaration scope and those that persist past the end of the declaration (i.e., names defined in "typedef" or "otype" 421 // declarations). 422 // 423 // The non-terminals "push" and "pop" denote the opening and closing of scopes. Every push must have a matching pop, 424 // although it is regrettable the matching pairs do not always occur within the same rule. These non-terminals may 425 // appear in more contexts than strictly necessary from a semantic point of view. 408 // The C grammar is not context free because it relies on the distinct terminal symbols "identifier" and "TYPEDEFname", 409 // which are lexically identical. 410 // 411 // typedef int foo; // identifier foo must now be scanned as TYPEDEFname 412 // foo f; // to allow it to appear in this context 413 // 414 // While it may be possible to write a purely context-free grammar, such a grammar would obscure the relationship 415 // between syntactic and semantic constructs. Cforall compounds this problem by introducing type names local to the 416 // scope of a declaration (for instance, those introduced through "forall" qualifiers), and by introducing "type 417 // generators" -- parameterized types. This latter type name creates a third class of identifiers, "TYPEGENname", which 418 // must be distinguished by the lexical scanner. 419 // 420 // Since the scanner cannot distinguish among the different classes of identifiers without some context information, 421 // there is a type table (typedefTable), which holds type names and identifiers that override type names, for each named 422 // scope. During parsing, semantic actions update the type table by adding new identifiers in the current scope. For 423 // each context that introduces a name scope, a new level is created in the type table and that level is popped on 424 // exiting the scope. Since type names can be local to a particular declaration, each declaration is itself a scope. 425 // This requires distinguishing between type names that are local to the current declaration scope and those that 426 // persist past the end of the declaration (i.e., names defined in "typedef" or "otype" declarations). 427 // 428 // The non-terminals "push" and "pop" denote the opening and closing of named scopes. Every push has a matching pop in 429 // the production rule. There are multiple lists of declarations, where each declaration is a named scope, so pop/push 430 // around the list separator. 431 // 432 // int f( forall(T) T (*f1) T , forall( S ) S (*f2)( S ) ); 433 // push pop push pop 426 434 427 435 push: … … 497 505 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); } 498 506 | type_name '.' no_attr_identifier // CFA, nested type 499 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 507 // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 508 { $$ = nullptr; } 500 509 | type_name '.' '[' field_list ']' // CFA, nested type / tuple field selector 501 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 510 // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 511 { $$ = nullptr; } 502 512 | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11 503 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; } 513 { 514 // add the missing control expression to the GenericExpr and return it 515 $5->control = maybeMoveBuild<Expression>( $3 ); 516 $$ = new ExpressionNode( $5 ); 517 } 504 518 ; 505 519 506 520 generic_assoc_list: // C11 507 |generic_association521 generic_association 508 522 | generic_assoc_list ',' generic_association 523 { 524 // steal the association node from the singleton and delete the wrapper 525 $1->associations.splice($1->associations.end(), $3->associations); 526 delete $3; 527 $$ = $1; 528 } 509 529 ; 510 530 511 531 generic_association: // C11 512 532 type_no_function ':' assignment_expression 533 { 534 // create a GenericExpr wrapper with one association pair 535 $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>($3) } } ); 536 } 513 537 | DEFAULT ':' assignment_expression 538 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>($3) } } ); } 514 539 ; 515 540 … … 623 648 // semantics checks, e.g., ++3, 3--, *3, &&3 624 649 | constant 625 { $$ = $1; }626 650 | string_literal 627 651 { $$ = new ExpressionNode( $1 ); } … … 835 859 // '[' ']' 836 860 // { $$ = new ExpressionNode( build_tuple() ); } 837 // '[' push assignment_expression pop ']'861 // | '[' push assignment_expression pop ']' 838 862 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 839 '[' push ',' tuple_expression_list pop']'840 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $ 4) ) ); }841 | '[' push assignment_expression ',' tuple_expression_list pop']'842 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $ 5) ) ); }863 '[' ',' tuple_expression_list ']' 864 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); } 865 | '[' push assignment_expression pop ',' tuple_expression_list ']' 866 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $6 ) ) ); } 843 867 ; 844 868 … … 892 916 '{' '}' 893 917 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); } 894 | '{' 895 // Two scopes are necessary because the block itself has a scope, but every declaration within the block also 896 // requires its own scope. 897 push push 918 | '{' push 898 919 local_label_declaration_opt // GCC, local labels 899 920 statement_decl_list // C99, intermix declarations and statements 900 921 pop '}' 901 { $$ = new StatementNode( build_compound( $ 5) ); }922 { $$ = new StatementNode( build_compound( $4 ) ); } 902 923 ; 903 924 904 925 statement_decl_list: // C99 905 926 statement_decl 906 | statement_decl_list pushstatement_decl907 { if ( $1 != 0 ) { $1->set_last( $ 3); $$ = $1; } }927 | statement_decl_list statement_decl 928 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } } 908 929 ; 909 930 … … 923 944 $$ = new StatementNode( $2 ); 924 945 } 925 | statement pop946 | statement 926 947 ; 927 948 … … 938 959 939 960 selection_statement: 940 IF '(' push if_control_expression ')' statement %prec THEN 941 // explicitly deal with the shift/reduce conflict on if/else 942 { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); } 943 | IF '(' push if_control_expression ')' statement ELSE statement 944 { $$ = new StatementNode( build_if( $4, $6, $8 ) ); } 961 // pop causes a S/R conflict without separating the IF statement into a non-terminal even after resolving 962 // the inherent S/R conflict with THEN/ELSE. 963 push if_statement pop 964 { $$ = $2; } 945 965 | SWITCH '(' comma_expression ')' case_clause 946 966 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); } 947 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA967 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 948 968 { 949 969 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) ); … … 957 977 | CHOOSE '(' comma_expression ')' case_clause // CFA 958 978 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); } 959 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA979 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 960 980 { 961 981 StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) ); … … 964 984 ; 965 985 986 if_statement: 987 IF '(' if_control_expression ')' statement %prec THEN 988 // explicitly deal with the shift/reduce conflict on if/else 989 { $$ = new StatementNode( build_if( $3, $5, nullptr ) ); } 990 | IF '(' if_control_expression ')' statement ELSE statement 991 { $$ = new StatementNode( build_if( $3, $5, $7 ) ); } 992 ; 993 966 994 if_control_expression: 967 comma_expression pop995 comma_expression 968 996 { $$ = new IfCtl( nullptr, $1 ); } 969 | c_declaration pop// no semi-colon997 | c_declaration // no semi-colon 970 998 { $$ = new IfCtl( $1, nullptr ); } 971 | cfa_declaration pop// no semi-colon999 | cfa_declaration // no semi-colon 972 1000 { $$ = new IfCtl( $1, nullptr ); } 973 1001 | declaration comma_expression // semi-colon separated … … 1026 1054 1027 1055 iteration_statement: 1028 WHILE '(' comma_expression ')' statement1029 { $$ = new StatementNode( build_while( $ 3, $5) ); }1056 WHILE '(' push if_control_expression ')' statement pop 1057 { $$ = new StatementNode( build_while( $4, $6 ) ); } 1030 1058 | DO statement WHILE '(' comma_expression ')' ';' 1031 { $$ = new StatementNode( build_ while( $5, $2, true) ); }1032 | FOR '(' push for_control_expression ')' statement 1059 { $$ = new StatementNode( build_do_while( $5, $2 ) ); } 1060 | FOR '(' push for_control_expression ')' statement pop 1033 1061 { $$ = new StatementNode( build_for( $4, $6 ) ); } 1034 1062 ; 1035 1063 1036 1064 for_control_expression: 1037 comma_expression_opt pop';' comma_expression_opt ';' comma_expression_opt1038 { $$ = new ForCtl( $1, $ 4, $6); }1065 comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt 1066 { $$ = new ForCtl( $1, $3, $5 ); } 1039 1067 | declaration comma_expression_opt ';' comma_expression_opt // C99 1040 1068 { $$ = new ForCtl( $1, $2, $4 ); } … … 1158 1186 1159 1187 handler_clause: 1160 handler_key '(' push pushexception_declaration pop handler_predicate_opt ')' compound_statement pop1161 { $$ = new StatementNode( build_catch( $1, $ 5, $7, $9) ); }1162 | handler_clause handler_key '(' push pushexception_declaration pop handler_predicate_opt ')' compound_statement pop1163 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $ 6, $8, $10) ) ); }1188 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop 1189 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); } 1190 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop 1191 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); } 1164 1192 ; 1165 1193 … … 1265 1293 1266 1294 declaration_list_opt: // used at beginning of switch statement 1267 pop// empty1295 // empty 1268 1296 { $$ = nullptr; } 1269 1297 | declaration_list … … 1272 1300 declaration_list: 1273 1301 declaration 1274 | declaration_list pushdeclaration1275 { $$ = $1->appendList( $ 3); }1276 ; 1277 1278 KR_ declaration_list_opt:// used to declare parameter types in K&R style functions1302 | declaration_list declaration 1303 { $$ = $1->appendList( $2 ); } 1304 ; 1305 1306 KR_parameter_list_opt: // used to declare parameter types in K&R style functions 1279 1307 // empty 1280 1308 { $$ = nullptr; } 1281 | KR_ declaration_list1282 ; 1283 1284 KR_ declaration_list:1309 | KR_parameter_list 1310 ; 1311 1312 KR_parameter_list: 1285 1313 push c_declaration pop ';' 1286 1314 { $$ = $2; } 1287 | KR_ declaration_list push c_declaration pop ';'1315 | KR_parameter_list push c_declaration pop ';' 1288 1316 { $$ = $1->appendList( $3 ); } 1289 1317 ; … … 1305 1333 1306 1334 declaration: // old & new style declarations 1307 c_declaration pop';'1308 | cfa_declaration pop ';'// CFA1309 | static_assert 1335 c_declaration ';' 1336 | cfa_declaration ';' // CFA 1337 | static_assert // C11 1310 1338 ; 1311 1339 … … 1313 1341 STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11 1314 1342 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1343 | STATICASSERT '(' constant_expression ')' ';' // CFA 1344 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); } 1315 1345 1316 1346 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 1357 1387 cfa_function_declaration: // CFA 1358 1388 cfa_function_specifier 1359 { $$ = $1; }1360 1389 | type_qualifier_list cfa_function_specifier 1361 1390 { $$ = $2->addQualifiers( $1 ); } … … 1364 1393 | declaration_qualifier_list type_qualifier_list cfa_function_specifier 1365 1394 { $$ = $3->addQualifiers( $1 )->addQualifiers( $2 ); } 1366 | cfa_function_declaration ',' identifier_or_type_name '(' cfa_parameter_type_list_opt')'1395 | cfa_function_declaration ',' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' 1367 1396 { 1368 1397 // Append the return type at the start (left-hand-side) to each identifier in the list. 1369 1398 DeclarationNode * ret = new DeclarationNode; 1370 1399 ret->type = maybeClone( $1->type->base ); 1371 $$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $ 5, nullptr ) );1400 $$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $6, nullptr ) ); 1372 1401 } 1373 1402 ; 1374 1403 1375 1404 cfa_function_specifier: // CFA 1376 // '[' ']' identifier_or_type_name '(' push cfa_parameter_ type_list_opt pop ')' // S/R conflict1405 // '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict 1377 1406 // { 1378 1407 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true ); 1379 1408 // } 1380 // '[' ']' identifier '(' push cfa_parameter_ type_list_opt pop ')'1409 // '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')' 1381 1410 // { 1382 1411 // typedefTable.setNextIdentifier( *$5 ); 1383 1412 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1384 1413 // } 1385 // | '[' ']' TYPEDEFname '(' push cfa_parameter_ type_list_opt pop ')'1414 // | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')' 1386 1415 // { 1387 1416 // typedefTable.setNextIdentifier( *$5 ); … … 1391 1420 // identifier_or_type_name must be broken apart because of the sequence: 1392 1421 // 1393 // '[' ']' identifier_or_type_name '(' cfa_parameter_ type_list_opt ')'1422 // '[' ']' identifier_or_type_name '(' cfa_parameter_ellipsis_list_opt ')' 1394 1423 // '[' ']' type_specifier 1395 1424 // 1396 1425 // type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be 1397 1426 // flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name. 1398 cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ type_list_opt pop ')'1427 cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' 1399 1428 // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator). 1400 1429 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); } 1401 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ type_list_opt pop ')'1430 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' 1402 1431 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); } 1403 1432 ; … … 1414 1443 TYPEDEF cfa_variable_specifier 1415 1444 { 1416 typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname );1445 typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname, "1" ); 1417 1446 $$ = $2->addTypedef(); 1418 1447 } 1419 1448 | TYPEDEF cfa_function_specifier 1420 1449 { 1421 typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname );1450 typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname, "2" ); 1422 1451 $$ = $2->addTypedef(); 1423 1452 } 1424 1453 | cfa_typedef_declaration pop ',' push no_attr_identifier 1425 1454 { 1426 typedefTable.addToEnclosingScope( *$5, TYPEDEFname );1455 typedefTable.addToEnclosingScope( *$5, TYPEDEFname, "3" ); 1427 1456 $$ = $1->appendList( $1->cloneType( $5 ) ); 1428 1457 } … … 1435 1464 TYPEDEF type_specifier declarator 1436 1465 { 1437 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname );1466 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" ); 1438 1467 $$ = $3->addType( $2 )->addTypedef(); 1439 1468 } 1440 1469 | typedef_declaration pop ',' push declarator 1441 1470 { 1442 typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname );1471 typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname, "5" ); 1443 1472 $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() ); 1444 1473 } 1445 1474 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 ) 1446 1475 { 1447 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname );1476 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" ); 1448 1477 $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef(); 1449 1478 } 1450 1479 | type_specifier TYPEDEF declarator 1451 1480 { 1452 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname );1481 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" ); 1453 1482 $$ = $3->addType( $1 )->addTypedef(); 1454 1483 } 1455 1484 | type_specifier TYPEDEF type_qualifier_list declarator 1456 1485 { 1457 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname );1486 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" ); 1458 1487 $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 ); 1459 1488 } … … 1582 1611 1583 1612 forall: 1584 FORALL '(' push type_parameter_list pop')' // CFA1585 { $$ = DeclarationNode::newForall( $ 4); }1613 FORALL '(' type_parameter_list ')' // CFA 1614 { $$ = DeclarationNode::newForall( $3 ); } 1586 1615 ; 1587 1616 … … 1765 1794 { $$ = DeclarationNode::newFromTypedef( $1 ); } 1766 1795 | '.' TYPEDEFname 1767 { $$ = DeclarationNode::newFromTypedef( $2 ); } // FIX ME1796 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 1768 1797 | type_name '.' TYPEDEFname 1769 { $$ = DeclarationNode::newFromTypedef( $3 ); } // FIX ME1798 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 1770 1799 | typegen_name 1771 1800 | '.' typegen_name 1772 { $$ = $2; } // FIX ME1801 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 1773 1802 | type_name '.' typegen_name 1774 { $$ = $3; } // FIX ME1803 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 1775 1804 ; 1776 1805 … … 1794 1823 ; 1795 1824 1825 fred: 1826 // empty 1827 { yyy = false; } 1828 ; 1829 1796 1830 aggregate_type: // struct, union 1797 1831 aggregate_key attribute_list_opt '{' field_declaration_list_opt '}' 1798 1832 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); } 1799 | aggregate_key attribute_list_opt no_attr_identifier _or_type_name1800 { 1801 typedefTable.makeTypedef( *$3 );// create typedef1802 if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update1833 | aggregate_key attribute_list_opt no_attr_identifier fred 1834 { 1835 typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); // create typedef 1836 //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update 1803 1837 forall = false; // reset 1804 1838 } 1805 1839 '{' field_declaration_list_opt '}' 1806 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); } 1840 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $7, true )->addQualifiers( $2 ); } 1841 | aggregate_key attribute_list_opt type_name fred 1842 { 1843 typedefTable.makeTypedef( *$3->type->symbolic.name, forall ? TYPEGENname : TYPEDEFname ); // create typedef 1844 //if ( forall ) typedefTable.changeKind( *$3->type->symbolic.name, TYPEGENname ); // possibly update 1845 forall = false; // reset 1846 } 1847 '{' field_declaration_list_opt '}' 1848 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $7, true )->addQualifiers( $2 ); } 1807 1849 | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA 1808 1850 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); } … … 1811 1853 1812 1854 aggregate_type_nobody: // struct, union - {...} 1813 aggregate_key attribute_list_opt no_attr_identifier 1814 { 1815 typedefTable.makeTypedef( *$3 );1816 if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update1855 aggregate_key attribute_list_opt no_attr_identifier fred 1856 { 1857 typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); 1858 //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update 1817 1859 forall = false; // reset 1818 1860 $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 ); 1819 1861 } 1820 | aggregate_key attribute_list_opt TYPEDEFname 1821 { 1822 typedefTable.makeTypedef( *$3 ); 1823 $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 ); 1824 } 1825 | aggregate_key attribute_list_opt typegen_name // CFA 1862 | aggregate_key attribute_list_opt type_name fred 1826 1863 { 1827 1864 // Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is … … 1837 1874 aggregate_key: 1838 1875 STRUCT 1839 { $$ = DeclarationNode::Struct; }1876 { yyy = true; $$ = DeclarationNode::Struct; } 1840 1877 | UNION 1841 { $$ = DeclarationNode::Union; }1878 { yyy = true; $$ = DeclarationNode::Union; } 1842 1879 | EXCEPTION 1843 { $$ = DeclarationNode::Exception; }1880 { yyy = true; $$ = DeclarationNode::Exception; } 1844 1881 | COROUTINE 1845 { $$ = DeclarationNode::Coroutine; }1882 { yyy = true; $$ = DeclarationNode::Coroutine; } 1846 1883 | MONITOR 1847 { $$ = DeclarationNode::Monitor; }1884 { yyy = true; $$ = DeclarationNode::Monitor; } 1848 1885 | THREAD 1849 { $$ = DeclarationNode::Thread; }1886 { yyy = true; $$ = DeclarationNode::Thread; } 1850 1887 ; 1851 1888 … … 1858 1895 1859 1896 field_declaration: 1860 cfa_field_declaring_list ';' // CFA, new style field declaration 1897 type_specifier field_declaring_list ';' 1898 { $$ = distAttr( $1, $2 ); } 1899 | EXTENSION type_specifier field_declaring_list ';' // GCC 1900 { distExt( $3 ); $$ = distAttr( $2, $3 ); } // mark all fields in list 1901 | typedef_declaration ';' // CFA 1902 { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; } 1903 | cfa_field_declaring_list ';' // CFA, new style field declaration 1861 1904 | EXTENSION cfa_field_declaring_list ';' // GCC 1862 { 1863 distExt( $2 ); // mark all fields in list 1864 $$ = $2; 1865 } 1866 | type_specifier field_declaring_list ';' 1867 { 1868 $$ = distAttr( $1, $2 ); } 1869 | EXTENSION type_specifier field_declaring_list ';' // GCC 1870 { 1871 distExt( $3 ); // mark all fields in list 1872 $$ = distAttr( $2, $3 ); 1873 } 1874 | static_assert 1905 { distExt( $2 ); $$ = $2; } // mark all fields in list 1906 | cfa_typedef_declaration ';' // CFA 1907 { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; } 1908 | static_assert // C11 1875 1909 ; 1876 1910 … … 1911 1945 { $$ = nullptr; } 1912 1946 | bit_subrange_size 1913 { $$ = $1; }1914 1947 ; 1915 1948 … … 1922 1955 ENUM attribute_list_opt '{' enumerator_list comma_opt '}' 1923 1956 { $$ = DeclarationNode::newEnum( new string( DeclarationNode::anonymous.newName() ), $4, true )->addQualifiers( $2 ); } 1924 | ENUM attribute_list_opt no_attr_identifier _or_type_name1957 | ENUM attribute_list_opt no_attr_identifier 1925 1958 { typedefTable.makeTypedef( *$3 ); } 1926 1959 '{' enumerator_list comma_opt '}' 1927 1960 { $$ = DeclarationNode::newEnum( $3, $6, true )->addQualifiers( $2 ); } 1961 | ENUM attribute_list_opt type_name 1962 '{' enumerator_list comma_opt '}' 1963 { $$ = DeclarationNode::newEnum( $3->type->symbolic.name, $5, true )->addQualifiers( $2 ); } 1928 1964 | enum_type_nobody 1929 1965 ; 1930 1966 1931 1967 enum_type_nobody: // enum - {...} 1932 ENUM attribute_list_opt no_attr_identifier _or_type_name1968 ENUM attribute_list_opt no_attr_identifier 1933 1969 { 1934 1970 typedefTable.makeTypedef( *$3 ); 1935 1971 $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 ); 1972 } 1973 | ENUM attribute_list_opt type_name 1974 { 1975 typedefTable.makeTypedef( *$3->type->symbolic.name ); 1976 $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 ); 1936 1977 } 1937 1978 ; … … 1951 1992 ; 1952 1993 1953 cfa_parameter_ type_list_opt: // CFA, abstract + real1994 cfa_parameter_ellipsis_list_opt: // CFA, abstract + real 1954 1995 // empty 1955 1996 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } … … 2084 2125 { $$ = $2; } 2085 2126 | '=' VOID 2086 { $$ = n ullptr; }2127 { $$ = new InitializerNode( true ); } 2087 2128 | ATassign initializer 2088 2129 { $$ = $2->set_maybeConstructed( false ); } … … 2161 2202 type_parameter_list: // CFA 2162 2203 type_parameter 2163 { $$ = $1; }2164 2204 | type_parameter_list ',' type_parameter 2165 2205 { $$ = $1->appendList( $3 ); } … … 2175 2215 type_parameter: // CFA 2176 2216 type_class no_attr_identifier_or_type_name 2177 { typedefTable.addTo EnclosingScope( *$2, TYPEDEFname); }2217 { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); } 2178 2218 type_initializer_opt assertion_list_opt 2179 2219 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); } … … 2209 2249 '|' no_attr_identifier_or_type_name '(' type_list ')' 2210 2250 { $$ = DeclarationNode::newTraitUse( $2, $4 ); } 2211 | '|' '{' push trait_declaration_list '}'2251 | '|' '{' push trait_declaration_list pop '}' 2212 2252 { $$ = $4; } 2213 | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list'}' '(' type_list ')'2214 { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }2253 // | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}' '(' type_list ')' 2254 // { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; } 2215 2255 ; 2216 2256 … … 2244 2284 no_attr_identifier_or_type_name 2245 2285 { 2246 typedefTable.addToEnclosingScope( *$1, TYPEDEFname );2286 typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" ); 2247 2287 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 2248 2288 } 2249 | no_attr_identifier_or_type_name '(' push type_parameter_list pop')'2250 { 2251 typedefTable.addToEnclosingScope( *$1, TYPEGENname );2252 $$ = DeclarationNode::newTypeDecl( $1, $ 4);2289 | no_attr_identifier_or_type_name '(' type_parameter_list ')' 2290 { 2291 typedefTable.addToEnclosingScope( *$1, TYPEGENname, "11" ); 2292 $$ = DeclarationNode::newTypeDecl( $1, $3 ); 2253 2293 } 2254 2294 ; 2255 2295 2256 2296 trait_specifier: // CFA 2257 TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop')' '{' '}'2258 { $$ = DeclarationNode::newTrait( $2, $ 5, 0 ); }2259 | TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' push trait_declaration_list'}'2260 { $$ = DeclarationNode::newTrait( $2, $ 5, $10); }2297 TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' '}' 2298 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); } 2299 | TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 2300 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 2261 2301 ; 2262 2302 2263 2303 trait_declaration_list: // CFA 2264 2304 trait_declaration 2265 | trait_declaration_list p ush trait_declaration2266 { $$ = $1->appendList( $ 3); }2305 | trait_declaration_list pop push trait_declaration 2306 { $$ = $1->appendList( $4 ); } 2267 2307 ; 2268 2308 2269 2309 trait_declaration: // CFA 2270 cfa_trait_declaring_list pop';'2271 | trait_declaring_list pop';'2310 cfa_trait_declaring_list ';' 2311 | trait_declaring_list ';' 2272 2312 ; 2273 2313 … … 2289 2329 2290 2330 translation_unit: 2291 // empty 2292 {} // empty input file 2331 // empty, input file 2293 2332 | external_definition_list 2294 2333 { parseTree = parseTree ? parseTree->appendList( $1 ) : $1; } … … 2296 2335 2297 2336 external_definition_list: 2298 external_definition 2337 push external_definition pop 2338 { $$ = $2; } 2299 2339 | external_definition_list 2300 2340 { forall = xxx; } 2301 push external_definition 2341 push external_definition pop 2302 2342 { $$ = $1 ? $1->appendList( $4 ) : $4; } 2303 2343 ; … … 2309 2349 ; 2310 2350 2351 up: 2352 { typedefTable.up(); } 2353 ; 2354 2355 down: 2356 { typedefTable.down(); } 2357 ; 2358 2311 2359 external_definition: 2312 2360 declaration 2313 2361 | external_function_definition 2362 | EXTENSION external_definition // GCC, multiple __extension__ allowed, meaning unknown 2363 { 2364 distExt( $2 ); // mark all fields in list 2365 $$ = $2; 2366 } 2314 2367 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 2315 2368 { … … 2321 2374 linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 ); 2322 2375 } 2323 '{' external_definition_list_opt'}'2376 '{' up external_definition_list_opt down '}' 2324 2377 { 2325 2378 linkage = linkageStack.top(); 2326 2379 linkageStack.pop(); 2327 $$ = $5; 2328 } 2329 | EXTENSION external_definition // GCC, multiple __extension__ allowed, meaning unknown 2330 { 2331 distExt( $2 ); // mark all fields in list 2332 $$ = $2; 2380 $$ = $6; 2333 2381 } 2334 2382 | type_qualifier_list 2335 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type 2336 push '{' external_definition_list '}' // CFA, namespace 2383 { 2384 if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 2385 if ( $1->type->forall ) xxx = forall = true; // remember generic type 2386 } 2387 '{' up external_definition_list_opt down '}' // CFA, namespace 2337 2388 { 2338 2389 for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { … … 2346 2397 } 2347 2398 | declaration_qualifier_list 2348 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type 2349 push '{' external_definition_list '}' // CFA, namespace 2399 { 2400 if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 2401 if ( $1->type->forall ) xxx = forall = true; // remember generic type 2402 } 2403 '{' up external_definition_list_opt down '}' // CFA, namespace 2350 2404 { 2351 2405 for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { … … 2360 2414 | declaration_qualifier_list type_qualifier_list 2361 2415 { 2362 // forall must be in the type_qualifier_list2363 if ( $2->type->forall ) xxx = forall = true; // remember generic type2364 } 2365 push '{' external_definition_list '}'// CFA, namespace2416 if ( ($1->type && $1->type->qualifiers.val) || $2->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 2417 if ( ($1->type && $1->type->forall) || $2->type->forall ) xxx = forall = true; // remember generic type 2418 } 2419 '{' up external_definition_list_opt down '}' // CFA, namespace 2366 2420 { 2367 2421 for ( DeclarationNode * iter = $6; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { … … 2387 2441 | function_declarator compound_statement 2388 2442 { $$ = $1->addFunctionBody( $2 ); } 2389 | KR_function_declarator KR_ declaration_list_opt compound_statement2443 | KR_function_declarator KR_parameter_list_opt compound_statement 2390 2444 { $$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 ); } 2391 2445 ; … … 2427 2481 2428 2482 // Old-style K&R function definition, OBSOLESCENT (see 4) 2429 | declaration_specifier KR_function_declarator KR_ declaration_list_opt with_clause_opt compound_statement2483 | declaration_specifier KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement 2430 2484 { 2431 2485 rebindForall( $1, $2 ); … … 2433 2487 } 2434 2488 // handles default int return type, OBSOLESCENT (see 1) 2435 | type_qualifier_list KR_function_declarator KR_ declaration_list_opt with_clause_opt compound_statement2489 | type_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement 2436 2490 { $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); } 2437 2491 // handles default int return type, OBSOLESCENT (see 1) 2438 | declaration_qualifier_list KR_function_declarator KR_ declaration_list_opt with_clause_opt compound_statement2492 | declaration_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement 2439 2493 { $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); } 2440 2494 // handles default int return type, OBSOLESCENT (see 1) 2441 | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_ declaration_list_opt with_clause_opt compound_statement2495 | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement 2442 2496 { $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 ); } 2443 2497 ; … … 2684 2738 typedef 2685 2739 // hide type name in enclosing scope by variable name 2686 { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER ); }2740 { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" ); } 2687 2741 | '(' paren_type ')' 2688 2742 { $$ = $2; } … … 2974 3028 '[' ']' 2975 3029 { $$ = DeclarationNode::newArray( 0, 0, false ); } 2976 // multi_array_dimension handles the '[' '*' ']' case3030 // multi_array_dimension handles the '[' '*' ']' case 2977 3031 | '[' push type_qualifier_list '*' pop ']' // remaining C99 2978 3032 { $$ = DeclarationNode::newVarArray( $3 ); } 2979 3033 | '[' push type_qualifier_list pop ']' 2980 3034 { $$ = DeclarationNode::newArray( 0, $3, false ); } 2981 // multi_array_dimension handles the '[' assignment_expression ']' case3035 // multi_array_dimension handles the '[' assignment_expression ']' case 2982 3036 | '[' push type_qualifier_list assignment_expression pop ']' 2983 3037 { $$ = DeclarationNode::newArray( $4, $3, false ); } … … 3115 3169 // 3116 3170 // cfa_abstract_tuple identifier_or_type_name 3117 // '[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_ type_list_opt ')'3171 // '[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_ellipsis_list_opt ')' 3118 3172 // 3119 3173 // since a function return type can be syntactically identical to a tuple type: … … 3174 3228 '[' push cfa_abstract_parameter_list pop ']' 3175 3229 { $$ = DeclarationNode::newTuple( $3 ); } 3230 | '[' push type_specifier_nobody ELLIPSIS pop ']' 3231 { SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; } 3232 | '[' push type_specifier_nobody ELLIPSIS constant_expression pop ']' 3233 { SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; } 3176 3234 ; 3177 3235 3178 3236 cfa_abstract_function: // CFA 3179 // '[' ']' '(' cfa_parameter_ type_list_opt ')'3237 // '[' ']' '(' cfa_parameter_ellipsis_list_opt ')' 3180 3238 // { $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); } 3181 cfa_abstract_tuple '(' push cfa_parameter_ type_list_opt pop ')'3239 cfa_abstract_tuple '(' push cfa_parameter_ellipsis_list_opt pop ')' 3182 3240 { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); } 3183 | cfa_function_return '(' push cfa_parameter_ type_list_opt pop ')'3241 | cfa_function_return '(' push cfa_parameter_ellipsis_list_opt pop ')' 3184 3242 { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); } 3185 3243 ; … … 3212 3270 3213 3271 %% 3272 3214 3273 // ----end of grammar---- 3215 3274
Note: See TracChangeset
for help on using the changeset viewer.