audk/BaseTools/Source/Python/Ecc/CParser4/C.g4

632 lines
16 KiB
ANTLR

/* @file
This file is used to be the grammar file of ECC tool
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
*/
grammar C;
options {
language=Python;
}
@header {
## @file
# The file defines the parser for C source files.
#
# THIS FILE IS AUTO-GENENERATED. PLEASE DON NOT MODIFY THIS FILE.
# This file is generated by running:
# java org.antlr.Tool C.g
#
# Copyright (c) 2009 - 2010, Intel Corporation All rights reserved.
#
# This program and the accompanying materials are licensed and made available
# under the terms and conditions of the BSD License which accompanies this
# distribution. The full text of the license may be found at:
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
import Ecc.CodeFragment as CodeFragment
import Ecc.FileProfile as FileProfile
}
@members {
def printTokenInfo(self, line, offset, tokenText):
print(str(line)+ ',' + str(offset) + ':' + str(tokenText))
def StorePredicateExpression(self, StartLine, StartOffset, EndLine, EndOffset, Text):
PredExp = CodeFragment.PredicateExpression(Text, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.PredicateExpressionList.append(PredExp)
def StoreEnumerationDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text):
EnumDef = CodeFragment.EnumerationDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.EnumerationDefinitionList.append(EnumDef)
def StoreStructUnionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text):
SUDef = CodeFragment.StructUnionDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.StructUnionDefinitionList.append(SUDef)
def StoreTypedefDefinition(self, StartLine, StartOffset, EndLine, EndOffset, FromText, ToText):
Tdef = CodeFragment.TypedefDefinition(FromText, ToText, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.TypedefDefinitionList.append(Tdef)
def StoreFunctionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText, LeftBraceLine, LeftBraceOffset, DeclLine, DeclOffset):
FuncDef = CodeFragment.FunctionDefinition(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset), (LeftBraceLine, LeftBraceOffset), (DeclLine, DeclOffset))
FileProfile.FunctionDefinitionList.append(FuncDef)
def StoreVariableDeclaration(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText):
VarDecl = CodeFragment.VariableDeclaration(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.VariableDeclarationList.append(VarDecl)
def StoreFunctionCalling(self, StartLine, StartOffset, EndLine, EndOffset, FuncName, ParamList):
FuncCall = CodeFragment.FunctionCalling(FuncName, ParamList, (StartLine, StartOffset), (EndLine, EndOffset))
FileProfile.FunctionCallingList.append(FuncCall)
}
translation_unit
: external_declaration*
;
external_declaration
: ( declaration_specifiers? declarator declaration* '{' )
| function_definition
| declaration
| macro_statement (';')?
;
function_definition
locals [String ModifierText = '', String DeclText = '', int LBLine = 0, int LBOffset = 0, int DeclLine = 0, int DeclOffset = 0]
@init {
ModifierText = '';
DeclText = '';
LBLine = 0;
LBOffset = 0;
DeclLine = 0;
DeclOffset = 0;
}
@after{
self.StoreFunctionDefinition(localctx.start.line, localctx.start.column, localctx.stop.line, localctx.stop.column, ModifierText, DeclText, LBLine, LBOffset, DeclLine, DeclOffset)
}
: d=declaration_specifiers? declarator
( declaration+ a=compound_statement // K&R style
| b=compound_statement // ANSI style
) {
if localctx.d != None:
ModifierText = $declaration_specifiers.text
else:
ModifierText = ''
DeclText = $declarator.text
DeclLine = $declarator.start.line
DeclOffset = $declarator.start.column
if localctx.a != None:
LBLine = $a.start.line
LBOffset = $a.start.column
else:
LBLine = $b.start.line
LBOffset = $b.start.column
}
;
declaration_specifiers
: ( storage_class_specifier
| type_specifier
| type_qualifier
)+
;
declaration
: a='typedef' b=declaration_specifiers? c=init_declarator_list d=';'
{
if localctx.b is not None:
self.StoreTypedefDefinition(localctx.a.line, localctx.a.column, $d.line, localctx.d.column, $b.text, $c.text)
else:
self.StoreTypedefDefinition(localctx.a.line, localctx.a.column, $d.line, localctx.d.column, '', $c.text)
}
| s=declaration_specifiers t=init_declarator_list? e=';'
{
if localctx.t is not None:
self.StoreVariableDeclaration($s.start.line, $s.start.column, $t.start.line, $t.start.column, $s.text, $t.text)
}
;
init_declarator_list
: init_declarator (',' init_declarator)*
;
init_declarator
: declarator ('=' initializer)?
;
storage_class_specifier
: 'extern'
| 'static'
| 'auto'
| 'register'
| 'STATIC'
;
type_specifier
: 'void'
| 'char'
| 'short'
| 'int'
| 'long'
| 'float'
| 'double'
| 'signed'
| 'unsigned'
| s=struct_or_union_specifier
{
if localctx.s.stop is not None:
self.StoreStructUnionDefinition($s.start.line, $s.start.column, $s.stop.line, $s.stop.column, $s.text)
}
| e=enum_specifier
{
if localctx.e.stop is not None:
self.StoreEnumerationDefinition($e.start.line, $e.start.column, $e.stop.line, $e.stop.column, $e.text)
}
| (IDENTIFIER type_qualifier* declarator)
| type_id
;
type_id
: IDENTIFIER
//{self.printTokenInfo($a.line, $a.pos, $a.text)}
;
struct_or_union_specifier
: struct_or_union IDENTIFIER? '{' struct_declaration_list '}'
| struct_or_union IDENTIFIER
;
struct_or_union
: 'struct'
| 'union'
;
struct_declaration_list
: struct_declaration+
;
struct_declaration
: specifier_qualifier_list struct_declarator_list ';'
;
specifier_qualifier_list
: ( type_qualifier | type_specifier )+
;
struct_declarator_list
: struct_declarator (',' struct_declarator)*
;
struct_declarator
: declarator (':' constant_expression)?
| ':' constant_expression
;
enum_specifier
: 'enum' '{' enumerator_list ','? '}'
| 'enum' IDENTIFIER '{' enumerator_list ','? '}'
| 'enum' IDENTIFIER
;
enumerator_list
: enumerator (',' enumerator)*
;
enumerator
: IDENTIFIER ('=' constant_expression)?
;
type_qualifier
: 'const'
| 'volatile'
| 'IN'
| 'OUT'
| 'OPTIONAL'
| 'CONST'
| 'UNALIGNED'
| 'VOLATILE'
| 'GLOBAL_REMOVE_IF_UNREFERENCED'
| 'EFIAPI'
| 'EFI_BOOTSERVICE'
| 'EFI_RUNTIMESERVICE'
| 'PACKED'
;
declarator
: pointer? ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? direct_declarator
// | ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? pointer? direct_declarator
| pointer
;
direct_declarator
: IDENTIFIER declarator_suffix*
| '(' ('EFIAPI')? declarator ')' declarator_suffix+
;
declarator_suffix
: '[' constant_expression ']'
| '[' ']'
| '(' parameter_type_list ')'
| '(' identifier_list ')'
| '(' ')'
;
pointer
: '*' type_qualifier+ pointer?
| '*' pointer
| '*'
;
parameter_type_list
: parameter_list (',' ('OPTIONAL')? '...')?
;
parameter_list
: parameter_declaration (',' ('OPTIONAL')? parameter_declaration)*
;
parameter_declaration
: declaration_specifiers (declarator|abstract_declarator)* ('OPTIONAL')?
//accomerdate user-defined type only, no declarator follow.
| pointer* IDENTIFIER
;
identifier_list
: IDENTIFIER
(',' IDENTIFIER)*
;
type_name
: specifier_qualifier_list abstract_declarator?
| type_id
;
abstract_declarator
: pointer direct_abstract_declarator?
| direct_abstract_declarator
;
direct_abstract_declarator
: ( '(' abstract_declarator ')' | abstract_declarator_suffix ) abstract_declarator_suffix*
;
abstract_declarator_suffix
: '[' ']'
| '[' constant_expression ']'
| '(' ')'
| '(' parameter_type_list ')'
;
initializer
: assignment_expression
| '{' initializer_list ','? '}'
;
initializer_list
: initializer (',' initializer )*
;
// E x p r e s s i o n s
argument_expression_list
: assignment_expression ('OPTIONAL')? (',' assignment_expression ('OPTIONAL')?)*
;
additive_expression
: (multiplicative_expression) ('+' multiplicative_expression | '-' multiplicative_expression)*
;
multiplicative_expression
: (cast_expression) ('*' cast_expression | '/' cast_expression | '%' cast_expression)*
;
cast_expression
: '(' type_name ')' cast_expression
| unary_expression
;
unary_expression
: postfix_expression
| '++' unary_expression
| '--' unary_expression
| unary_operator cast_expression
| 'sizeof' unary_expression
| 'sizeof' '(' type_name ')'
;
postfix_expression
locals [FuncCallText='']
@init
{
self.FuncCallText=''
}
: p=primary_expression {self.FuncCallText += $p.text}
( '[' expression ']'
| '(' a=')'{self.StoreFunctionCalling($p.start.line, $p.start.column, $a.line, localctx.a.column, self.FuncCallText, '')}
| '(' c=argument_expression_list b=')' {self.StoreFunctionCalling($p.start.line, $p.start.column, $b.line, localctx.b.column, self.FuncCallText, $c.text)}
| '(' macro_parameter_list ')'
| '.' x=IDENTIFIER {self.FuncCallText += '.' + $x.text}
| '*' y=IDENTIFIER {self.FuncCallText = $y.text}
| '->' z=IDENTIFIER {self.FuncCallText += '->' + $z.text}
| '++'
| '--'
)*
;
macro_parameter_list
: parameter_declaration (',' parameter_declaration)*
;
unary_operator
: '&'
| '*'
| '+'
| '-'
| '~'
| '!'
;
primary_expression
: IDENTIFIER
| constant
| '(' expression ')'
;
constant
: HEX_LITERAL
| OCTAL_LITERAL
| DECIMAL_LITERAL
| CHARACTER_LITERAL
| (IDENTIFIER* STRING_LITERAL+)+ IDENTIFIER*
| FLOATING_POINT_LITERAL
;
/////
expression
: assignment_expression (',' assignment_expression)*
;
constant_expression
: conditional_expression
;
assignment_expression
: lvalue assignment_operator assignment_expression
| conditional_expression
;
lvalue
: unary_expression
;
assignment_operator
: '='
| '*='
| '/='
| '%='
| '+='
| '-='
| '<<='
| '>>='
| '&='
| '^='
| '|='
;
conditional_expression
: e=logical_or_expression ('?' expression ':' conditional_expression {self.StorePredicateExpression($e.start.line, $e.start.column, $e.stop.line, $e.stop.column, $e.text)})?
;
logical_or_expression
: logical_and_expression ('||' logical_and_expression)*
;
logical_and_expression
: inclusive_or_expression ('&&' inclusive_or_expression)*
;
inclusive_or_expression
: exclusive_or_expression ('|' exclusive_or_expression)*
;
exclusive_or_expression
: and_expression ('^' and_expression)*
;
and_expression
: equality_expression ('&' equality_expression)*
;
equality_expression
: relational_expression (('=='|'!=') relational_expression )*
;
relational_expression
: shift_expression (('<'|'>'|'<='|'>=') shift_expression)*
;
shift_expression
: additive_expression (('<<'|'>>') additive_expression)*
;
// S t a t e m e n t s
statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
| macro_statement
| asm2_statement
| asm1_statement
| asm_statement
| declaration
;
asm2_statement
: '__asm__'? IDENTIFIER '(' (~(';'))* ')' ';'
;
asm1_statement
: '_asm' '{' (~('}'))* '}'
;
asm_statement
: '__asm' '{' (~('}'))* '}'
;
macro_statement
: IDENTIFIER '(' declaration* statement_list? expression? ')'
;
labeled_statement
: IDENTIFIER ':' statement
| 'case' constant_expression ':' statement
| 'default' ':' statement
;
compound_statement
: '{' declaration* statement_list? '}'
;
statement_list
: statement+
;
expression_statement
: ';'
| expression ';'
;
selection_statement
: 'if' '(' e=expression ')' {self.StorePredicateExpression($e.start.line, $e.start.column, $e.stop.line, $e.stop.column, $e.text)} statement (:'else' statement)?
| 'switch' '(' expression ')' statement
;
iteration_statement
: 'while' '(' e=expression ')' statement {self.StorePredicateExpression($e.start.line, $e.start.column, $e.stop.line, $e.stop.column, $e.text)}
| 'do' statement 'while' '(' e=expression ')' ';' {self.StorePredicateExpression($e.start.line, $e.start.column, $e.stop.line, $e.stop.column, $e.text)}
//| 'for' '(' expression_statement e=expression_statement expression? ')' statement {self.StorePredicateExpression($e.start.line, $e.start.column, $e.stop.line, $e.stop.column, $e.text)}
;
jump_statement
: 'goto' IDENTIFIER ';'
| 'continue' ';'
| 'break' ';'
| 'return' ';'
| 'return' expression ';'
;
IDENTIFIER
: LETTER (LETTER|'0'..'9')*
;
fragment
LETTER
: '$'
| 'A'..'Z'
| 'a'..'z'
| '_'
;
CHARACTER_LITERAL
: ('L')? '\'' ( EscapeSequence | ~('\''|'\\') ) '\''
;
STRING_LITERAL
: ('L')? '"' ( EscapeSequence | ~('\\'|'"') )* '"'
;
HEX_LITERAL : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ;
DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ;
OCTAL_LITERAL : '0' ('0'..'7')+ IntegerTypeSuffix? ;
fragment
HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment
IntegerTypeSuffix
: ('u'|'U')
| ('l'|'L')
| ('u'|'U') ('l'|'L')
| ('u'|'U') ('l'|'L') ('l'|'L')
;
FLOATING_POINT_LITERAL
: ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?
| '.' ('0'..'9')+ Exponent? FloatTypeSuffix?
| ('0'..'9')+ Exponent FloatTypeSuffix?
| ('0'..'9')+ Exponent? FloatTypeSuffix
;
fragment
Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
fragment
FloatTypeSuffix : ('f'|'F'|'d'|'D') ;
fragment
EscapeSequence
: '\\' ('b'|'t'|'n'|'f'|'r'|'\''|'\\')
| OctalEscape
;
fragment
OctalEscape
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UnicodeEscape
: '\\' 'u' HexDigit HexDigit HexDigit HexDigit
;
WS : (' '|'\r'|'\t'|'\u000C'|'\n')
-> channel(HIDDEN)
;
// ingore '\' of line concatenation
BS : ('\\')
-> channel(HIDDEN)
;
UnicodeVocabulary
: '\u0003'..'\uFFFE'
;
COMMENT
: '/*' .*? '*/'
-> channel(HIDDEN)
;
LINE_COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n'
-> channel(HIDDEN)
;
// ignore #line info for now
LINE_COMMAND
: '#' ~('\n'|'\r')* '\r'? '\n'
-> channel(HIDDEN)
;