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