source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb@ 374

Last change on this file since 374 was 374, checked in by coas-nagasima, 5 years ago

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 28.0 KB
RevLine 
[337]1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
[374]6# Copyright (C) 2008-2018 by TOPPERS Project
[337]7#--
[374]8# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
[337]9# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
10# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
11# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13# スコード中に含まれていること.
14# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
16# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
17# の無保証規定を掲載すること.
18# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
19# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
20# と.
21# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22# 作権表示,この利用条件および下記の無保証規定を掲載すること.
23# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
24# 報告すること.
25# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
26# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
27# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
28# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
29# 免責すること.
30#
31# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
33# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
34# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
35# の責任を負わない.
36#
[359]37# $Id$
[337]38#++
39
40class C_parser
41rule
42# トップレベルの構文要素は C_parser
43all: C_parser
44
45# Expr
46########################## 式 ##########################
47# K&Rの文法(プログラミング言語C 第2版 付録)と一部異なる
48# argument_expression_list(関数引数), assignment_expression(代入)がない
49# 式の result は、すべて配列で第一要素が識別シンボル、第二要素以下が引数
[374]50#
51# 2019/3/28 長島 下記のC99の構文に近づくよう変更
52#(読めないヘッダーファイルがあったため)
53# http://www.quut.com/c/ANSI-C-grammar-y-1999.html
54# 元々のコメントと合わなくなっています
[337]55
56primary_expression
[374]57 : namespace_identifier
[337]58 { result = [ :IDENTIFIER, val[0] ] } #1ok
59# : IDENTIFIER # mikan namespace への対応
60# { result = [ :IDENTIFIER, val[0] ] }
61# | TRUE
62# { result = [ :BOOL_CONSTANT, true ] }
63# | FALSE
64# { result = [ :BOOL_CONSTANT, false ] }
[374]65 | INTEGER_CONSTANT
[337]66 { result = [ :INTEGER_CONSTANT, val[0] ] }
[374]67 | FLOATING_CONSTANT
[337]68 { result = [ :FLOATING_CONSTANT, val[0] ] }
[374]69 | OCTAL_CONSTANT
[337]70 { result = [ :OCTAL_CONSTANT, val[0] ] }
[374]71 | HEX_CONSTANT
[337]72 { result = [ :HEX_CONSTANT, val[0] ] }
[374]73 | CHARACTER_LITERAL
[337]74 { result = [ :CHARACTER_LITERAL, val[0] ] }
[374]75 | string_literal_list
[337]76 { result = [ :STRING_LITERAL_LIST, val[0] ] }
[374]77 | '(' expression ')'
[337]78 { result = [ :PARENTHESES, val[1].get_elements ] }
79
80string_literal_list
[374]81 : STRING_LITERAL
[337]82 { result = [val[0]] }
[374]83 | string_literal_list STRING_LITERAL
[337]84 { result << val[1] }
85
86# 関数呼び出しと後置インクリメント、デクリメント演算子がない
87postfix_expression
[374]88 : primary_expression
89 | postfix_expression '[' expression ']'
[337]90 { result = [ :OP_SUBSC, val[0], val[2] ] }
[374]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
[337]95 { result = [ :OP_DOT, val[0], val[2] ] }
[374]96 | postfix_expression '->' IDENTIFIER
[337]97 { result = [ :OP_REF, val[0], val[2] ] }
[374]98 | postfix_expression '++' { result = val[0] } # ++, -- は無視する
99 | postfix_expression '--' { result = val[0] }
100 | '(' type_name ')' '{' initializer_list '}'
101 | '(' type_name ')' '{' initializer_list ',' '}'
[337]102
[374]103argument_expression_list
104 : assignment_expression
105 | argument_expression_list ',' assignment_expression
[337]106
107
108# 前置インクリメント、デクリメント演算子がない
109unary_expression
[374]110 : postfix_expression
111 | unary_operator cast_expression
[337]112 { result = [ val[0], val[1] ] }
[374]113 | SIZEOF unary_expression
[337]114 { result = [ :OP_SIZEOF_EXPR, val[1] ] }
[374]115 | SIZEOF '(' type_name ')'
[337]116 { result = [ :OP_SIZEOF_TYPE, val[1] ] }
117 | '++' unary_expression { result = val[1] } # ++, -- は無視する
118 | '--' unary_expression { result = val[1] }
119
120unary_operator
[374]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 }
[337]127
128cast_expression
[374]129 : unary_expression
130 | '(' type_name ')' cast_expression
[337]131 { result = [ :CAST, val[1], val[3] ] }
132
133multiplicative_expression
[374]134 : cast_expression
135 | multiplicative_expression '*' cast_expression
[337]136 { result = [ :OP_MULT, val[0], val[2] ] }
[374]137 | multiplicative_expression '/' cast_expression
[337]138 { result = [ :OP_DIV, val[0], val[2] ] }
[374]139 | multiplicative_expression '%' cast_expression
[337]140 { result = [ :OP_REMAIN, val[0], val[2] ] }
141
142additive_expression
[374]143 : multiplicative_expression
144 | additive_expression '+' multiplicative_expression
[337]145 { result = [ :OP_ADD, val[0], val[2] ] }
[374]146 | additive_expression '-' multiplicative_expression
[337]147 { result = [ :OP_SUB, val[0], val[2] ] }
148
149shift_expression
[374]150 : additive_expression
151 | shift_expression '<<' additive_expression
[337]152 { result = [ :OP_LSFT, val[0], val[2] ] }
[374]153 | shift_expression '>>' additive_expression
[337]154 { result = [ :OP_RSFT, val[0], val[2] ] }
155
156relational_expression
[374]157 : shift_expression
158 | relational_expression '<' shift_expression
[337]159 { result = [ :OP_LT, val[0], val[2] ] }
[374]160 | relational_expression '>' shift_expression
[337]161 { result = [ :OP_GT, val[0], val[2] ] }
[374]162 | relational_expression '<=' shift_expression
[337]163 { result = [ :OP_LE, val[0], val[2] ] }
[374]164 | relational_expression '>=' shift_expression
[337]165 { result = [ :OP_GE, val[0], val[2] ] }
166
167equality_expression
[374]168 : relational_expression
169 | equality_expression '==' relational_expression
[337]170 { result = [ :OP_EQ, val[0], val[2] ] }
[374]171 | equality_expression '!=' relational_expression
[337]172 { result = [ :OP_NE, val[0], val[2] ] }
173
174and_expression
[374]175 : equality_expression
176 | and_expression '&' equality_expression
[337]177 { result = [ :OP_AND, val[0], val[2] ] }
178
179exclusive_or_expression
[374]180 : and_expression
181 | exclusive_or_expression '^' and_expression
[337]182 { result = [ :OP_EOR, val[0], val[2] ] }
183
184inclusive_or_expression
[374]185 : exclusive_or_expression
186 | inclusive_or_expression '|' exclusive_or_expression
[337]187 { result = [ :OP_OR, val[0], val[2] ] }
188
189logical_and_expression
[374]190 : inclusive_or_expression
191 | logical_and_expression '&&' inclusive_or_expression
[337]192 { result = [ :OP_LAND, val[0], val[2] ] }
193
194logical_or_expression
[374]195 : logical_and_expression
196 | logical_or_expression '||' logical_and_expression
[337]197 { result = [ :OP_LOR, val[0], val[2] ] }
198
199conditional_expression
[374]200 : logical_or_expression
201 | logical_or_expression '?' expression ':' conditional_expression
[337]202 { result = [ :OP_CEX, val[0], val[2].get_elements, val[4] ] }
203
[374]204assignment_expression
205 : conditional_expression
206 | unary_expression assignment_operator assignment_expression
[337]207
[374]208assignment_operator
209 : '='
210 | '+='
211 | '-='
212 | '*='
213 | '/='
214 | '%='
215 | '<<='
216 | '>>='
217 | '&='
218 | '|='
219 | '^='
220
[337]221expression
[374]222 : assignment_expression
[337]223 {
224 result = Expression.new( val[0] )
225 # result.print
226 }
[374]227 | expression ',' assignment_expression
228 {
229 result = Expression.new( val[2] ) # ',' の後ろを採用
230 }
[337]231
232constant_expression
[374]233 : conditional_expression
[337]234 {
235 result = Expression.new( val[0] )
236 # result.print
237# res = result.eval_const( nil )
238
239 # if res then
240 # puts "val: #{res}"
241 # else
242 # puts "val: nil"
243 # end
244 }
245
246# Types
247########################## 宣言 ##########################
248# 宣言もK&Rと一部異なる
249
250# declarationはセルの属性で使われる
251# K&Rとの違い: storage classが指定できない、型が省略できない
252declaration
[374]253 : declaration_specifiers init_declarator_list ';'
254# : specifier_qualifier_list init_declarator_list ';'
[337]255
256# declaration_specifiersは関数のパラメータで使われるが、
[374]257# specifier_qualifier_listで十分かもしれない
[337]258
259declaration_specifiers
[374]260 : storage_class_specifier
[337]261 {
262 result = CIntType.new( -3 ) # storage class は無視
263 }
[374]264 | storage_class_specifier declaration_specifiers
[337]265 {
266 result = val[1] # storage class は無視
267 }
[374]268 | type_specifier
269 | type_specifier declaration_specifiers
[337]270 {
271 result = val[1].merge val[0]
272 }
[374]273 | type_qualifier
[337]274 {
[374]275 result = CIntType.new( -3 )
276 result.set_qualifier val[0]
277 }
278 | type_qualifier declaration_specifiers
279 {
[337]280 val[1].set_qualifier val[0]
[374]281 result = val[1]
[337]282 }
[374]283 | function_specifier
284 | function_specifier declaration_specifiers
[337]285
286init_declarator_list
[374]287 : init_declarator
[337]288 { result = [val[0]] }
[374]289 | init_declarator_list ',' init_declarator
[337]290 { result << val[2] }
291
292init_declarator
[374]293 : declarator
294 | declarator '=' initializer
[337]295 { val[0].set_initializer( val[2] ) }
296
[374]297storage_class_specifier
298 : EXTERN
299 | STATIC
300 | AUTO
301 | REGISTER
302
[337]303type_specifier
[374]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
[337]319 {
320 set_no_type_name true
321 result = CIntType.new( -3 )
322 result.set_sign :SIGNED
323 }
[374]324 | UNSIGNED
[337]325 {
326 set_no_type_name true
327 result = CIntType.new( -3 )
328 result.set_sign :UNSIGNED
329 }
[374]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 ) }
[337]340
341# mikan K&Rのstruct_or_union_specifierに相当するが、unionは使えない, bit field にも対応しない
342struct_specifier # mikan
343# : STRUCT struct_tag '{'
[374]344 : struct_term struct_tag '{'
[337]345 { StructType.set_define( true ) }
[374]346 struct_declaration_list '}'
[337]347 {
348 StructType.end_of_parse
349 result = val[1]
350 }
351# | STRUCT
[374]352 | struct_term
[337]353 {
354 result = CStructType.new()
355 StructType.set_define( true )
356 }
[374]357 '{' struct_declaration_list '}'
[337]358 {
359 StructType.end_of_parse
360 result = val[1]
361 }
362# | STRUCT struct_tag # mikan struct_tag は namespace 対応が必要
[374]363 | struct_term struct_tag # mikan struct_tag は namespace 対応が必要
[337]364 {
365 StructType.set_define( false )
366 StructType.end_of_parse
367 result = val[1]
368 }
369
370struct_term
[374]371 : STRUCT { set_no_type_name true }
[337]372
373struct_declaration_list
[374]374 : struct_declaration
375 | struct_declaration_list struct_declaration
[337]376
377struct_tag:
[374]378 IDENTIFIER
[337]379 {
380 result = CStructType.new( val[0].val )
381 set_no_type_name true
382 }
383
384# ポインタ修飾子を追加
385struct_declaration
[374]386 : declaration_specifiers struct_declarator_list ';'
387# : specifier_qualifier_list struct_declarator_list ';'
[337]388 {
389 val[1].each { |i| # i: Decl
390 i.set_type( val[0] )
391 i.set_kind( :MEMBER )
392 i.check
393 CStructType.new_member( i )
394 }
395 result = val[1]
396 }
[374]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 ';' # 無名
[337]410
411
412
413# K&Rのspecifier_qualifier_listと同じ
414# 名前がまぎらわしかったのでtype_を付けた
[374]415specifier_qualifier_list
416 : type_specifier specifier_qualifier_list
[337]417 {
418 result = val[1].merge val[0]
419 }
[374]420 | type_specifier
421 | type_qualifier specifier_qualifier_list
[337]422 {
[374]423 val[1].set_qualifier val[0]
424 result = val[1]
425 }
426 | type_qualifier
427 {
[337]428 result = CIntType.new( -3 )
429 result.set_qualifier val[0]
430 }
431
432struct_declarator_list
[374]433 : struct_declarator
[337]434 { result = [ val[0] ] }
[374]435 | struct_declarator_list ',' struct_declarator
[337]436 { result << val[2] }
437
438# ビットフィールドは使えない
439struct_declarator
[374]440 : declarator
441# | ':' constant_expression
442# | declarator ':' constant_expression
[337]443
444union_specifier
445# : UNION union_tag '{' union_declaration_list '}'
446# | UNION '{' union_declaration_list '}'
447# | UNION union_tag # mikan struct_tag は namespace 対応が必要
[374]448 : union_term union_tag '{' union_declaration_list '}'
449 | union_term '{' union_declaration_list '}'
450 | union_term union_tag # mikan struct_tag は namespace 対応が必要
[337]451
452union_term
[374]453 : UNION { set_no_type_name true }
[337]454
455union_declaration_list
[374]456 : union_declaration
457 | union_declaration_list union_declaration
[337]458
459union_tag:
460 IDENTIFIER
461
462union_declaration
[374]463 : declaration_specifiers union_declarator_list ';'
[337]464 | union_specifier ';' # 無名
465 | struct_specifier ';' # 無名
466
467union_declarator_list
[374]468 : union_declarator
469 | union_declarator_list ',' union_declarator
[337]470
471union_declarator
[374]472 : declarator
473 | ':' constant_expression
474 | declarator ':' constant_expression
[337]475
[374]476enum_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
[337]485
486enumerator_list
[374]487 : enumerator
488 | enumerator_list ',' enumerator
[337]489
490enumerator
[374]491 : IDENTIFIER
492 | IDENTIFIER '=' constant_expression
[337]493
494type_qualifier
[374]495 : CONST
496 { result = :CONST }
497 | RESTRICT
498 | VOLATILE
499 { result = :VOLATILE }
[337]500
[374]501function_specifier
502 : __INLINE__
503 | INLINE
504 | __INLINE
505 | CINLINE
506
[337]507declarator
[374]508 : pointer direct_declarator
[337]509 {
510 val[1].set_type( val[0] )
511 result = val[1]
512 }
[374]513 | direct_declarator
514 | pointer TYPE_NAME # 関数ポインタの typedef が二重定義の場合
[337]515 {
516 result = Decl.new( val[1].val )
517 result.set_type( val[0] )
518 }
519
520direct_declarator # mikan
[374]521 : IDENTIFIER
[337]522 { result = Decl.new( val[0].val ) }
[374]523 | '(' declarator ')'
[337]524 { result = val[1] }
[374]525 | direct_declarator '[' constant_expression ']'
[337]526 {
527 val[0].set_type( CArrayType.new( val[2] ) )
528 result = val[0]
529 }
[374]530 | direct_declarator '[' ']'
[337]531 {
532 val[0].set_type( CArrayType.new )
533 result = val[0]
534 }
[374]535 | direct_declarator '(' parameter_type_list ')'
[337]536 {
537 # Generator.warning( "W6001 need 'void' for no parameter" )
538 val[0].set_type( CFuncType.new )
539 result = val[0]
540 }
[374]541 | direct_declarator '(' identifier_list ')' # これは何のために必要? 060211
542 | direct_declarator '(' ')'
[337]543 {
544 # Generator.warning( "W6002 need 'void' for no parameter" )
545 val[0].set_type( CFuncType.new )
546 result = val[0]
547 }
548
549pointer
[374]550 : '*'
[337]551 { result = CPtrType.new }
[374]552 | '*' type_qualifier_list
[337]553 {
554 result = CPtrType.new
555 result.set_qualifier( val[1] )
556 }
[374]557 | '*' pointer
[337]558 {
559 val[1].set_type(CPtrType.new)
560 result = val[1]
561 }
[374]562 | '*' type_qualifier_list pointer
[337]563 {
564 ptrtype = CPtrType.new
565 ptrtype.set_qualifier( val[1] )
566 val[2].set_type( ptrtype )
567 result = val[2]
568 }
569
[374]570type_qualifier_list
571 : type_qualifier
572 | type_qualifier_list type_qualifier
[337]573
574parameter_type_list
[374]575 : parameter_list
576 | parameter_list ',' '.' '.' '.'
[337]577 # mikan 可変長パラメータ, ... の間のスペースが許される(手抜き)
578
579parameter_list
[374]580 : parameter_declaration
[337]581# { result = ParamList.new( val[0] ) }
[374]582 | parameter_list ',' parameter_declaration
[337]583# {
584# val[0].add_param( val[2] )
585# # result = val[0] 不要
586# }
587
588
589# パラメータ修飾子を追加
590parameter_declaration
[374]591 : declaration_specifiers declarator
[337]592# {
593# decl = ParamDecl.new( val[1], val[0], [] )
594# val[1].set_kind( :PARAMETER )
595# result = decl
596# }
597
598 # 以下はエラーとする
599# | declaration_specifiers # 仮引数なしは、とりあえず扱わない 060210
600# {
601# unless val[0].kind_of?( VoidType ) then
602# Generator.error( "B1001 need parameter name" )
603# end
604# result = nil
605# }
[374]606 | declaration_specifiers abstract_declarator # 仮引数なし
607 | declaration_specifiers # 仮引数なし
[337]608
609
[374]610identifier_list # 060211 不用になった
611 : IDENTIFIER
612 | identifier_list ',' IDENTIFIER
[337]613
614type_name
[374]615 : specifier_qualifier_list
616 | specifier_qualifier_list abstract_declarator
[337]617
618abstract_declarator # mikan
[374]619 : pointer
620 | direct_abstract_declarator
621 | pointer direct_abstract_declarator
[337]622
623direct_abstract_declarator
[374]624 : '(' abstract_declarator ')'
625 | '[' ']'
626 | '[' assignment_expression ']'
627 | direct_abstract_declarator '[' ']'
628 | direct_abstract_declarator '[' assignment_expression ']'
629 | '(' ')'
[337]630 {
631 Generator.warning( "W6003 need 'void' for no parameter" )
632 }
[374]633 | '(' parameter_type_list ')'
634 | direct_abstract_declarator '(' ')'
[337]635 {
636 Generator.warning( "W6004 need 'void' for no parameter" )
637 }
[374]638 | direct_abstract_declarator '(' parameter_type_list ')'
[337]639
640# assignment_expressionをconstant_expressionに変更
641initializer # mikan
[374]642 : assignment_expression
[337]643 { result = val[0] }
[374]644 | '{' initializer_list '}'
[337]645 { result = val[1] }
[374]646 | '{' initializer_list ',' '}'
[337]647 { result = val[1] }
[374]648 | C_EXP '(' STRING_LITERAL ')'
[337]649 { result = C_EXP.new( val[2] ) }
650
651initializer_list
[374]652 : initializer
[337]653 {
654 result = [ val[0] ]
655 }
[374]656 | initializer_list ',' initializer
[337]657 {
658 val[0] << val[2]
659 result = val[0]
660 }
661
662
663########################## ここからはCDL独自 ##########################
664
665#トップレベルの構文規則
666C_parser
[374]667 :
668 | C_parser extension_statement
[337]669
670extension_statement
[374]671 : cdl_statement
672 | EXTENSION cdl_statement
[337]673
[374]674cdl_statement
675 : typedef
676 | func_def
677 | enum_specifier ';'
678 | struct_specifier ';'
679 | declaration
680 | ';'
681 | error # エラー回復ポイント
[337]682
683typedef
[374]684 : TYPEDEF specifier_qualifier_list declarator_list ';'
[337]685 {
686 val[2].each{ |i|
687 i.set_kind( :TYPEDEF )
688 }
689 Typedef.new_decl_list( val[1], val[2] )
690 # val[1].show_tree 0
691 }
692
693declarator_list
[374]694 : declarator
[337]695 { result = [ val[0] ] }
[374]696 | declarator_list ',' declarator
[337]697 { result << val[2] }
698
699func_def
[374]700 : declaration_specifiers declarator compound_statement
[337]701
[374]702statement
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
[337]713
[374]714labeled_statement
715 : IDENTIFIER ':' statement
716 | CASE constant_expression ':' statement
717 | DEFAULT ':' statement
[337]718
[374]719compound_statement
720 : '{' '}'
721 | '{' block_item_list '}'
[337]722
[374]723block_item_list
724 : block_item
725 | block_item_list block_item
[337]726
[374]727block_item
728 : declaration
729 | statement
[337]730
[374]731expression_statement
732 : ';'
733 | expression ';'
[337]734
[374]735ifstatement
736 : IF '(' expression ')' statement
737 | IF '(' expression ')' statement ELSE statement
738
[337]739switchstatement
[374]740 : SWITCH '(' expression ')' compound_statement
[337]741
[374]742whilestatement
743 : WHILE '(' expression ')' statement
[337]744
[374]745dowhilestatement
746 : DO statement WHILE '(' expression ')' ';'
[337]747
[374]748forstatement
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
[337]753
[374]754jump_statement
755 : GOTO IDENTIFIER ';'
756 | CONTINUE ';'
757 | BREAK ';'
758 | RETURN ';'
759 | RETURN expression ';'
[337]760
761namespace_identifier
[374]762 : IDENTIFIER { result = NamespacePath.new( val[0].val, false ) }
763 | '::' IDENTIFIER { result = NamespacePath.new( val[1].val, true ) }
764 | namespace_identifier '::' IDENTIFIER
[337]765 { result = val[0].append!( val[2].val ) }
766
[374]767asm_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
[337]781end
782
783---- inner
784
[374]785 RESERVED = {
786 # keyword
787 'typedef' => :TYPEDEF,
788 'struct' => :STRUCT,
789 'union' => :UNION,
790 'sizeof' => :SIZEOF,
791 'throw' => :THROW,
[337]792
[374]793 # specifier
794 # types
795 'void' => :VOID,
796 'char' => :CHAR,
797 'short' => :SHORT,
[337]798
[374]799 'volatile'=> :VOLATILE,
800 'restrict'=> :RESTRICT,
801 'const' => :CONST,
802 'extern' => :EXTERN,
[337]803
[374]804 'long' => :LONG,
805 'float' => :FLOAT,
806 'double' => :DOUBLE,
807 'signed' => :SIGNED,
808 'unsigned'=> :UNSIGNED,
[337]809
[374]810 'int' => :INT,
811 'enum' => :ENUM,
[337]812
[374]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
[337]835
[374]836 }
[337]837
[374]838 @@generator_nest = -1
839 @@generator_stack = []
840 @@current_locale = []
[337]841
[374]842 def finalize
[337]843
[374]844 # mikan Namespace.pop
845 Celltype.pop
846 Cell.pop
847 CompositeCelltype.pop
848 Region.pop
[337]849
[374]850 end
[337]851
[374]852 def set_plugin( plugin )
853 @plugin = plugin
854 end
[337]855
[374]856 def self.get_plugin
857 @@generator_stack[@@generator_nest].get_plugin
858 end
[337]859
[374]860 def get_plugin
861 @plugin
862 end
[337]863
[374]864 def parse(files)
[337]865
[374]866 # mikan Namespace.push
867 Celltype.push
868 Cell.push
869 CompositeCelltype.push
870 Region.push
[337]871
[374]872 @@generator_nest += 1
873 @@generator_stack[@@generator_nest] = self
874 @b_no_type_name = false
[337]875
[374]876 begin
[337]877
[374]878 @q = []
879 comment = false
880# b_asm = false
[337]881
[374]882 # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策
883 TECS_LANG::set_kcode_binary
[337]884
[374]885 # 800U, 0xffLL など (整数リテラルに共通の修飾子)
886 integer_qualifier = "([Uu][Ll][Ll]|[Uu][Ll]|[Uu]|[Ll][Ll]|[Ll])?"
[337]887
[374]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!
[337]895
[374]896 until line.empty?
[337]897
[374]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
[337]956
[374]957 line = $'
958 col += $&.length
959 end
[337]960
[374]961 lineno += 1
962 }
[337]963
[374]964 rescue => evar
965 Generator.error( "B1002 while open or reading \'$1\'" , file )
966 print_exception( evar )
967 end
968 }
[337]969
[374]970 # 終了の印
971 @q << nil
[337]972
[374]973 @yydebug = true
974 do_parse
[337]975
[374]976 ensure
977 @@generator_nest -= 1
978 TECS_LANG::reset_kcode
979 end
[337]980
[374]981 end
[337]982
983
[374]984 def next_token
985 token = @q.shift
[337]986
[374]987 if token then
988 @@current_locale[@@generator_nest] = token[1].locale
[337]989
[374]990 case token[1].val
991 when ";", ":", ",", "(", ")", "{", "}"
992 set_no_type_name false
993 when ".", "->"
994 set_no_type_name true
995 end
[337]996
[374]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]
[337]1002#print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}: type_name'\n" )
[374]1003 end
1004 end
[337]1005
[374]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
[337]1015
[374]1016 token
1017 end
[337]1018
[374]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
[337]1025
[374]1026 end
[337]1027
[374]1028 def self.current_locale
1029 @@current_locale[ @@generator_nest ]
1030 end
[337]1031
[374]1032 @@n_error = 0
1033 @@n_warning = 0
1034 @@n_info = 0
[337]1035
[374]1036 # このメソッドは構文解析、意味解析からのみ呼出し可(コード生成でエラー発生は不適切)
1037 def self.error( msg )
1038 @@n_error += 1
1039 locale = @@current_locale[ @@generator_nest ]
[337]1040
[374]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
[337]1047
[374]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
[337]1054
[374]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
[337]1061
[374]1062 def self.get_n_error
1063 @@n_error
1064 end
[337]1065
[374]1066 def self.get_n_warning
1067 @@n_warning
1068 end
[337]1069
[374]1070 def self.get_nest
1071 @@generator_nest
1072 end
[337]1073
[374]1074 def set_no_type_name b_no_type_name
1075 locale = @@current_locale[ @@generator_nest ]
[337]1076#print "b_no_type_name=#{b_no_type_name} #{locale[0]}: line #{locale[1]}\n"
[374]1077 @b_no_type_name = b_no_type_name
1078 end
[337]1079
1080---- footer
1081
Note: See TracBrowser for help on using the repository browser.