- Timestamp:
- Jul 3, 2020, 7:19:17 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb
r321 r429 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 # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. … … 35 35 # の責任を負わない. 36 36 # 37 # $Id $37 # $Id: C_parser.y.rb 2810 2018-03-11 13:20:03Z okuma-top $ 38 38 #++ 39 39 … … 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 : STRUCT struct_tag '{' 343 # : STRUCT struct_tag '{' 344 : struct_term struct_tag '{' 302 345 { StructType.set_define( true ) } 303 346 struct_declaration_list '}' 304 347 { 305 348 StructType.end_of_parse 306 349 result = val[1] 307 350 } 308 | STRUCT 351 # | STRUCT 352 | struct_term 309 353 { 310 354 result = CStructType.new() 311 355 StructType.set_define( true ) 312 356 } 313 357 '{' struct_declaration_list '}' 314 358 { 315 359 StructType.end_of_parse 316 360 result = val[1] 317 361 } 318 | STRUCT struct_tag # mikan struct_tag は namespace 対応が必要 362 # | STRUCT struct_tag # mikan struct_tag は namespace 対応が必要 363 | struct_term struct_tag # mikan struct_tag は namespace 対応が必要 319 364 { 320 365 StructType.set_define( false ) … … 323 368 } 324 369 370 struct_term 371 : STRUCT { set_no_type_name true } 372 325 373 struct_declaration_list 326 327 374 : struct_declaration 375 | struct_declaration_list struct_declaration 328 376 329 377 struct_tag: 330 378 IDENTIFIER 331 379 { 332 380 result = CStructType.new( val[0].val ) … … 336 384 # ポインタ修飾子を追加 337 385 struct_declaration 338 339 # : type_specifier_qualifier_list struct_declarator_list ';'386 : declaration_specifiers struct_declarator_list ';' 387 # : specifier_qualifier_list struct_declarator_list ';' 340 388 { 341 389 val[1].each { |i| # i: Decl … … 347 395 result = val[1] 348 396 } 349 | union_specifier ';' # 無名 350 | 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 ';' # 無名 351 410 352 411 … … 354 413 # K&Rのspecifier_qualifier_listと同じ 355 414 # 名前がまぎらわしかったのでtype_を付けた 356 type_specifier_qualifier_list 357 : type_specifier 358 | type_specifier type_specifier_qualifier_list 415 specifier_qualifier_list 416 : type_specifier specifier_qualifier_list 359 417 { 360 418 result = val[1].merge val[0] 361 419 } 362 | 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 363 427 { 364 428 result = CIntType.new( -3 ) 365 429 result.set_qualifier val[0] 366 430 } 367 | type_qualifier type_specifier_qualifier_list368 {369 val[1].set_qualifier val[0]370 result = val[1]371 }372 431 373 432 struct_declarator_list 374 433 : struct_declarator 375 434 { result = [ val[0] ] } 376 435 | struct_declarator_list ',' struct_declarator 377 436 { result << val[2] } 378 437 379 438 # ビットフィールドは使えない 380 439 struct_declarator 381 382 383 440 : declarator 441 # | ':' constant_expression 442 # | declarator ':' constant_expression 384 443 385 444 union_specifier 386 : UNION union_tag '{' union_declaration_list '}' 387 | UNION '{' union_declaration_list '}' 388 | UNION union_tag # mikan struct_tag は namespace 対応が必要 445 # : UNION union_tag '{' union_declaration_list '}' 446 # | UNION '{' union_declaration_list '}' 447 # | UNION union_tag # mikan struct_tag は namespace 対応が必要 448 : union_term union_tag '{' union_declaration_list '}' 449 | union_term '{' union_declaration_list '}' 450 | union_term union_tag # mikan struct_tag は namespace 対応が必要 451 452 union_term 453 : UNION { set_no_type_name true } 389 454 390 455 union_declaration_list 391 392 456 : union_declaration 457 | union_declaration_list union_declaration 393 458 394 459 union_tag: … … 396 461 397 462 union_declaration 398 463 : declaration_specifiers union_declarator_list ';' 399 464 | union_specifier ';' # 無名 400 465 | struct_specifier ';' # 無名 401 466 402 467 union_declarator_list 403 : union_declarator 404 | union_declarator_list ',' union_declarator 405 406 # ビットフィールドは使えない 468 : union_declarator 469 | union_declarator_list ',' union_declarator 470 407 471 union_declarator 408 : declarator 409 410 411 412 # enumの種類を追加 413 enum_specifier # mikan 414 : enum_type '{' enumerator_list '}' 415 | enum_type IDENTIFIER '{' enumerator_list '}' 416 | enum_type IDENTIFIER 417 418 enum_type 419 : ENUM { result = CEnumType.new( -1 ) } 420 # | ENUM8 { result = CEnumType.new( 8 ) } 421 # | ENUM16 { result = CEnumType.new( 16 ) } 422 # | ENUM32 { result = CEnumType.new( 32 ) } 423 # | ENUM64 { result = CEnumType.new( 64 ) } 424 # | 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 425 485 426 486 enumerator_list 427 428 487 : enumerator 488 | enumerator_list ',' enumerator 429 489 430 490 enumerator 431 432 491 : IDENTIFIER 492 | IDENTIFIER '=' constant_expression 433 493 434 494 type_qualifier 435 : CONST { result = :CONST } 436 | 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 437 506 438 507 declarator 439 508 : pointer direct_declarator 440 509 { 441 510 val[1].set_type( val[0] ) 442 511 result = val[1] 443 512 } 444 445 513 | direct_declarator 514 | pointer TYPE_NAME # 関数ポインタの typedef が二重定義の場合 446 515 { 447 516 result = Decl.new( val[1].val ) … … 450 519 451 520 direct_declarator # mikan 452 521 : IDENTIFIER 453 522 { result = Decl.new( val[0].val ) } 454 523 | '(' declarator ')' 455 524 { result = val[1] } 456 525 | direct_declarator '[' constant_expression ']' 457 526 { 458 527 val[0].set_type( CArrayType.new( val[2] ) ) 459 528 result = val[0] 460 529 } 461 530 | direct_declarator '[' ']' 462 531 { 463 532 val[0].set_type( CArrayType.new ) 464 533 result = val[0] 465 534 } 466 535 | direct_declarator '(' parameter_type_list ')' 467 536 { 468 537 # Generator.warning( "W6001 need 'void' for no parameter" ) … … 470 539 result = val[0] 471 540 } 472 473 # | direct_declarator '(' identifier_list ')' # これは何のために必要? 060211 474 | direct_declarator '(' ')' 541 | direct_declarator '(' identifier_list ')' # これは何のために必要? 060211 542 | direct_declarator '(' ')' 475 543 { 476 544 # Generator.warning( "W6002 need 'void' for no parameter" ) … … 480 548 481 549 pointer 482 550 : '*' 483 551 { result = CPtrType.new } 484 | '*' type_qualifier 552 | '*' type_qualifier_list 485 553 { 486 554 result = CPtrType.new 487 555 result.set_qualifier( val[1] ) 488 556 } 489 557 | '*' pointer 490 558 { 491 559 val[1].set_type(CPtrType.new) 492 560 result = val[1] 493 561 } 494 | '*' type_qualifierpointer562 | '*' type_qualifier_list pointer 495 563 { 496 564 ptrtype = CPtrType.new … … 500 568 } 501 569 570 type_qualifier_list 571 : type_qualifier 572 | type_qualifier_list type_qualifier 502 573 503 574 parameter_type_list 504 505 575 : parameter_list 576 | parameter_list ',' '.' '.' '.' 506 577 # mikan 可変長パラメータ, ... の間のスペースが許される(手抜き) 507 578 508 579 parameter_list 509 580 : parameter_declaration 510 581 # { result = ParamList.new( val[0] ) } 511 582 | parameter_list ',' parameter_declaration 512 583 # { 513 584 # val[0].add_param( val[2] ) … … 518 589 # パラメータ修飾子を追加 519 590 parameter_declaration 520 591 : declaration_specifiers declarator 521 592 # { 522 593 # decl = ParamDecl.new( val[1], val[0], [] ) … … 533 604 # result = nil 534 605 # } 535 536 537 538 539 #identifier_list # 060211 不用になった540 #: IDENTIFIER541 #| identifier_list ',' IDENTIFIER606 | declaration_specifiers abstract_declarator # 仮引数なし 607 | declaration_specifiers # 仮引数なし 608 609 610 identifier_list # 060211 不用になった 611 : IDENTIFIER 612 | identifier_list ',' IDENTIFIER 542 613 543 614 type_name 544 : type_specifier_qualifier_list545 | type_specifier_qualifier_list abstract_declarator615 : specifier_qualifier_list 616 | specifier_qualifier_list abstract_declarator 546 617 547 618 abstract_declarator # mikan 548 549 550 619 : pointer 620 | direct_abstract_declarator 621 | pointer direct_abstract_declarator 551 622 552 623 direct_abstract_declarator 553 554 555 | '[' constant_expression ']'556 557 | direct_abstract_declarator '[' constant_expression ']'558 624 : '(' abstract_declarator ')' 625 | '[' ']' 626 | '[' assignment_expression ']' 627 | direct_abstract_declarator '[' ']' 628 | direct_abstract_declarator '[' assignment_expression ']' 629 | '(' ')' 559 630 { 560 631 Generator.warning( "W6003 need 'void' for no parameter" ) 561 632 } 562 563 633 | '(' parameter_type_list ')' 634 | direct_abstract_declarator '(' ')' 564 635 { 565 636 Generator.warning( "W6004 need 'void' for no parameter" ) 566 637 } 567 638 | direct_abstract_declarator '(' parameter_type_list ')' 568 639 569 640 # assignment_expressionをconstant_expressionに変更 570 641 initializer # mikan 571 : constant_expression642 : assignment_expression 572 643 { result = val[0] } 573 644 | '{' initializer_list '}' 574 645 { result = val[1] } 575 646 | '{' initializer_list ',' '}' 576 647 { result = val[1] } 577 | C_EXP '(' STRING_LITERAL ')'648 | C_EXP '(' STRING_LITERAL ')' 578 649 { result = C_EXP.new( val[2] ) } 579 650 580 651 initializer_list 581 652 : initializer 582 653 { 583 654 result = [ val[0] ] 584 655 } 585 656 | initializer_list ',' initializer 586 657 { 587 658 val[0] << val[2] … … 594 665 #トップレベルの構文規則 595 666 C_parser 596 597 667 : 668 | C_parser extension_statement 598 669 599 670 extension_statement 600 :statement601 | EXTENSIONstatement602 603 statement604 605 606 607 608 609 610 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 # エラー回復ポイント 611 682 612 683 typedef 613 : TYPEDEF type_specifier_qualifier_list declarator_list ';'684 : TYPEDEF specifier_qualifier_list declarator_list ';' 614 685 { 615 686 val[2].each{ |i| … … 621 692 622 693 declarator_list 623 694 : declarator 624 695 { result = [ val[0] ] } 625 696 | declarator_list ',' declarator 626 697 { result << val[2] } 627 698 628 699 func_def 629 : declaration_specifiers declarator compoundstatement 630 631 infunc_statement_list 632 : 633 | infunc_statement_list infunc_statement 634 635 infunc_statement 636 : declaration 637 | ifstatement 638 | whilestatement 639 | dowhilestatement 640 | forstatement 641 | switchstatement 642 | labelstatement 643 | compoundstatement 644 | gotostatement 645 | expressionstatement 646 | ';' 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 ';' 647 734 648 735 ifstatement 649 : IF '(' expression ')' infunc_statement 650 | 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 651 741 652 742 whilestatement 653 : WHILE '(' expression ')' infunc_statement743 : WHILE '(' expression ')' statement 654 744 655 745 dowhilestatement 656 : DO infunc_statement WHILE '(' expression ')' ';'746 : DO statement WHILE '(' expression ')' ';' 657 747 658 748 forstatement 659 : FOR '(' expression ';' expression ';' expression ')' infunc_statement 660 661 switchstatement 662 : SWITCH '(' expression ')' infunc_statment 663 664 labelstatement 665 : IDENTIFIER ':' infunc_statement 666 | CASE constant_expression ':' infunc_statement 667 | DEFAULT ':' infunc_statement 668 669 compoundstatement 670 : '{' infunc_statement_list '}' 671 672 gotostatement 673 : GOTO IDENTIFIER ';' 674 | CONTINUE ';' 675 | BREAK ';' 676 | RETURN expression ';' 677 | RETURN ';' 678 679 expressionstatement 680 : expression ';' 681 | unary_expression assignment_operator expression ';' 682 683 assignment_operator 684 : '=' 685 | '+=' 686 | '-=' 687 | '*=' 688 | '/=' 689 | '%=' 690 | '<<=' 691 | '>>=' 692 | '&=' 693 | '|=' 694 | '^=' 695 696 storage_class 697 : __INLINE__ 698 | INLINE 699 | __INLINE 700 | CINLINE 701 | EXTERN 702 | STATIC 703 | AUTO 704 | 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 ';' 705 760 706 761 namespace_identifier 707 708 709 762 : IDENTIFIER { result = NamespacePath.new( val[0].val, false ) } 763 | '::' IDENTIFIER { result = NamespacePath.new( val[1].val, true ) } 764 | namespace_identifier '::' IDENTIFIER 710 765 { result = val[0].append!( val[2].val ) } 711 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 712 781 end 713 782 714 783 ---- inner 715 784 716 RESERVED = { 717 # keyword 718 'typedef' => :TYPEDEF, 719 'struct' => :STRUCT, 720 'union' => :UNION, 721 'sizeof' => :SIZEOF, 722 'throw' => :THROW, 723 724 # specifier 725 # types 726 'void' => :VOID, 727 'char' => :CHAR, 728 'short' => :SHORT, 729 730 'volatile'=> :VOLATILE, 731 'const' => :CONST, 732 'extern' => :EXTERN, 733 734 'long' => :LONG, 735 'float' => :FLOAT, 736 'double' => :DOUBLE, 737 'signed' => :SIGNED, 738 'unsigned'=> :UNSIGNED, 739 740 'int' => :INT, 741 'enum' => :ENUM, 742 743 'if' => :IF, 744 'else' => :ELSE, 745 'while' => :WHILE, 746 'do' => :DO, 747 'for' => :FOR, 748 'case' => :CASE, 749 'default' => :DEFAULT, 750 'goto' => :GOTO, 751 'continue' => :CONTINUE, 752 'break' => :BREAK, 753 'return' => :RETURN, 754 '__inline__' => :__INLINE__, 755 'inline' => :INLINE, 756 '__inline' => :__INLINE, 757 'Inline' => :CINLINE, # inline starting with Capital letter 758 'static' => :STATIC, 759 'register' => :REGISTER, 760 'auto' => :AUTO, 761 '__extension__' => :EXTENSION, 762 763 } 764 765 @@generator_nest = -1 766 @@generator_stack = [] 767 @@current_locale = [] 768 769 def finalize 770 771 # mikan Namespace.pop 772 Celltype.pop 773 Cell.pop 774 CompositeCelltype.pop 775 Region.pop 776 777 end 778 779 def set_plugin( plugin ) 780 @plugin = plugin 781 end 782 783 def self.get_plugin 784 @@generator_stack[@@generator_nest].get_plugin 785 end 786 787 def get_plugin 788 @plugin 789 end 790 791 def parse(files) 792 793 # mikan Namespace.push 794 Celltype.push 795 Cell.push 796 CompositeCelltype.push 797 Region.push 798 799 @@generator_nest += 1 800 @@generator_stack[@@generator_nest] = self 801 @b_no_type_name = false 802 803 begin 804 805 @q = [] 806 comment = false 807 808 # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策 809 TECS_LANG::set_kcode_binary 810 811 # 800U, 0xffLL など (整数リテラルに共通の修飾子) 812 integer_qualifier = "([Uu][Ll][Ll]|[Uu][Ll]|[Uu]|[Ll][Ll]|[Ll])?" 813 814 files.each {|file| 815 lineno = 1 816 begin 817 #2.0 IO.foreach(file) {|line| 818 TECSIO.foreach(file) {|line| 819 col = 1 820 line.rstrip! 821 822 until line.empty? 823 824 if comment 825 case line 826 # コメント終了 827 when /\A\*\// 828 comment = false 829 when /\A./ 830 ; 831 end 832 else 833 case line 834 # 空白、プリプロセスディレクティブ 835 when /\A\s+/ 836 ; 837 # 識別子 838 when /\A[a-zA-Z_]\w*/ 839 word = $& 840 @q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)] 841 # 16 進数定数 842 when /\A0x[0-9A-Fa-f]+#{integer_qualifier}/ 843 @q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)] 844 # 8 進数定数 845 when /\A0[0-7]+#{integer_qualifier}/ 846 @q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)] 847 # 浮動小数定数 848 when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/ 849 @q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)] 850 # 整数定数 851 when /\A\d+#{integer_qualifier}/ 852 # when /\A\d+/ 853 @q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)] 854 # 文字 855 when /\A'(?:[^'\\]|\\.)'/ 856 @q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)] 857 # 文字列 858 # "#include #include #include \"../systask/logtask.cfg\" 最後の " 忘れ)で無限ループ 859 # when /\A"(?:[^"\\]+|\\.)*"/ 860 when /\A"(?:[^"\\]|\\.)*"/ # これはうまく行くようだ 861 @q << [:STRING_LITERAL, Token.new($&, file, lineno, col)] 862 # 行コメント 863 when /\A\/\/.*$/ 864 # 読み飛ばすだけ 865 # コメント開始 866 when /\A\/\*/ 867 comment = true 868 when /\A>>=/, /\A<<=/, /\A>>/, /\A<</ 869 @q << [$&, Token.new($&, file, lineno, col)] 870 when /\A\+=/, /\A\-=/, /\A\*=/, /\A\/=/, /\A%=/, /\A&=/, /\A\|=/, /\A\^=/ 871 @q << [$&, Token.new($&, file, lineno, col)] 872 when /\A::/, /\A==/, /\A!=/, /\A>=/, /\A<=/, /\A\->/, /\A\+\+/, /\A\-\-/ 873 @q << [$&, Token.new($&, file, lineno, col)] 874 when /\A./ 875 @q << [$&, Token.new($&, file, lineno, col)] 876 else 877 raise 878 end 879 end 880 881 line = $' 882 col += $&.length 883 end 884 885 lineno += 1 886 } 887 888 rescue => evar 889 Generator.error( "B1002 while open or reading \'$1\'" , file ) 890 print_exception( evar ) 891 end 892 } 893 894 # 終了の印 895 @q << nil 896 897 @yydebug = true 898 do_parse 899 900 ensure 901 @@generator_nest -= 1 902 TECS_LANG::reset_kcode 903 end 904 905 end 906 907 908 def next_token 909 token = @q.shift 910 911 if token then 912 @@current_locale[@@generator_nest] = token[1].locale 913 914 case token[1].val 915 when ";", ":", ",", "(", ")", "{", "}" 916 set_no_type_name false 917 when ".", "->" 918 set_no_type_name true 919 end 920 921 # TYPE_NAME トークンへ置き換え 922 if @b_no_type_name == false 923 if token[0] == :IDENTIFIER && Namespace.is_typename?( token[1].val ) then 924 token[0] = :TYPE_NAME 925 end 926 end 927 928 if $debug then # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生) 929 locale = @@current_locale[@@generator_nest] 930 if token then 931 print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" ) 932 else 933 print( "#{locale[0]}: line #{locale[1]} : EOF\n" ) 934 end 935 end 936 end 937 938 token 939 end 940 941 def on_error(t, v, vstack) 942 if v == "$" then 943 Generator.error( "B1003 Unexpected EOF" ) 944 else 945 Generator.error( "B1004 syntax error near \'$1\'" , v.val ) 946 end 947 948 end 949 950 def self.current_locale 951 @@current_locale[ @@generator_nest ] 952 end 953 954 @@n_error = 0 955 @@n_warning = 0 956 957 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でエラー発生は不適切) 958 def self.error( msg ) 959 @@n_error += 1 960 locale = @@current_locale[ @@generator_nest ] 961 962 if locale then 963 Console.puts "error: #{locale[0]}: line #{locale[1]} #{msg}" 964 else 965 Console.puts "error: #{msg}" 966 end 967 end 968 969 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でウォーニング発生は不適切) 970 def self.warning( msg ) 971 @@n_warning += 1 972 locale = @@current_locale[ @@generator_nest ] 973 Console.puts "warning: #{locale[0]}: line #{locale[1]} #{msg}" 974 end 975 976 def self.get_n_error 977 @@n_error 978 end 979 980 def self.get_n_warning 981 @@n_warning 982 end 983 984 def self.get_nest 985 @@generator_nest 986 end 987 988 def set_no_type_name b_no_type_name 989 # print "b_no_type_name=#{b_no_type_name}\n" 990 @b_no_type_name = b_no_type_name 991 end 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] 1002 #print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}: type_name'\n" ) 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 "#{locale[0]}:#{locale[1]}: error: #{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 "#{locale[0]}:#{locale[1]}: warning: #{msg}" 1053 end 1054 1055 # このメソッドは構文解析、意味解析からのみ呼出し可 1056 def self.info( msg ) 1057 @@n_info += 1 1058 locale = @@current_locale[ @@generator_nest ] 1059 Console.puts "#{locale[0]}:#{locale[1]}: info: #{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 ] 1076 #print "b_no_type_name=#{b_no_type_name} #{locale[0]}: line #{locale[1]}\n" 1077 @b_no_type_name = b_no_type_name 1078 end 992 1079 993 1080 ---- footer
Note:
See TracChangeset
for help on using the changeset viewer.