ECC: CParser remove \ in string.
[people/mcb30/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, $e.line, $e.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         | 'BOOLEAN'\r
164         | s=struct_or_union_specifier {self.StoreStructUnionDefinition($s.start.line, $s.start.charPositionInLine, $s.stop.line, $s.stop.charPositionInLine, $s.text)}\r
165         | e=enum_specifier {self.StoreEnumerationDefinition($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}\r
166         | (IDENTIFIER declarator)=> type_id\r
167         ;\r
168 \r
169 type_id\r
170     :   IDENTIFIER\r
171         //{self.printTokenInfo($a.line, $a.pos, $a.text)}\r
172     ;\r
173 \r
174 struct_or_union_specifier\r
175 options {k=3;}\r
176         : struct_or_union IDENTIFIER? '{' struct_declaration_list '}'\r
177         | struct_or_union IDENTIFIER\r
178         ;\r
179 \r
180 struct_or_union\r
181         : 'struct'\r
182         | 'union'\r
183         ;\r
184 \r
185 struct_declaration_list\r
186         : struct_declaration+\r
187         ;\r
188 \r
189 struct_declaration\r
190         : specifier_qualifier_list struct_declarator_list ';'\r
191         ;\r
192 \r
193 specifier_qualifier_list\r
194         : ( type_qualifier | type_specifier )+\r
195         ;\r
196 \r
197 struct_declarator_list\r
198         : struct_declarator (',' struct_declarator)*\r
199         ;\r
200 \r
201 struct_declarator\r
202         : declarator (':' constant_expression)?\r
203         | ':' constant_expression\r
204         ;\r
205 \r
206 enum_specifier\r
207 options {k=3;}\r
208         : 'enum' '{' enumerator_list '}'\r
209         | 'enum' IDENTIFIER '{' enumerator_list '}'\r
210         | 'enum' IDENTIFIER\r
211         ;\r
212 \r
213 enumerator_list\r
214         : enumerator (',' enumerator)*\r
215         ;\r
216 \r
217 enumerator\r
218         : IDENTIFIER ('=' constant_expression)?\r
219         ;\r
220 \r
221 type_qualifier\r
222         : 'const'\r
223         | 'volatile'\r
224         | 'IN'\r
225         | 'OUT'\r
226         | 'OPTIONAL'\r
227         | 'CONST'\r
228         ;\r
229 \r
230 declarator\r
231         : ('EFIAPI')? pointer? direct_declarator\r
232         | pointer\r
233         ;\r
234 \r
235 direct_declarator\r
236         : IDENTIFIER declarator_suffix*\r
237         | '(' declarator ')' declarator_suffix+\r
238         ;\r
239 \r
240 declarator_suffix\r
241         :   '[' constant_expression ']'\r
242     |   '[' ']'\r
243     |   '(' parameter_type_list ')'\r
244     |   '(' identifier_list ')'\r
245     |   '(' ')'\r
246         ;\r
247 \r
248 pointer\r
249         : '*' type_qualifier+ pointer?\r
250         | '*' pointer\r
251         | '*'\r
252         ;\r
253 \r
254 parameter_type_list\r
255         : parameter_list (',' '...')?\r
256         ;\r
257 \r
258 parameter_list\r
259         : parameter_declaration (',' ('OPTIONAL')? parameter_declaration)*\r
260         ;\r
261 \r
262 parameter_declaration\r
263         : declaration_specifiers (declarator|abstract_declarator)* ('OPTIONAL')?\r
264         //accomerdate user-defined type only, no declarator follow.\r
265         | IDENTIFIER\r
266         ;\r
267 \r
268 identifier_list\r
269         : IDENTIFIER\r
270         (',' IDENTIFIER)*\r
271         ;\r
272 \r
273 type_name\r
274         : specifier_qualifier_list abstract_declarator?\r
275         | type_id\r
276         ;\r
277 \r
278 abstract_declarator\r
279         : pointer direct_abstract_declarator?\r
280         | direct_abstract_declarator\r
281         ;\r
282 \r
283 direct_abstract_declarator\r
284         :       ( '(' abstract_declarator ')' | abstract_declarator_suffix ) abstract_declarator_suffix*\r
285         ;\r
286 \r
287 abstract_declarator_suffix\r
288         :       '[' ']'\r
289         |       '[' constant_expression ']'\r
290         |       '(' ')'\r
291         |       '(' parameter_type_list ')'\r
292         ;\r
293         \r
294 initializer\r
295 \r
296         : assignment_expression\r
297         | '{' initializer_list ','? '}'\r
298         ;\r
299 \r
300 initializer_list\r
301         : initializer (',' initializer )*\r
302         ;\r
303 \r
304 // E x p r e s s i o n s\r
305 \r
306 argument_expression_list\r
307         :   assignment_expression (',' assignment_expression)*\r
308         ;\r
309 \r
310 additive_expression\r
311         : (multiplicative_expression) ('+' multiplicative_expression | '-' multiplicative_expression)*\r
312         ;\r
313 \r
314 multiplicative_expression\r
315         : (cast_expression) ('*' cast_expression | '/' cast_expression | '%' cast_expression)*\r
316         ;\r
317 \r
318 cast_expression\r
319         : '(' type_name ')' cast_expression\r
320         | unary_expression\r
321         ;\r
322 \r
323 unary_expression\r
324         : postfix_expression\r
325         | '++' unary_expression\r
326         | '--' unary_expression\r
327         | unary_operator cast_expression\r
328         | 'sizeof' unary_expression\r
329         | 'sizeof' '(' type_name ')'\r
330         ;\r
331 \r
332 postfix_expression\r
333         :   p=primary_expression\r
334         (   '[' expression ']'\r
335         |   '(' a=')'{self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $a.line, $a.charPositionInLine, $p.text, '')}\r
336         |   '(' c=argument_expression_list b=')' {self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $b.line, $b.charPositionInLine, $p.text, $c.text)}\r
337         |   '.' IDENTIFIER\r
338         |   '*' IDENTIFIER\r
339         |   '->' IDENTIFIER\r
340         |   '++'\r
341         |   '--'\r
342         )*\r
343         ;\r
344 \r
345 unary_operator\r
346         : '&'\r
347         | '*'\r
348         | '+'\r
349         | '-'\r
350         | '~'\r
351         | '!'\r
352         ;\r
353 \r
354 primary_expression\r
355         : IDENTIFIER\r
356         | constant\r
357         | '(' expression ')'\r
358         ;\r
359 \r
360 constant\r
361     :   HEX_LITERAL\r
362     |   OCTAL_LITERAL\r
363     |   DECIMAL_LITERAL\r
364     |   CHARACTER_LITERAL\r
365     |   STRING_LITERAL+\r
366     |   FLOATING_POINT_LITERAL\r
367     ;\r
368 \r
369 /////\r
370 \r
371 expression\r
372         : assignment_expression (',' assignment_expression)*\r
373         ;\r
374 \r
375 constant_expression\r
376         : conditional_expression\r
377         ;\r
378 \r
379 assignment_expression\r
380         : lvalue assignment_operator assignment_expression\r
381         | conditional_expression\r
382         ;\r
383         \r
384 lvalue\r
385         :       unary_expression\r
386         ;\r
387 \r
388 assignment_operator\r
389         : '='\r
390         | '*='\r
391         | '/='\r
392         | '%='\r
393         | '+='\r
394         | '-='\r
395         | '<<='\r
396         | '>>='\r
397         | '&='\r
398         | '^='\r
399         | '|='\r
400         ;\r
401 \r
402 conditional_expression\r
403         : e=logical_or_expression ('?' expression ':' conditional_expression {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)})?\r
404         ;\r
405 \r
406 logical_or_expression\r
407         : logical_and_expression ('||' logical_and_expression)*\r
408         ;\r
409 \r
410 logical_and_expression\r
411         : inclusive_or_expression ('&&' inclusive_or_expression)*\r
412         ;\r
413 \r
414 inclusive_or_expression\r
415         : exclusive_or_expression ('|' exclusive_or_expression)*\r
416         ;\r
417 \r
418 exclusive_or_expression\r
419         : and_expression ('^' and_expression)*\r
420         ;\r
421 \r
422 and_expression\r
423         : equality_expression ('&' equality_expression)*\r
424         ;\r
425 equality_expression\r
426         : relational_expression (('=='|'!=') relational_expression )*\r
427         ;\r
428 \r
429 relational_expression\r
430         : shift_expression (('<'|'>'|'<='|'>=') shift_expression)*\r
431         ;\r
432 \r
433 shift_expression\r
434         : additive_expression (('<<'|'>>') additive_expression)*\r
435         ;\r
436 \r
437 // S t a t e m e n t s\r
438 \r
439 statement\r
440         : labeled_statement\r
441         | compound_statement\r
442         | expression_statement\r
443         | selection_statement\r
444         | iteration_statement\r
445         | jump_statement\r
446         | macro_statement\r
447         | declaration\r
448         ;\r
449 \r
450 macro_statement\r
451         : IDENTIFIER '(' (IDENTIFIER | declaration*  statement_list?) ')'\r
452         ;\r
453         \r
454 labeled_statement\r
455         : IDENTIFIER ':' statement\r
456         | 'case' constant_expression ':' statement\r
457         | 'default' ':' statement\r
458         ;\r
459 \r
460 compound_statement\r
461         : '{' declaration* statement_list? '}'\r
462         ;\r
463 \r
464 statement_list\r
465         : statement+\r
466         ;\r
467 \r
468 expression_statement\r
469         : ';'\r
470         | expression ';'\r
471         ;\r
472 \r
473 selection_statement\r
474         : '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
475         | 'switch' '(' expression ')' statement\r
476         ;\r
477 \r
478 iteration_statement\r
479         : 'while' '(' e=expression ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}\r
480         | 'do' statement 'while' '(' e=expression ')' ';' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)}\r
481         | '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
482         ;\r
483 \r
484 jump_statement\r
485         : 'goto' IDENTIFIER ';'\r
486         | 'continue' ';'\r
487         | 'break' ';'\r
488         | 'return' ';'\r
489         | 'return' expression ';'\r
490         ;\r
491 \r
492 IDENTIFIER\r
493         :       LETTER (LETTER|'0'..'9')*\r
494         ;\r
495         \r
496 fragment\r
497 LETTER\r
498         :       '$'\r
499         |  'A'..'Z'\r
500         |  'a'..'z'\r
501         |       '_'\r
502         ;\r
503 \r
504 CHARACTER_LITERAL\r
505     :   ('L')? '\'' ( EscapeSequence | ~('\''|'\\') ) '\''\r
506     ;\r
507 \r
508 STRING_LITERAL\r
509     :  ('L')? '"' ( EscapeSequence | ~('\\'|'"') )* '"'\r
510     ;\r
511     \r
512 HEX_LITERAL : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ;\r
513 \r
514 DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ;\r
515 \r
516 OCTAL_LITERAL : '0' ('0'..'7')+ IntegerTypeSuffix? ;\r
517 \r
518 fragment\r
519 HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;\r
520 \r
521 fragment\r
522 IntegerTypeSuffix\r
523         :       ('u'|'U')? ('l'|'L')\r
524         |       ('u'|'U')  ('l'|'L')? ('l'|'L')?\r
525         ;\r
526 \r
527 FLOATING_POINT_LITERAL\r
528     :   ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?\r
529     |   '.' ('0'..'9')+ Exponent? FloatTypeSuffix?\r
530     |   ('0'..'9')+ Exponent FloatTypeSuffix?\r
531     |   ('0'..'9')+ Exponent? FloatTypeSuffix\r
532         ;\r
533 \r
534 fragment\r
535 Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;\r
536 \r
537 fragment\r
538 FloatTypeSuffix : ('f'|'F'|'d'|'D') ;\r
539 \r
540 fragment\r
541 EscapeSequence\r
542     :  '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')\r
543     |   OctalEscape\r
544     ;\r
545 \r
546 fragment\r
547 OctalEscape\r
548     :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')\r
549     |   '\\' ('0'..'7') ('0'..'7')\r
550     |   '\\' ('0'..'7')\r
551     ;\r
552 \r
553 fragment\r
554 UnicodeEscape\r
555     :   '\\' 'u' HexDigit HexDigit HexDigit HexDigit\r
556     ;\r
557 \r
558 WS  :  (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}\r
559     ;\r
560 \r
561 // ingore '\' of line concatenation\r
562 BS  : ('\\') {$channel=HIDDEN;}\r
563     ;\r
564     \r
565 // ingore function modifiers\r
566 //FUNC_MODIFIERS  : 'EFIAPI' {$channel=HIDDEN;}\r
567 //    ;\r
568         \r
569 UnicodeVocabulary\r
570     : '\u0003'..'\uFFFE'\r
571     ;\r
572 COMMENT\r
573     :   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}\r
574     ;\r
575 \r
576 \r
577 LINE_COMMENT\r
578     : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}\r
579     ;\r
580 \r
581 // ignore #line info for now\r
582 LINE_COMMAND \r
583     : '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}\r
584     ;\r