- Timestamp:
- Apr 5, 2019, 9:26:53 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
asp3_tinet_ecnl_rx/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb
r359 r374 4 4 # Generator for TOPPERS Embedded Component System 5 5 # 6 # Copyright (C) 2008-201 4by TOPPERS Project6 # Copyright (C) 2008-2018 by TOPPERS Project 7 7 #-- 8 # 上記著作権者は,以下の(1) ~(4)の条件を満たす場合に限り,本ソフトウェ8 # 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ 9 9 # ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 10 10 # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. … … 48 48 # argument_expression_list(関数引数), assignment_expression(代入)がない 49 49 # 式の result は、すべて配列で第一要素が識別シンボル、第二要素以下が引数 50 # 51 # 2019/3/28 長島 下記のC99の構文に近づくよう変更 52 #(読めないヘッダーファイルがあったため) 53 # http://www.quut.com/c/ANSI-C-grammar-y-1999.html 54 # 元々のコメントと合わなくなっています 50 55 51 56 primary_expression 52 57 : namespace_identifier 53 58 { result = [ :IDENTIFIER, val[0] ] } #1ok 54 59 # : IDENTIFIER # mikan namespace への対応 … … 58 63 # | FALSE 59 64 # { result = [ :BOOL_CONSTANT, false ] } 60 65 | INTEGER_CONSTANT 61 66 { result = [ :INTEGER_CONSTANT, val[0] ] } 62 67 | FLOATING_CONSTANT 63 68 { result = [ :FLOATING_CONSTANT, val[0] ] } 64 69 | OCTAL_CONSTANT 65 70 { result = [ :OCTAL_CONSTANT, val[0] ] } 66 71 | HEX_CONSTANT 67 72 { result = [ :HEX_CONSTANT, val[0] ] } 68 73 | CHARACTER_LITERAL 69 74 { result = [ :CHARACTER_LITERAL, val[0] ] } 70 75 | string_literal_list 71 76 { result = [ :STRING_LITERAL_LIST, val[0] ] } 72 77 | '(' expression ')' 73 78 { result = [ :PARENTHESES, val[1].get_elements ] } 74 79 75 80 string_literal_list 76 81 : STRING_LITERAL 77 82 { result = [val[0]] } 78 83 | string_literal_list STRING_LITERAL 79 84 { result << val[1] } 80 85 81 86 # 関数呼び出しと後置インクリメント、デクリメント演算子がない 82 87 postfix_expression 83 : primary_expression 84 | primary_expression '(' argument_list ')' 85 | primary_expression type_qualifier '(' argument_list ')' # intended __asm volatile ( " MNEMONIC OPERAND" ); 86 | postfix_expression '[' expression ']' 88 : primary_expression 89 | postfix_expression '[' expression ']' 87 90 { result = [ :OP_SUBSC, val[0], val[2] ] } 88 | postfix_expression '.' IDENTIFIER 91 | postfix_expression '(' ')' 92 | postfix_expression '(' argument_expression_list ')' 93 | postfix_expression type_qualifier '(' argument_expression_list ')' # intended __asm volatile ( " MNEMONIC OPERAND" ); 94 | postfix_expression '.' IDENTIFIER 89 95 { result = [ :OP_DOT, val[0], val[2] ] } 90 96 | postfix_expression '->' IDENTIFIER 91 97 { result = [ :OP_REF, val[0], val[2] ] } 92 | postfix_expression '++' { result = val[0] } # ++, -- は無視する 93 | postfix_expression '--' { result = val[0] } 94 95 argument_list 96 : 97 | expression 98 | argument_list ',' expression 98 | postfix_expression '++' { result = val[0] } # ++, -- は無視する 99 | postfix_expression '--' { result = val[0] } 100 | '(' type_name ')' '{' initializer_list '}' 101 | '(' type_name ')' '{' initializer_list ',' '}' 102 103 argument_expression_list 104 : assignment_expression 105 | argument_expression_list ',' assignment_expression 99 106 100 107 101 108 # 前置インクリメント、デクリメント演算子がない 102 109 unary_expression 103 104 110 : postfix_expression 111 | unary_operator cast_expression 105 112 { result = [ val[0], val[1] ] } 106 113 | SIZEOF unary_expression 107 114 { result = [ :OP_SIZEOF_EXPR, val[1] ] } 108 115 | SIZEOF '(' type_name ')' 109 116 { result = [ :OP_SIZEOF_TYPE, val[1] ] } 110 117 | '++' unary_expression { result = val[1] } # ++, -- は無視する … … 112 119 113 120 unary_operator 114 115 116 117 118 119 121 : '&' { result = :OP_U_AMP } 122 | '*' { result = :OP_U_ASTER } 123 | '+' { result = :OP_U_PLUS } 124 | '-' { result = :OP_U_MINUS } 125 | '~' { result = :OP_U_TILDE } 126 | '!' { result = :OP_U_EXCLAM } 120 127 121 128 cast_expression 122 123 129 : unary_expression 130 | '(' type_name ')' cast_expression 124 131 { result = [ :CAST, val[1], val[3] ] } 125 132 126 133 multiplicative_expression 127 128 134 : cast_expression 135 | multiplicative_expression '*' cast_expression 129 136 { result = [ :OP_MULT, val[0], val[2] ] } 130 137 | multiplicative_expression '/' cast_expression 131 138 { result = [ :OP_DIV, val[0], val[2] ] } 132 139 | multiplicative_expression '%' cast_expression 133 140 { result = [ :OP_REMAIN, val[0], val[2] ] } 134 141 135 142 additive_expression 136 137 143 : multiplicative_expression 144 | additive_expression '+' multiplicative_expression 138 145 { result = [ :OP_ADD, val[0], val[2] ] } 139 146 | additive_expression '-' multiplicative_expression 140 147 { result = [ :OP_SUB, val[0], val[2] ] } 141 148 142 149 shift_expression 143 144 150 : additive_expression 151 | shift_expression '<<' additive_expression 145 152 { result = [ :OP_LSFT, val[0], val[2] ] } 146 153 | shift_expression '>>' additive_expression 147 154 { result = [ :OP_RSFT, val[0], val[2] ] } 148 155 149 156 relational_expression 150 151 157 : shift_expression 158 | relational_expression '<' shift_expression 152 159 { result = [ :OP_LT, val[0], val[2] ] } 153 160 | relational_expression '>' shift_expression 154 161 { result = [ :OP_GT, val[0], val[2] ] } 155 162 | relational_expression '<=' shift_expression 156 163 { result = [ :OP_LE, val[0], val[2] ] } 157 164 | relational_expression '>=' shift_expression 158 165 { result = [ :OP_GE, val[0], val[2] ] } 159 166 160 167 equality_expression 161 162 168 : relational_expression 169 | equality_expression '==' relational_expression 163 170 { result = [ :OP_EQ, val[0], val[2] ] } 164 171 | equality_expression '!=' relational_expression 165 172 { result = [ :OP_NE, val[0], val[2] ] } 166 173 167 174 and_expression 168 169 175 : equality_expression 176 | and_expression '&' equality_expression 170 177 { result = [ :OP_AND, val[0], val[2] ] } 171 178 172 179 exclusive_or_expression 173 174 180 : and_expression 181 | exclusive_or_expression '^' and_expression 175 182 { result = [ :OP_EOR, val[0], val[2] ] } 176 183 177 184 inclusive_or_expression 178 179 185 : exclusive_or_expression 186 | inclusive_or_expression '|' exclusive_or_expression 180 187 { result = [ :OP_OR, val[0], val[2] ] } 181 188 182 189 logical_and_expression 183 184 190 : inclusive_or_expression 191 | logical_and_expression '&&' inclusive_or_expression 185 192 { result = [ :OP_LAND, val[0], val[2] ] } 186 193 187 194 logical_or_expression 188 189 195 : logical_and_expression 196 | logical_or_expression '||' logical_and_expression 190 197 { result = [ :OP_LOR, val[0], val[2] ] } 191 198 192 199 conditional_expression 193 194 200 : logical_or_expression 201 | logical_or_expression '?' expression ':' conditional_expression 195 202 { result = [ :OP_CEX, val[0], val[2].get_elements, val[4] ] } 196 203 197 198 # コンマ演算子が使えない 204 assignment_expression 205 : conditional_expression 206 | unary_expression assignment_operator assignment_expression 207 208 assignment_operator 209 : '=' 210 | '+=' 211 | '-=' 212 | '*=' 213 | '/=' 214 | '%=' 215 | '<<=' 216 | '>>=' 217 | '&=' 218 | '|=' 219 | '^=' 220 199 221 expression 200 : conditional_expression222 : assignment_expression 201 223 { 202 224 result = Expression.new( val[0] ) 203 225 # result.print 204 226 } 227 | expression ',' assignment_expression 228 { 229 result = Expression.new( val[2] ) # ',' の後ろを採用 230 } 205 231 206 232 constant_expression 207 233 : conditional_expression 208 234 { 209 235 result = Expression.new( val[0] ) … … 218 244 } 219 245 220 221 222 246 # Types 223 247 ########################## 宣言 ########################## … … 227 251 # K&Rとの違い: storage classが指定できない、型が省略できない 228 252 declaration 229 230 # : type_specifier_qualifier_list init_declarator_list ';'253 : declaration_specifiers init_declarator_list ';' 254 # : specifier_qualifier_list init_declarator_list ';' 231 255 232 256 # declaration_specifiersは関数のパラメータで使われるが、 233 # type_specifier_qualifier_listで十分かもしれない257 # specifier_qualifier_listで十分かもしれない 234 258 235 259 declaration_specifiers 236 : storage_class 260 : storage_class_specifier 237 261 { 238 262 result = CIntType.new( -3 ) # storage class は無視 239 263 } 240 | type_specifier 241 | type_qualifier 264 | storage_class_specifier declaration_specifiers 265 { 266 result = val[1] # storage class は無視 267 } 268 | type_specifier 269 | type_specifier declaration_specifiers 270 { 271 result = val[1].merge val[0] 272 } 273 | type_qualifier 242 274 { 243 275 result = CIntType.new( -3 ) 244 276 result.set_qualifier val[0] 245 277 } 246 | storage_class declaration_specifiers 247 { 248 result = val[1] # storage class は無視 249 } 250 | type_specifier declaration_specifiers 251 { 252 result = val[1].merge val[0] 253 } 254 | type_qualifier declaration_specifiers 278 | type_qualifier declaration_specifiers 255 279 { 256 280 val[1].set_qualifier val[0] 257 result = val[1] 258 } 259 281 result = val[1] 282 } 283 | function_specifier 284 | function_specifier declaration_specifiers 260 285 261 286 init_declarator_list 262 287 : init_declarator 263 288 { result = [val[0]] } 264 289 | init_declarator_list ',' init_declarator 265 290 { result << val[2] } 266 291 267 292 init_declarator 268 269 293 : declarator 294 | declarator '=' initializer 270 295 { val[0].set_initializer( val[2] ) } 271 296 297 storage_class_specifier 298 : EXTERN 299 | STATIC 300 | AUTO 301 | REGISTER 302 272 303 type_specifier 273 : VOID { set_no_type_name true; result = CVoidType.new } 274 | FLOAT { set_no_type_name true; result = CFloatType.new(-32) } 275 | DOUBLE { set_no_type_name true; result = CFloatType.new(-64) } 276 | BOOL { set_no_type_name true; result = CBoolType.new } 277 | struct_specifier { set_no_type_name true; result = val[0] } # set_no_type_name true は struct_tag でも呼ばれる 278 | union_specifier { set_no_type_name true; result = CVoidType.new } # void が宣言されたとする 279 | enum_specifier { set_no_type_name true; result = CVoidType.new } # void が宣言されたとする 280 | TYPE_NAME { set_no_type_name true; result = CDefinedType.new( val[0].val ) } 281 282 | CHAR { set_no_type_name true; result = CIntType.new(-11 ) } 283 | SHORT { set_no_type_name true; result = CIntType.new( -2 ) } 284 | INT { set_no_type_name true; result = CIntType.new( -3 ) } 285 | LONG { set_no_type_name true; result = CIntType.new( -4 ) } 286 | SIGNED 304 : VOID 305 { set_no_type_name true; result = CVoidType.new } 306 | CHAR 307 { set_no_type_name true; result = CIntType.new(-11 ) } 308 | SHORT 309 { set_no_type_name true; result = CIntType.new( -2 ) } 310 | INT 311 { set_no_type_name true; result = CIntType.new( -3 ) } 312 | LONG 313 { set_no_type_name true; result = CIntType.new( -4 ) } 314 | FLOAT 315 { set_no_type_name true; result = CFloatType.new(-32) } 316 | DOUBLE 317 { set_no_type_name true; result = CFloatType.new(-64) } 318 | SIGNED 287 319 { 288 320 set_no_type_name true … … 290 322 result.set_sign :SIGNED 291 323 } 292 324 | UNSIGNED 293 325 { 294 326 set_no_type_name true … … 296 328 result.set_sign :UNSIGNED 297 329 } 330 | BOOL 331 { set_no_type_name true; result = CBoolType.new } 332 | struct_specifier 333 { set_no_type_name true; result = val[0] } # set_no_type_name true は struct_tag でも呼ばれる 334 | union_specifier 335 { set_no_type_name true; result = CVoidType.new } # void が宣言されたとする 336 | enum_specifier 337 { set_no_type_name true; result = CVoidType.new } # void が宣言されたとする 338 | TYPE_NAME 339 { set_no_type_name true; result = CDefinedType.new( val[0].val ) } 298 340 299 341 # mikan K&Rのstruct_or_union_specifierに相当するが、unionは使えない, bit field にも対応しない 300 342 struct_specifier # mikan 301 343 # : STRUCT struct_tag '{' 302 344 : struct_term struct_tag '{' 303 345 { StructType.set_define( true ) } 304 346 struct_declaration_list '}' 305 347 { 306 348 StructType.end_of_parse … … 308 350 } 309 351 # | STRUCT 310 352 | struct_term 311 353 { 312 354 result = CStructType.new() 313 355 StructType.set_define( true ) 314 356 } 315 357 '{' struct_declaration_list '}' 316 358 { 317 359 StructType.end_of_parse … … 319 361 } 320 362 # | STRUCT struct_tag # mikan struct_tag は namespace 対応が必要 321 363 | struct_term struct_tag # mikan struct_tag は namespace 対応が必要 322 364 { 323 365 StructType.set_define( false ) … … 327 369 328 370 struct_term 329 371 : STRUCT { set_no_type_name true } 330 372 331 373 struct_declaration_list 332 333 374 : struct_declaration 375 | struct_declaration_list struct_declaration 334 376 335 377 struct_tag: 336 378 IDENTIFIER 337 379 { 338 380 result = CStructType.new( val[0].val ) … … 342 384 # ポインタ修飾子を追加 343 385 struct_declaration 344 345 # : type_specifier_qualifier_list struct_declarator_list ';'386 : declaration_specifiers struct_declarator_list ';' 387 # : specifier_qualifier_list struct_declarator_list ';' 346 388 { 347 389 val[1].each { |i| # i: Decl … … 353 395 result = val[1] 354 396 } 355 | union_specifier ';' # 無名 356 | struct_specifier ';' # 無名 397 # ビットフィールドを読み飛ばし 398 | declaration_specifiers struct_declarator_list ':' constant_expression ';' 399 { 400 val[1].each { |i| # i: Decl 401 i.set_type( val[0] ) 402 i.set_kind( :MEMBER ) 403 i.check 404 CStructType.new_member( i ) 405 } 406 result = val[1] 407 } 408 | union_specifier ';' # 無名 409 | struct_specifier ';' # 無名 357 410 358 411 … … 360 413 # K&Rのspecifier_qualifier_listと同じ 361 414 # 名前がまぎらわしかったのでtype_を付けた 362 type_specifier_qualifier_list 363 : type_specifier 364 | type_specifier type_specifier_qualifier_list 415 specifier_qualifier_list 416 : type_specifier specifier_qualifier_list 365 417 { 366 418 result = val[1].merge val[0] 367 419 } 368 | type_qualifier 420 | type_specifier 421 | type_qualifier specifier_qualifier_list 422 { 423 val[1].set_qualifier val[0] 424 result = val[1] 425 } 426 | type_qualifier 369 427 { 370 428 result = CIntType.new( -3 ) 371 429 result.set_qualifier val[0] 372 430 } 373 | type_qualifier type_specifier_qualifier_list374 {375 val[1].set_qualifier val[0]376 result = val[1]377 }378 431 379 432 struct_declarator_list 380 433 : struct_declarator 381 434 { result = [ val[0] ] } 382 435 | struct_declarator_list ',' struct_declarator 383 436 { result << val[2] } 384 437 385 438 # ビットフィールドは使えない 386 439 struct_declarator 387 388 389 440 : declarator 441 # | ':' constant_expression 442 # | declarator ':' constant_expression 390 443 391 444 union_specifier … … 393 446 # | UNION '{' union_declaration_list '}' 394 447 # | UNION union_tag # mikan struct_tag は namespace 対応が必要 395 396 397 448 : union_term union_tag '{' union_declaration_list '}' 449 | union_term '{' union_declaration_list '}' 450 | union_term union_tag # mikan struct_tag は namespace 対応が必要 398 451 399 452 union_term 400 453 : UNION { set_no_type_name true } 401 454 402 455 union_declaration_list 403 404 456 : union_declaration 457 | union_declaration_list union_declaration 405 458 406 459 union_tag: … … 408 461 409 462 union_declaration 410 463 : declaration_specifiers union_declarator_list ';' 411 464 | union_specifier ';' # 無名 412 465 | struct_specifier ';' # 無名 413 466 414 467 union_declarator_list 415 : union_declarator 416 | union_declarator_list ',' union_declarator 417 418 # ビットフィールドは使えない 468 : union_declarator 469 | union_declarator_list ',' union_declarator 470 419 471 union_declarator 420 : declarator 421 422 423 424 # enumの種類を追加 425 enum_specifier # mikan 426 : enum_type '{' enumerator_list '}' 427 | enum_type IDENTIFIER '{' enumerator_list '}' 428 | enum_type IDENTIFIER 429 430 enum_type 431 : ENUM { result = CEnumType.new( -1 ) } 432 # | ENUM8 { result = CEnumType.new( 8 ) } 433 # | ENUM16 { result = CEnumType.new( 16 ) } 434 # | ENUM32 { result = CEnumType.new( 32 ) } 435 # | ENUM64 { result = CEnumType.new( 64 ) } 436 # | ENUM128 { result = CEnumType.new( 128 ) } 472 : declarator 473 | ':' constant_expression 474 | declarator ':' constant_expression 475 476 enum_specifier 477 : ENUM '{' enumerator_list '}' 478 | ENUM IDENTIFIER '{' enumerator_list '}' 479 | ENUM '{' enumerator_list ',' '}' 480 | ENUM IDENTIFIER '{' enumerator_list ',' '}' 481 | ENUM IDENTIFIER 482 | ENUM TYPE_NAME '{' enumerator_list '}' 483 | ENUM TYPE_NAME '{' enumerator_list ',' '}' 484 | ENUM TYPE_NAME 437 485 438 486 enumerator_list 439 440 487 : enumerator 488 | enumerator_list ',' enumerator 441 489 442 490 enumerator 443 444 491 : IDENTIFIER 492 | IDENTIFIER '=' constant_expression 445 493 446 494 type_qualifier 447 : CONST { result = :CONST } 448 | VOLATILE { result = :VOLATILE } 495 : CONST 496 { result = :CONST } 497 | RESTRICT 498 | VOLATILE 499 { result = :VOLATILE } 500 501 function_specifier 502 : __INLINE__ 503 | INLINE 504 | __INLINE 505 | CINLINE 449 506 450 507 declarator 451 508 : pointer direct_declarator 452 509 { 453 510 val[1].set_type( val[0] ) 454 511 result = val[1] 455 512 } 456 457 513 | direct_declarator 514 | pointer TYPE_NAME # 関数ポインタの typedef が二重定義の場合 458 515 { 459 516 result = Decl.new( val[1].val ) … … 462 519 463 520 direct_declarator # mikan 464 521 : IDENTIFIER 465 522 { result = Decl.new( val[0].val ) } 466 523 | '(' declarator ')' 467 524 { result = val[1] } 468 525 | direct_declarator '[' constant_expression ']' 469 526 { 470 527 val[0].set_type( CArrayType.new( val[2] ) ) 471 528 result = val[0] 472 529 } 473 530 | direct_declarator '[' ']' 474 531 { 475 532 val[0].set_type( CArrayType.new ) 476 533 result = val[0] 477 534 } 478 535 | direct_declarator '(' parameter_type_list ')' 479 536 { 480 537 # Generator.warning( "W6001 need 'void' for no parameter" ) … … 482 539 result = val[0] 483 540 } 484 485 # | direct_declarator '(' identifier_list ')' # これは何のために必要? 060211 486 | direct_declarator '(' ')' 541 | direct_declarator '(' identifier_list ')' # これは何のために必要? 060211 542 | direct_declarator '(' ')' 487 543 { 488 544 # Generator.warning( "W6002 need 'void' for no parameter" ) … … 492 548 493 549 pointer 494 550 : '*' 495 551 { result = CPtrType.new } 496 | '*' type_qualifier 552 | '*' type_qualifier_list 497 553 { 498 554 result = CPtrType.new 499 555 result.set_qualifier( val[1] ) 500 556 } 501 557 | '*' pointer 502 558 { 503 559 val[1].set_type(CPtrType.new) 504 560 result = val[1] 505 561 } 506 | '*' type_qualifierpointer562 | '*' type_qualifier_list pointer 507 563 { 508 564 ptrtype = CPtrType.new … … 512 568 } 513 569 570 type_qualifier_list 571 : type_qualifier 572 | type_qualifier_list type_qualifier 514 573 515 574 parameter_type_list 516 517 575 : parameter_list 576 | parameter_list ',' '.' '.' '.' 518 577 # mikan 可変長パラメータ, ... の間のスペースが許される(手抜き) 519 578 520 579 parameter_list 521 580 : parameter_declaration 522 581 # { result = ParamList.new( val[0] ) } 523 582 | parameter_list ',' parameter_declaration 524 583 # { 525 584 # val[0].add_param( val[2] ) … … 530 589 # パラメータ修飾子を追加 531 590 parameter_declaration 532 591 : declaration_specifiers declarator 533 592 # { 534 593 # decl = ParamDecl.new( val[1], val[0], [] ) … … 545 604 # result = nil 546 605 # } 547 548 549 550 551 #identifier_list # 060211 不用になった552 #: IDENTIFIER553 #| identifier_list ',' IDENTIFIER606 | declaration_specifiers abstract_declarator # 仮引数なし 607 | declaration_specifiers # 仮引数なし 608 609 610 identifier_list # 060211 不用になった 611 : IDENTIFIER 612 | identifier_list ',' IDENTIFIER 554 613 555 614 type_name 556 : type_specifier_qualifier_list557 | type_specifier_qualifier_list abstract_declarator615 : specifier_qualifier_list 616 | specifier_qualifier_list abstract_declarator 558 617 559 618 abstract_declarator # mikan 560 561 562 619 : pointer 620 | direct_abstract_declarator 621 | pointer direct_abstract_declarator 563 622 564 623 direct_abstract_declarator 565 566 567 | '[' constant_expression ']'568 569 | direct_abstract_declarator '[' constant_expression ']'570 624 : '(' abstract_declarator ')' 625 | '[' ']' 626 | '[' assignment_expression ']' 627 | direct_abstract_declarator '[' ']' 628 | direct_abstract_declarator '[' assignment_expression ']' 629 | '(' ')' 571 630 { 572 631 Generator.warning( "W6003 need 'void' for no parameter" ) 573 632 } 574 575 633 | '(' parameter_type_list ')' 634 | direct_abstract_declarator '(' ')' 576 635 { 577 636 Generator.warning( "W6004 need 'void' for no parameter" ) 578 637 } 579 638 | direct_abstract_declarator '(' parameter_type_list ')' 580 639 581 640 # assignment_expressionをconstant_expressionに変更 582 641 initializer # mikan 583 : constant_expression642 : assignment_expression 584 643 { result = val[0] } 585 644 | '{' initializer_list '}' 586 645 { result = val[1] } 587 646 | '{' initializer_list ',' '}' 588 647 { result = val[1] } 589 | C_EXP '(' STRING_LITERAL ')'648 | C_EXP '(' STRING_LITERAL ')' 590 649 { result = C_EXP.new( val[2] ) } 591 650 592 651 initializer_list 593 652 : initializer 594 653 { 595 654 result = [ val[0] ] 596 655 } 597 656 | initializer_list ',' initializer 598 657 { 599 658 val[0] << val[2] … … 606 665 #トップレベルの構文規則 607 666 C_parser 608 609 667 : 668 | C_parser extension_statement 610 669 611 670 extension_statement 612 :statement613 | EXTENSIONstatement614 615 statement616 617 618 619 620 621 622 671 : cdl_statement 672 | EXTENSION cdl_statement 673 674 cdl_statement 675 : typedef 676 | func_def 677 | enum_specifier ';' 678 | struct_specifier ';' 679 | declaration 680 | ';' 681 | error # エラー回復ポイント 623 682 624 683 typedef 625 : TYPEDEF type_specifier_qualifier_list declarator_list ';'684 : TYPEDEF specifier_qualifier_list declarator_list ';' 626 685 { 627 686 val[2].each{ |i| … … 633 692 634 693 declarator_list 635 694 : declarator 636 695 { result = [ val[0] ] } 637 696 | declarator_list ',' declarator 638 697 { result << val[2] } 639 698 640 699 func_def 641 : declaration_specifiers declarator compoundstatement 642 643 infunc_statement_list 644 : 645 | infunc_statement_list infunc_statement 646 647 infunc_statement 648 : declaration 649 | ifstatement 650 | whilestatement 651 | dowhilestatement 652 | forstatement 653 | switchstatement 654 | labelstatement 655 | compoundstatement 656 | gotostatement 657 | expressionstatement 658 | ';' 700 : declaration_specifiers declarator compound_statement 701 702 statement 703 : labeled_statement 704 | compound_statement 705 | expression_statement 706 | ifstatement 707 | whilestatement 708 | dowhilestatement 709 | forstatement 710 | switchstatement 711 | jump_statement 712 | asm_statement 713 714 labeled_statement 715 : IDENTIFIER ':' statement 716 | CASE constant_expression ':' statement 717 | DEFAULT ':' statement 718 719 compound_statement 720 : '{' '}' 721 | '{' block_item_list '}' 722 723 block_item_list 724 : block_item 725 | block_item_list block_item 726 727 block_item 728 : declaration 729 | statement 730 731 expression_statement 732 : ';' 733 | expression ';' 659 734 660 735 ifstatement 661 : IF '(' expression ')' infunc_statement 662 | IF '(' expression ')' infunc_statement ELSE infunc_statement 736 : IF '(' expression ')' statement 737 | IF '(' expression ')' statement ELSE statement 738 739 switchstatement 740 : SWITCH '(' expression ')' compound_statement 663 741 664 742 whilestatement 665 : WHILE '(' expression ')' infunc_statement743 : WHILE '(' expression ')' statement 666 744 667 745 dowhilestatement 668 : DO infunc_statement WHILE '(' expression ')' ';'746 : DO statement WHILE '(' expression ')' ';' 669 747 670 748 forstatement 671 : FOR '(' expression ';' expression ';' expression ')' infunc_statement 672 673 switchstatement 674 : SWITCH '(' expression ')' infunc_statment 675 676 labelstatement 677 : IDENTIFIER ':' infunc_statement 678 | CASE constant_expression ':' infunc_statement 679 | DEFAULT ':' infunc_statement 680 681 compoundstatement 682 : '{' infunc_statement_list '}' 683 684 gotostatement 685 : GOTO IDENTIFIER ';' 686 | CONTINUE ';' 687 | BREAK ';' 688 | RETURN expression ';' 689 | RETURN ';' 690 691 expressionstatement 692 : expression ';' 693 | unary_expression assignment_operator expression ';' 694 695 assignment_operator 696 : '=' 697 | '+=' 698 | '-=' 699 | '*=' 700 | '/=' 701 | '%=' 702 | '<<=' 703 | '>>=' 704 | '&=' 705 | '|=' 706 | '^=' 707 708 storage_class 709 : __INLINE__ 710 | INLINE 711 | __INLINE 712 | CINLINE 713 | EXTERN 714 | STATIC 715 | AUTO 716 | REGISTER 749 : FOR '(' expression_statement expression_statement ')' statement 750 | FOR '(' expression_statement expression_statement expression ')' statement 751 | FOR '(' declaration expression_statement ')' statement 752 | FOR '(' declaration expression_statement expression ')' statement 753 754 jump_statement 755 : GOTO IDENTIFIER ';' 756 | CONTINUE ';' 757 | BREAK ';' 758 | RETURN ';' 759 | RETURN expression ';' 717 760 718 761 namespace_identifier 719 720 721 762 : IDENTIFIER { result = NamespacePath.new( val[0].val, false ) } 763 | '::' IDENTIFIER { result = NamespacePath.new( val[1].val, true ) } 764 | namespace_identifier '::' IDENTIFIER 722 765 { result = val[0].append!( val[2].val ) } 723 766 767 asm_statement 768 : _ASM { 769 while true 770 # ';' が表れるまで、トークンを読み飛ばす。 771 # gcc の構文拡張に対応すべきだが、単純な実装として、';' まで読み飛ばす。 772 # トークン単位で読み飛ばしているので、文字列やコメント内の ';' は対象にならない。 773 token = next_token 774 if token[1].val == ";" 775 break 776 end 777 # p "skip: #{token[1].val}" 778 end 779 } 780 724 781 end 725 782 726 783 ---- inner 727 784 728 RESERVED = { 729 # keyword 730 'typedef' => :TYPEDEF, 731 'struct' => :STRUCT, 732 'union' => :UNION, 733 'sizeof' => :SIZEOF, 734 'throw' => :THROW, 735 736 # specifier 737 # types 738 'void' => :VOID, 739 'char' => :CHAR, 740 'short' => :SHORT, 741 742 'volatile'=> :VOLATILE, 743 'const' => :CONST, 744 'extern' => :EXTERN, 745 746 'long' => :LONG, 747 'float' => :FLOAT, 748 'double' => :DOUBLE, 749 'signed' => :SIGNED, 750 'unsigned'=> :UNSIGNED, 751 752 'int' => :INT, 753 'enum' => :ENUM, 754 755 'if' => :IF, 756 'else' => :ELSE, 757 'while' => :WHILE, 758 'do' => :DO, 759 'for' => :FOR, 760 'case' => :CASE, 761 'default' => :DEFAULT, 762 'goto' => :GOTO, 763 'continue' => :CONTINUE, 764 'break' => :BREAK, 765 'return' => :RETURN, 766 '__inline__' => :__INLINE__, 767 'inline' => :INLINE, 768 '__inline' => :__INLINE, 769 'Inline' => :CINLINE, # inline starting with Capital letter 770 'static' => :STATIC, 771 'register' => :REGISTER, 772 'auto' => :AUTO, 773 '__extension__' => :EXTENSION, 774 775 } 776 777 @@generator_nest = -1 778 @@generator_stack = [] 779 @@current_locale = [] 780 781 def finalize 782 783 # mikan Namespace.pop 784 Celltype.pop 785 Cell.pop 786 CompositeCelltype.pop 787 Region.pop 788 789 end 790 791 def set_plugin( plugin ) 792 @plugin = plugin 793 end 794 795 def self.get_plugin 796 @@generator_stack[@@generator_nest].get_plugin 797 end 798 799 def get_plugin 800 @plugin 801 end 802 803 def parse(files) 804 805 # mikan Namespace.push 806 Celltype.push 807 Cell.push 808 CompositeCelltype.push 809 Region.push 810 811 @@generator_nest += 1 812 @@generator_stack[@@generator_nest] = self 813 @b_no_type_name = false 814 815 begin 816 817 @q = [] 818 comment = false 819 820 # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策 821 TECS_LANG::set_kcode_binary 822 823 # 800U, 0xffLL など (整数リテラルに共通の修飾子) 824 integer_qualifier = "([Uu][Ll][Ll]|[Uu][Ll]|[Uu]|[Ll][Ll]|[Ll])?" 825 826 files.each {|file| 827 lineno = 1 828 begin 829 #2.0 IO.foreach(file) {|line| 830 TECSIO.foreach(file) {|line| 831 col = 1 832 line.rstrip! 833 834 until line.empty? 835 836 if comment 837 case line 838 # コメント終了 839 when /\A\*\// 840 comment = false 841 when /\A./ 842 ; 843 end 844 else 845 case line 846 # 空白、プリプロセスディレクティブ 847 when /\A\s+/ 848 ; 849 # 識別子 850 when /\A[a-zA-Z_]\w*/ 851 word = $& 852 @q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)] 853 # 16 進数定数 854 when /\A0x[0-9A-Fa-f]+#{integer_qualifier}/ 855 @q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)] 856 # 8 進数定数 857 when /\A0[0-7]+#{integer_qualifier}/ 858 @q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)] 859 # 浮動小数定数 860 when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/ 861 @q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)] 862 # 整数定数 863 when /\A\d+#{integer_qualifier}/ 864 # when /\A\d+/ 865 @q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)] 866 # 文字 867 when /\A'(?:[^'\\]|\\.)'/ 868 @q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)] 869 # 文字列 870 # "#include #include #include \"../systask/logtask.cfg\" 最後の " 忘れ)で無限ループ 871 # when /\A"(?:[^"\\]+|\\.)*"/ 872 when /\A"(?:[^"\\]|\\.)*"/ # これはうまく行くようだ 873 @q << [:STRING_LITERAL, Token.new($&, file, lineno, col)] 874 # 行コメント 875 when /\A\/\/.*$/ 876 # 読み飛ばすだけ 877 # コメント開始 878 when /\A\/\*/ 879 comment = true 880 when /\A>>=/, /\A<<=/, /\A>>/, /\A<</ 881 @q << [$&, Token.new($&, file, lineno, col)] 882 when /\A\+=/, /\A\-=/, /\A\*=/, /\A\/=/, /\A%=/, /\A&=/, /\A\|=/, /\A\^=/ 883 @q << [$&, Token.new($&, file, lineno, col)] 884 when /\A::/, /\A==/, /\A!=/, /\A>=/, /\A<=/, /\A\->/, /\A\+\+/, /\A\-\-/ 885 @q << [$&, Token.new($&, file, lineno, col)] 886 when /\A./ 887 @q << [$&, Token.new($&, file, lineno, col)] 888 else 889 raise 890 end 891 end 892 893 line = $' 894 col += $&.length 895 end 896 897 lineno += 1 898 } 899 900 rescue => evar 901 Generator.error( "B1002 while open or reading \'$1\'" , file ) 902 print_exception( evar ) 903 end 904 } 905 906 # 終了の印 907 @q << nil 908 909 @yydebug = true 910 do_parse 911 912 ensure 913 @@generator_nest -= 1 914 TECS_LANG::reset_kcode 915 end 916 917 end 918 919 920 def next_token 921 token = @q.shift 922 923 if token then 924 @@current_locale[@@generator_nest] = token[1].locale 925 926 case token[1].val 927 when ";", ":", ",", "(", ")", "{", "}" 928 set_no_type_name false 929 when ".", "->" 930 set_no_type_name true 931 end 932 933 # TYPE_NAME トークンへ置き換え 934 if @b_no_type_name == false 935 if token[0] == :IDENTIFIER && Namespace.is_typename?( token[1].val ) then 936 token[0] = :TYPE_NAME 937 locale = @@current_locale[@@generator_nest] 785 RESERVED = { 786 # keyword 787 'typedef' => :TYPEDEF, 788 'struct' => :STRUCT, 789 'union' => :UNION, 790 'sizeof' => :SIZEOF, 791 'throw' => :THROW, 792 793 # specifier 794 # types 795 'void' => :VOID, 796 'char' => :CHAR, 797 'short' => :SHORT, 798 799 'volatile'=> :VOLATILE, 800 'restrict'=> :RESTRICT, 801 'const' => :CONST, 802 'extern' => :EXTERN, 803 804 'long' => :LONG, 805 'float' => :FLOAT, 806 'double' => :DOUBLE, 807 'signed' => :SIGNED, 808 'unsigned'=> :UNSIGNED, 809 810 'int' => :INT, 811 'enum' => :ENUM, 812 813 'if' => :IF, 814 'else' => :ELSE, 815 'while' => :WHILE, 816 'do' => :DO, 817 'for' => :FOR, 818 'switch' => :SWITCH, 819 'case' => :CASE, 820 'default' => :DEFAULT, 821 'goto' => :GOTO, 822 'continue' => :CONTINUE, 823 'break' => :BREAK, 824 'return' => :RETURN, 825 '__inline__' => :__INLINE__, 826 'inline' => :INLINE, 827 '__inline' => :__INLINE, 828 'Inline' => :CINLINE, # inline starting with Capital letter 829 'static' => :STATIC, 830 'register' => :REGISTER, 831 'auto' => :AUTO, 832 '__extension__' => :EXTENSION, 833 '__asm__' => :_ASM, 834 'asm' => :_ASM 835 836 } 837 838 @@generator_nest = -1 839 @@generator_stack = [] 840 @@current_locale = [] 841 842 def finalize 843 844 # mikan Namespace.pop 845 Celltype.pop 846 Cell.pop 847 CompositeCelltype.pop 848 Region.pop 849 850 end 851 852 def set_plugin( plugin ) 853 @plugin = plugin 854 end 855 856 def self.get_plugin 857 @@generator_stack[@@generator_nest].get_plugin 858 end 859 860 def get_plugin 861 @plugin 862 end 863 864 def parse(files) 865 866 # mikan Namespace.push 867 Celltype.push 868 Cell.push 869 CompositeCelltype.push 870 Region.push 871 872 @@generator_nest += 1 873 @@generator_stack[@@generator_nest] = self 874 @b_no_type_name = false 875 876 begin 877 878 @q = [] 879 comment = false 880 # b_asm = false 881 882 # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策 883 TECS_LANG::set_kcode_binary 884 885 # 800U, 0xffLL など (整数リテラルに共通の修飾子) 886 integer_qualifier = "([Uu][Ll][Ll]|[Uu][Ll]|[Uu]|[Ll][Ll]|[Ll])?" 887 888 files.each {|file| 889 lineno = 1 890 begin 891 #2.0 IO.foreach(file) {|line| 892 TECSIO.foreach(file) {|line| 893 col = 1 894 line.rstrip! 895 896 until line.empty? 897 898 if comment 899 case line 900 # コメント終了 901 when /\A\*\// 902 comment = false 903 when /\A./ 904 ; 905 end 906 else 907 case line 908 # 空白、プリプロセスディレクティブ 909 when /\A\s+/ 910 ; 911 # 識別子 912 when /\A[a-zA-Z_]\w*/ 913 word = $& 914 @q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)] 915 # 16 進数定数 916 when /\A0x[0-9A-Fa-f]+#{integer_qualifier}/ 917 @q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)] 918 # 8 進数定数 919 when /\A0[0-7]+#{integer_qualifier}/ 920 @q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)] 921 # 浮動小数定数 922 when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/ 923 @q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)] 924 # 整数定数 925 when /\A\d+#{integer_qualifier}/ 926 # when /\A\d+/ 927 @q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)] 928 # 文字 929 when /\A'(?:[^'\\]|\\.)'/ 930 @q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)] 931 # 文字列 932 # "#include #include #include \"../systask/logtask.cfg\" 最後の " 忘れ)で無限ループ 933 # when /\A"(?:[^"\\]+|\\.)*"/ 934 when /\A"(?:[^"\\]|\\.)*"/ # これはうまく行くようだ 935 @q << [:STRING_LITERAL, Token.new($&, file, lineno, col)] 936 # 行コメント 937 when /\A\/\/.*$/ 938 # 読み飛ばすだけ 939 # コメント開始 940 when /\A\/\*/ 941 comment = true 942 when /\A>>=/, /\A<<=/, /\A>>/, /\A<</ 943 @q << [$&, Token.new($&, file, lineno, col)] 944 when /\A\+=/, /\A\-=/, /\A\*=/, /\A\/=/, /\A%=/, /\A&=/, /\A\|=/, /\A\^=/ 945 @q << [$&, Token.new($&, file, lineno, col)] 946 when /\A::/, /\A==/, /\A!=/, /\A>=/, /\A<=/, /\A\->/, /\A\+\+/, /\A\-\-/ 947 @q << [$&, Token.new($&, file, lineno, col)] 948 when /\A\|\|/, /\A\&\&/ 949 @q << [$&, Token.new($&, file, lineno, col)] 950 when /\A./ 951 @q << [$&, Token.new($&, file, lineno, col)] 952 else 953 raise 954 end 955 end 956 957 line = $' 958 col += $&.length 959 end 960 961 lineno += 1 962 } 963 964 rescue => evar 965 Generator.error( "B1002 while open or reading \'$1\'" , file ) 966 print_exception( evar ) 967 end 968 } 969 970 # 終了の印 971 @q << nil 972 973 @yydebug = true 974 do_parse 975 976 ensure 977 @@generator_nest -= 1 978 TECS_LANG::reset_kcode 979 end 980 981 end 982 983 984 def next_token 985 token = @q.shift 986 987 if token then 988 @@current_locale[@@generator_nest] = token[1].locale 989 990 case token[1].val 991 when ";", ":", ",", "(", ")", "{", "}" 992 set_no_type_name false 993 when ".", "->" 994 set_no_type_name true 995 end 996 997 # TYPE_NAME トークンへ置き換え 998 if @b_no_type_name == false 999 if token[0] == :IDENTIFIER && Namespace.is_typename?( token[1].val ) then 1000 token[0] = :TYPE_NAME 1001 locale = @@current_locale[@@generator_nest] 938 1002 #print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}: type_name'\n" ) 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1003 end 1004 end 1005 1006 if $debug then # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生) 1007 locale = @@current_locale[@@generator_nest] 1008 if token then 1009 print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" ) 1010 else 1011 print( "#{locale[0]}: line #{locale[1]} : EOF\n" ) 1012 end 1013 end 1014 end 1015 1016 token 1017 end 1018 1019 def on_error(t, v, vstack) 1020 if v == "$" then 1021 Generator.error( "B1003 Unexpected EOF" ) 1022 else 1023 Generator.error( "B1004 syntax error near \'$1\'" , v.val ) 1024 end 1025 1026 end 1027 1028 def self.current_locale 1029 @@current_locale[ @@generator_nest ] 1030 end 1031 1032 @@n_error = 0 1033 @@n_warning = 0 1034 @@n_info = 0 1035 1036 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でエラー発生は不適切) 1037 def self.error( msg ) 1038 @@n_error += 1 1039 locale = @@current_locale[ @@generator_nest ] 1040 1041 if locale then 1042 Console.puts "error: #{locale[0]}: line #{locale[1]} #{msg}" 1043 else 1044 Console.puts "error: #{msg}" 1045 end 1046 end 1047 1048 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でウォーニング発生は不適切) 1049 def self.warning( msg ) 1050 @@n_warning += 1 1051 locale = @@current_locale[ @@generator_nest ] 1052 Console.puts "warning: #{locale[0]}: line #{locale[1]} #{msg}" 1053 end 1054 1055 # このメソッドは構文解析、意味解析からのみ呼出し可 1056 def self.info( msg ) 1057 @@n_info += 1 1058 locale = @@current_locale[ @@generator_nest ] 1059 Console.puts "info: #{locale[0]}: line #{locale[1]} #{msg}" 1060 end 1061 1062 def self.get_n_error 1063 @@n_error 1064 end 1065 1066 def self.get_n_warning 1067 @@n_warning 1068 end 1069 1070 def self.get_nest 1071 @@generator_nest 1072 end 1073 1074 def set_no_type_name b_no_type_name 1075 locale = @@current_locale[ @@generator_nest ] 1012 1076 #print "b_no_type_name=#{b_no_type_name} #{locale[0]}: line #{locale[1]}\n" 1013 1014 1077 @b_no_type_name = b_no_type_name 1078 end 1015 1079 1016 1080 ---- footer
Note:
See TracChangeset
for help on using the changeset viewer.