]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Ecc/C.g
Check In tool source code based on Build tool project revision r1655.
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / C.g
1
2 grammar C;
3 options {
4 language=Python;
5 backtrack=true;
6 memoize=true;
7 k=2;
8 }
9
10 @header {
11 import CodeFragment
12 import FileProfile
13 }
14
15 @members {
16
17 def printTokenInfo(self, line, offset, tokenText):
18 print str(line)+ ',' + str(offset) + ':' + str(tokenText)
19
20 def StorePredicateExpression(self, StartLine, StartOffset, EndLine, EndOffset, Text):
21 PredExp = CodeFragment.PredicateExpression(Text, (StartLine, StartOffset), (EndLine, EndOffset))
22 FileProfile.PredicateExpressionList.append(PredExp)
23
24 def StoreEnumerationDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text):
25 EnumDef = CodeFragment.EnumerationDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset))
26 FileProfile.EnumerationDefinitionList.append(EnumDef)
27
28 def StoreStructUnionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text):
29 SUDef = CodeFragment.StructUnionDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset))
30 FileProfile.StructUnionDefinitionList.append(SUDef)
31
32 def StoreTypedefDefinition(self, StartLine, StartOffset, EndLine, EndOffset, FromText, ToText):
33 Tdef = CodeFragment.TypedefDefinition(FromText, ToText, (StartLine, StartOffset), (EndLine, EndOffset))
34 FileProfile.TypedefDefinitionList.append(Tdef)
35
36 def StoreFunctionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText, LeftBraceLine, LeftBraceOffset, DeclLine, DeclOffset):
37 FuncDef = CodeFragment.FunctionDefinition(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset), (LeftBraceLine, LeftBraceOffset), (DeclLine, DeclOffset))
38 FileProfile.FunctionDefinitionList.append(FuncDef)
39
40 def StoreVariableDeclaration(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText):
41 VarDecl = CodeFragment.VariableDeclaration(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset))
42 FileProfile.VariableDeclarationList.append(VarDecl)
43
44 def StoreFunctionCalling(self, StartLine, StartOffset, EndLine, EndOffset, FuncName, ParamList):
45 FuncCall = CodeFragment.FunctionCalling(FuncName, ParamList, (StartLine, StartOffset), (EndLine, EndOffset))
46 FileProfile.FunctionCallingList.append(FuncCall)
47
48 }
49
50 translation_unit
51 : external_declaration*
52 ;
53
54
55 /*function_declaration
56 @after{
57 print $function_declaration.text
58 }
59 : declaration_specifiers IDENTIFIER '(' parameter_list ')' ';'
60 ;
61 */
62 external_declaration
63 options {k=1;}
64 /*@after{
65 print $external_declaration.text
66 }*/
67 : ( declaration_specifiers? declarator declaration* '{' )=> function_definition
68 | declaration
69 | macro_statement (';')?
70 ;
71
72
73
74 function_definition
75 scope {
76 ModifierText;
77 DeclText;
78 LBLine;
79 LBOffset;
80 DeclLine;
81 DeclOffset;
82 }
83 @init {
84 $function_definition::ModifierText = '';
85 $function_definition::DeclText = '';
86 $function_definition::LBLine = 0;
87 $function_definition::LBOffset = 0;
88 $function_definition::DeclLine = 0;
89 $function_definition::DeclOffset = 0;
90 }
91 @after{
92 self.StoreFunctionDefinition($function_definition.start.line, $function_definition.start.charPositionInLine, $function_definition.stop.line, $function_definition.stop.charPositionInLine, $function_definition::ModifierText, $function_definition::DeclText, $function_definition::LBLine, $function_definition::LBOffset, $function_definition::DeclLine, $function_definition::DeclOffset)
93 }
94 : d=declaration_specifiers? declarator
95 ( declaration+ a=compound_statement // K&R style
96 | b=compound_statement // ANSI style
97 ) {
98 if d != None:
99 $function_definition::ModifierText = $declaration_specifiers.text
100 else:
101 $function_definition::ModifierText = ''
102 $function_definition::DeclText = $declarator.text
103 $function_definition::DeclLine = $declarator.start.line
104 $function_definition::DeclOffset = $declarator.start.charPositionInLine
105 if a != None:
106 $function_definition::LBLine = $a.start.line
107 $function_definition::LBOffset = $a.start.charPositionInLine
108 else:
109 $function_definition::LBLine = $b.start.line
110 $function_definition::LBOffset = $b.start.charPositionInLine
111 }
112 ;
113
114 declaration
115 : a='typedef' b=declaration_specifiers?
116 c=init_declarator_list d=';'
117 {
118 if b != None:
119 self.StoreTypedefDefinition($a.line, $a.charPositionInLine, $d.line, $d.charPositionInLine, $b.text, $c.text)
120 else:
121 self.StoreTypedefDefinition($a.line, $a.charPositionInLine, $d.line, $d.charPositionInLine, '', $c.text)
122 }
123 | s=declaration_specifiers t=init_declarator_list? e=';'
124 {
125 if t != None:
126 self.StoreVariableDeclaration($s.start.line, $s.start.charPositionInLine, $t.start.line, $t.start.charPositionInLine, $s.text, $t.text)
127 }
128 ;
129
130 declaration_specifiers
131 : ( storage_class_specifier
132 | type_specifier
133 | type_qualifier
134 )+
135 ;
136
137 init_declarator_list
138 : init_declarator (',' init_declarator)*
139 ;
140
141 init_declarator
142 : declarator ('=' initializer)?
143 ;
144
145 storage_class_specifier
146 : 'extern'
147 | 'static'
148 | 'auto'
149 | 'register'
150 | 'STATIC'
151 ;
152
153 type_specifier
154 : 'void'
155 | 'char'
156 | 'short'
157 | 'int'
158 | 'long'
159 | 'float'
160 | 'double'
161 | 'signed'
162 | 'unsigned'
163 | s=struct_or_union_specifier
164 {
165 if s.stop != None:
166 self.StoreStructUnionDefinition($s.start.line, $s.start.charPositionInLine, $s.stop.line, $s.stop.charPositionInLine, $s.text)
167 }
168 | e=enum_specifier
169 {
170 if e.stop != None:
171 self.StoreEnumerationDefinition($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)
172 }
173 | (IDENTIFIER type_qualifier* declarator)=> type_id
174 ;
175
176 type_id
177 : IDENTIFIER
178 //{self.printTokenInfo($a.line, $a.pos, $a.text)}
179 ;
180
181 struct_or_union_specifier
182 options {k=3;}
183 : struct_or_union IDENTIFIER? '{' struct_declaration_list '}'
184 | struct_or_union IDENTIFIER
185 ;
186
187 struct_or_union
188 : 'struct'
189 | 'union'
190 ;
191
192 struct_declaration_list
193 : struct_declaration+
194 ;
195
196 struct_declaration
197 : specifier_qualifier_list struct_declarator_list ';'
198 ;
199
200 specifier_qualifier_list
201 : ( type_qualifier | type_specifier )+
202 ;
203
204 struct_declarator_list
205 : struct_declarator (',' struct_declarator)*
206 ;
207
208 struct_declarator
209 : declarator (':' constant_expression)?
210 | ':' constant_expression
211 ;
212
213 enum_specifier
214 options {k=3;}
215 : 'enum' '{' enumerator_list ','? '}'
216 | 'enum' IDENTIFIER '{' enumerator_list ','? '}'
217 | 'enum' IDENTIFIER
218 ;
219
220 enumerator_list
221 : enumerator (',' enumerator)*
222 ;
223
224 enumerator
225 : IDENTIFIER ('=' constant_expression)?
226 ;
227
228 type_qualifier
229 : 'const'
230 | 'volatile'
231 | 'IN'
232 | 'OUT'
233 | 'OPTIONAL'
234 | 'CONST'
235 | 'UNALIGNED'
236 | 'VOLATILE'
237 | 'GLOBAL_REMOVE_IF_UNREFERENCED'
238 | 'EFIAPI'
239 | 'EFI_BOOTSERVICE'
240 | 'EFI_RUNTIMESERVICE'
241 ;
242
243 declarator
244 : pointer? ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? direct_declarator
245 // | ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? pointer? direct_declarator
246 | pointer
247 ;
248
249 direct_declarator
250 : IDENTIFIER declarator_suffix*
251 | '(' ('EFIAPI')? declarator ')' declarator_suffix+
252 ;
253
254 declarator_suffix
255 : '[' constant_expression ']'
256 | '[' ']'
257 | '(' parameter_type_list ')'
258 | '(' identifier_list ')'
259 | '(' ')'
260 ;
261
262 pointer
263 : '*' type_qualifier+ pointer?
264 | '*' pointer
265 | '*'
266 ;
267
268 parameter_type_list
269 : parameter_list (',' ('OPTIONAL')? '...')?
270 ;
271
272 parameter_list
273 : parameter_declaration (',' ('OPTIONAL')? parameter_declaration)*
274 ;
275
276 parameter_declaration
277 : declaration_specifiers (declarator|abstract_declarator)* ('OPTIONAL')?
278 //accomerdate user-defined type only, no declarator follow.
279 | pointer* IDENTIFIER
280 ;
281
282 identifier_list
283 : IDENTIFIER
284 (',' IDENTIFIER)*
285 ;
286
287 type_name
288 : specifier_qualifier_list abstract_declarator?
289 | type_id
290 ;
291
292 abstract_declarator
293 : pointer direct_abstract_declarator?
294 | direct_abstract_declarator
295 ;
296
297 direct_abstract_declarator
298 : ( '(' abstract_declarator ')' | abstract_declarator_suffix ) abstract_declarator_suffix*
299 ;
300
301 abstract_declarator_suffix
302 : '[' ']'
303 | '[' constant_expression ']'
304 | '(' ')'
305 | '(' parameter_type_list ')'
306 ;
307
308 initializer
309
310 : assignment_expression
311 | '{' initializer_list ','? '}'
312 ;
313
314 initializer_list
315 : initializer (',' initializer )*
316 ;
317
318 // E x p r e s s i o n s
319
320 argument_expression_list
321 : assignment_expression ('OPTIONAL')? (',' assignment_expression ('OPTIONAL')?)*
322 ;
323
324 additive_expression
325 : (multiplicative_expression) ('+' multiplicative_expression | '-' multiplicative_expression)*
326 ;
327
328 multiplicative_expression
329 : (cast_expression) ('*' cast_expression | '/' cast_expression | '%' cast_expression)*
330 ;
331
332 cast_expression
333 : '(' type_name ')' cast_expression
334 | unary_expression
335 ;
336
337 unary_expression
338 : postfix_expression
339 | '++' unary_expression
340 | '--' unary_expression
341 | unary_operator cast_expression
342 | 'sizeof' unary_expression
343 | 'sizeof' '(' type_name ')'
344 ;
345
346 postfix_expression
347 scope {
348 FuncCallText;
349 }
350 @init {
351 $postfix_expression::FuncCallText = '';
352 }
353 : p=primary_expression {$postfix_expression::FuncCallText += $p.text}
354 ( '[' expression ']'
355 | '(' a=')'{self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $a.line, $a.charPositionInLine, $postfix_expression::FuncCallText, '')}
356 | '(' c=argument_expression_list b=')' {self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $b.line, $b.charPositionInLine, $postfix_expression::FuncCallText, $c.text)}
357 | '(' macro_parameter_list ')'
358 | '.' x=IDENTIFIER {$postfix_expression::FuncCallText += '.' + $x.text}
359 | '*' y=IDENTIFIER {$postfix_expression::FuncCallText = $y.text}
360 | '->' z=IDENTIFIER {$postfix_expression::FuncCallText += '->' + $z.text}
361 | '++'
362 | '--'
363 )*
364 ;
365
366 macro_parameter_list
367 : parameter_declaration (',' parameter_declaration)*
368 ;
369
370 unary_operator
371 : '&'
372 | '*'
373 | '+'
374 | '-'
375 | '~'
376 | '!'
377 ;
378
379 primary_expression
380 : IDENTIFIER
381 | constant
382 | '(' expression ')'
383 ;
384
385 constant
386 : HEX_LITERAL
387 | OCTAL_LITERAL
388 | DECIMAL_LITERAL
389 | CHARACTER_LITERAL
390 | (IDENTIFIER* STRING_LITERAL+)+ IDENTIFIER*
391 | FLOATING_POINT_LITERAL
392 ;
393
394 /////
395
396 expression
397 : assignment_expression (',' assignment_expression)*
398 ;
399
400 constant_expression
401 : conditional_expression
402 ;
403
404 assignment_expression
405 : lvalue assignment_operator assignment_expression
406 | conditional_expression
407 ;
408
409 lvalue
410 : unary_expression
411 ;
412
413 assignment_operator
414 : '='
415 | '*='
416 | '/='
417 | '%='
418 | '+='
419 | '-='
420 | '<<='
421 | '>>='
422 | '&='
423 | '^='
424 | '|='
425 ;
426
427 conditional_expression
428 : e=logical_or_expression ('?' expression ':' conditional_expression {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)})?
429 ;
430
431 logical_or_expression
432 : logical_and_expression ('||' logical_and_expression)*
433 ;
434
435 logical_and_expression
436 : inclusive_or_expression ('&&' inclusive_or_expression)*
437 ;
438
439 inclusive_or_expression
440 : exclusive_or_expression ('|' exclusive_or_expression)*
441 ;
442
443 exclusive_or_expression
444 : and_expression ('^' and_expression)*
445 ;
446
447 and_expression
448 : equality_expression ('&' equality_expression)*
449 ;
450 equality_expression
451 : relational_expression (('=='|'!=') relational_expression )*
452 ;
453
454 relational_expression
455 : shift_expression (('<'|'>'|'<='|'>=') shift_expression)*
456 ;
457
458 shift_expression
459 : additive_expression (('<<'|'>>') additive_expression)*
460 ;
461
462 // S t a t e m e n t s
463
464 statement
465 : labeled_statement
466 | compound_statement
467 | expression_statement
468 | selection_statement
469 | iteration_statement
470 | jump_statement
471 | macro_statement
472 | asm2_statement
473 | asm1_statement
474 | asm_statement
475 | declaration
476 ;
477
478 asm2_statement
479 : '__asm__'? IDENTIFIER '(' (~(';'))* ')' ';'
480 ;
481
482 asm1_statement
483 : '_asm' '{' (~('}'))* '}'
484 ;
485
486 asm_statement
487 : '__asm' '{' (~('}'))* '}'
488 ;
489
490 macro_statement
491 : IDENTIFIER '(' declaration* statement_list? expression? ')'
492 ;
493
494 labeled_statement
495 : IDENTIFIER ':' statement
496 | 'case' constant_expression ':' statement
497 | 'default' ':' statement
498 ;
499
500 compound_statement
501 : '{' declaration* statement_list? '}'
502 ;
503
504 statement_list
505 : statement+
506 ;
507
508 expression_statement
509 : ';'
510 | expression ';'
511 ;
512
513 selection_statement
514 : 'if' '(' e=expression ')' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)} statement (options {k=1; backtrack=false;}:'else' statement)?
515 | 'switch' '(' expression ')' statement
516 ;
517
518 iteration_statement
519 : 'while' '(' e=expression ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
520 | 'do' statement 'while' '(' e=expression ')' ';' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
521 | 'for' '(' expression_statement e=expression_statement expression? ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}
522 ;
523
524 jump_statement
525 : 'goto' IDENTIFIER ';'
526 | 'continue' ';'
527 | 'break' ';'
528 | 'return' ';'
529 | 'return' expression ';'
530 ;
531
532 IDENTIFIER
533 : LETTER (LETTER|'0'..'9')*
534 ;
535
536 fragment
537 LETTER
538 : '$'
539 | 'A'..'Z'
540 | 'a'..'z'
541 | '_'
542 ;
543
544 CHARACTER_LITERAL
545 : ('L')? '\'' ( EscapeSequence | ~('\''|'\\') ) '\''
546 ;
547
548 STRING_LITERAL
549 : ('L')? '"' ( EscapeSequence | ~('\\'|'"') )* '"'
550 ;
551
552 HEX_LITERAL : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ;
553
554 DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ;
555
556 OCTAL_LITERAL : '0' ('0'..'7')+ IntegerTypeSuffix? ;
557
558 fragment
559 HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;
560
561 fragment
562 IntegerTypeSuffix
563 : ('u'|'U')
564 | ('l'|'L')
565 | ('u'|'U') ('l'|'L')
566 | ('u'|'U') ('l'|'L') ('l'|'L')
567 ;
568
569 FLOATING_POINT_LITERAL
570 : ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?
571 | '.' ('0'..'9')+ Exponent? FloatTypeSuffix?
572 | ('0'..'9')+ Exponent FloatTypeSuffix?
573 | ('0'..'9')+ Exponent? FloatTypeSuffix
574 ;
575
576 fragment
577 Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
578
579 fragment
580 FloatTypeSuffix : ('f'|'F'|'d'|'D') ;
581
582 fragment
583 EscapeSequence
584 : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
585 | OctalEscape
586 ;
587
588 fragment
589 OctalEscape
590 : '\\' ('0'..'3') ('0'..'7') ('0'..'7')
591 | '\\' ('0'..'7') ('0'..'7')
592 | '\\' ('0'..'7')
593 ;
594
595 fragment
596 UnicodeEscape
597 : '\\' 'u' HexDigit HexDigit HexDigit HexDigit
598 ;
599
600 WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
601 ;
602
603 // ingore '\' of line concatenation
604 BS : ('\\') {$channel=HIDDEN;}
605 ;
606
607 // ingore function modifiers
608 //FUNC_MODIFIERS : 'EFIAPI' {$channel=HIDDEN;}
609 // ;
610
611 UnicodeVocabulary
612 : '\u0003'..'\uFFFE'
613 ;
614 COMMENT
615 : '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
616 ;
617
618
619 LINE_COMMENT
620 : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
621 ;
622
623 // ignore #line info for now
624 LINE_COMMAND
625 : '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
626 ;