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