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