/*============================================================================
Name : CDeclaration.g
Author : luqi
Version : 0.1
Copyright : Your copyright notice
Description : C99 - Declaration - have not tested yet <C99.pdf 6.7>
============================================================================*/
grammar CDeclaration;
options {
language = Java;
superClass = DebugParser;
//@ superClass = DebugLexer;
//output = AST;
}
@header
{
package c99.cdeclaration;
import util.DebugParser;
}
@lexer::header
{
package c99.cdeclaration;
import util.DebugLexer;
}
/*==========================================================================================================
* Declarations Grammar
*=========================================================================================================*/
declaration : declaration_specifiers init_declarator_list ?
;
declaration_specifiers : ( storage_class_specifier
| type_specifier
| type_qualifier
| function_specifier
) +
;
init_declarator_list : init_declarator (',' init_declarator)*
;
init_declarator : declarator ( '=' initializer) ?
;
storage_class_specifier : 'typedef'
| 'extern'
| 'static'
| 'auto'
| 'register'
;
type_specifier : 'void'
| 'char'
| 'short'
| 'int'
| 'long'
| 'float'
| 'double'
| 'signed'
| 'unsigned'
| '_Bool'
| '_Complex'
| '_Imaginary'
| struct_or_union_specifier
| enum_specifier
| typedef_name
;
// need a improve here
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_specifier | type_qualifier) +
;
struct_declarator_list : struct_declarator (',' struct_declarator) *
;
struct_declarator : declarator (':' constant_expression)?
| ':' constant_expression
;
enum_specifier : 'enum' IDENTIFIER ? '{' enumerator_list ','? '}'
| 'enum' IDENTIFIER
;
enumerator_list : enumerator (',' enumerator)*
;
enumerator : ENUMERATION_CONSTANT ('=' constant_expression) ?
;
type_qualifier : 'const'
| 'restrict'
| 'volatile'
;
function_specifier : 'inline'
;
declarator : pointer ? direct_declarator
;
direct_declarator : ( IDENTIFIER | '(' declarator ')' )
(
'[' type_qualifier_list ? assignment_expression ? ']'
|'[' 'static' type_qualifier_list ? assignment_expression ']'
|'[' type_qualifier_list 'static' assignment_expression ']'
|'[' type_qualifier_list ? '*' ']'
|'(' parameter_type_list ')'
//|'(' identifier_list ? ')'
)*
;
// need a improve here remark
pointer : ('*' type_qualifier_list ?) +
;
type_qualifier_list : (type_qualifier) +
;
parameter_type_list : parameter_list (',' '...')?
;
parameter_list : parameter_declaration (',' parameter_declaration) *
;
// need a check
parameter_declaration : declaration_specifiers
( (declarator)=>declarator
| (abstract_declarator)=>abstract_declarator
) ?
;
identifier_list : IDENTIFIER (',' IDENTIFIER )*
;
type_name : //'type_name'
specifier_qualifier_list abstract_declarator ?
;
//need to check
//abstract_declarator : pointer
//| pointer ? direct_abstract_declarator
//;
abstract_declarator : pointer direct_abstract_declarator?
| direct_abstract_declarator
;
direct_abstract_declarator : ( '(' abstract_declarator ')'
| '[' assignment_expression ? ']'
| '[' '*' ']'
| '(' parameter_type_list ? ')'
)
(
'[' assignment_expression ? ']'
|'[' '*' ']'
|'(' parameter_type_list ? ')'
) *
;
typedef_name : { 1 == 2}? IDENTIFIER
;
initializer : assignment_expression
| '{' initializer_list ',' ? '}'
;
initializer_list : designation ? initializer (',' designation ? initializer) *
;
designation : designator_list '='
;
designator_list : designator +
;
designator : '[' constant_expression ']'
| '.' IDENTIFIER
;
/*==========================================================================================================
* Expression Grammar
*=========================================================================================================*/
primary_expression : IDENTIFIER
| CONSTANT
| STRING_LITERAL
| '(' expression ')'
;
postfix_expression : primary_expression
( '[' expression ']'
| '(' argument_expression_list ? ')'
| '.' IDENTIFIER
| '->' IDENTIFIER
| '++'
| '--'
//| '(' type_name ')' '{' initializer_list ','? '}'
)*
;
argument_expression_list : assignment_expression (',' assignment_expression)*
;
unary_expression : postfix_expression
| '++' unary_expression
| '--' unary_expression
| unary_operator cast_expression
| ('sizeof' '(' type_name ')')=>'sizeof' '(' type_name ')'
| ('sizeof' unary_expression)=> 'sizeof' unary_expression
;
unary_operator : '&'
| '*'
| '+'
| '-'
| '~'
| '!'
;
cast_expression : (unary_expression)=> unary_expression
| '(' type_name ')' cast_expression
;
multiplicative_expression : cast_expression
(('*' | '/' | '%') cast_expression)*
;
additive_expression : multiplicative_expression
(('+' | '-') multiplicative_expression)*
;
shift_expression : additive_expression
(('<<' | '>>') additive_expression)*
;
relational_expression : shift_expression
(('<' | '>' | '<=' | '>=') shift_expression)*
;
equality_expression : relational_expression
(('==' | '!=') relational_expression)*
;
and_expression : equality_expression ( '&' equality_expression)*
;
exclusive_or_expression : and_expression ( '^' and_expression)*
;
inclusive_or_expression : exclusive_or_expression
( '|' exclusive_or_expression)*
;
logical_and_expression : inclusive_or_expression
( '&&' inclusive_or_expression)*
;
logical_or_expression : logical_and_expression
( '||' logical_and_expression)*
;
conditional_expression : logical_or_expression
('?' expression ':' conditional_expression)?
;
assignment_expression : (unary_expression assignment_operator assignment_expression)=>unary_expression assignment_operator assignment_expression
// unary_expression assignment_operator assignment_expression
| conditional_expression
;
assignment_operator : '='
| '*='
| '/='
| '%='
| '+='
| '-='
| '<<='
| '>>='
| '&='
| '^='
| '|='
;
expression : assignment_expression
(',' assignment_expression) *
;
constant_expression : conditional_expression
;
/*==========================================================================================================
* Lexer Grammar
*=========================================================================================================*/
KEYWORD : 'auto' | 'break' | 'case' | 'char' | 'const' | 'continue'
| 'default' | 'do' | 'double' | 'else' | 'enum' | 'extern'
| 'float' | 'for' | 'goto' | 'if' | 'inline' | 'int'
| 'long' | 'register' | 'restrict' | 'return' | 'short' | 'signed'
| 'sizeof' | 'static' | 'struct' | 'switch' | 'typedef' | 'union'
| 'unsigned' | 'void' | 'volatile' | 'while' | '_Bool' | '_Complex'
| '_Imaginary'
;
IDENTIFIER : IDENTIFIER_NONDIGIT ( IDENTIFIER_NONDIGIT | DIGIT ) *
;
fragment
IDENTIFIER_NONDIGIT : NONDIGIT
| UNIVERSAL_CHARACTER_NAME
;
fragment
NONDIGIT : 'a' .. 'z'
| 'A' .. 'Z'
| '_'
;
fragment
DIGIT : '0' .. '9'
;
fragment
UNIVERSAL_CHARACTER_NAME : '\\u' HEX_QUAD
| '\\U' HEX_QUAD HEX_QUAD
;
fragment
HEX_QUAD : HEXADECIMAL_DIGIT HEXADECIMAL_DIGIT HEXADECIMAL_DIGIT HEXADECIMAL_DIGIT
;
CONSTANT : INTEGER_CONSTANT
| FLOATING_CONSTANT
//| ENUMERATION_CONSTANT
| CHARACTER_CONSTANT
;
fragment
INTEGER_CONSTANT : DECIMAL_CONSTANT INTEGER_SUFFIX ?
| OCTAL_CONSTANT INTEGER_SUFFIX ?
| HEXADECIMAL_CONSTANT INTEGER_SUFFIX ?
;
fragment
INTEGER_SUFFIX : UNSIGNED_SUFFIX LONG_SUFFIX ?
| UNSIGNED_SUFFIX LONG_LONG_SUFFIX
| LONG_SUFFIX UNSIGNED_SUFFIX ?
| LONG_LONG_SUFFIX UNSIGNED_SUFFIX ?
;
fragment
UNSIGNED_SUFFIX : 'u'
| 'U'
;
fragment
LONG_SUFFIX : 'l'
| 'L'
;
fragment
LONG_LONG_SUFFIX : 'll'
| 'LL'
;
fragment
DECIMAL_CONSTANT : NONZERO_DIGIT (DIGIT) *
;
fragment
OCTAL_CONSTANT : '0' (OCTAL_DIGIT) *
;
fragment
HEXADECIMAL_CONSTANT : HEXADECIMAL_PREFIX ( HEXADECIMAL_DIGIT )+
;
fragment
HEXADECIMAL_PREFIX : '0x'
| '0X'
;
fragment
NONZERO_DIGIT : '1' .. '9'
;
fragment
OCTAL_DIGIT : '0' .. '7'
;
fragment
HEXADECIMAL_DIGIT : '0' .. '9'
| 'a' .. 'f'
| 'A' .. 'F'
;
fragment
FLOATING_CONSTANT : DECIMAL_FLOATING_CONSTANT
| HEXADECIMAL_FLOATING_CONSTANT
;
fragment
DECIMAL_FLOATING_CONSTANT : FRACTIONAL_CONSTANT EXPONENT_PART ? FLOATING_SUFFIX ?
| DIGIT_SEQUENCE EXPONENT_PART FLOATING_SUFFIX ?
;
fragment
FRACTIONAL_CONSTANT : DIGIT_SEQUENCE ? '.' DIGIT_SEQUENCE
| DIGIT_SEQUENCE '.'
;
fragment
EXPONENT_PART : 'e' SIGN ? DIGIT_SEQUENCE
| 'E' SIGN ? DIGIT_SEQUENCE
;
fragment
SIGN : '+'
| '-'
;
fragment
DIGIT_SEQUENCE : DIGIT +
;
fragment
HEXADECIMAL_FLOATING_CONSTANT : HEXADECIMAL_PREFIX HEXADECIMAL_FRACTIONAL_CONSTANT BINARY_EXPONENT_PART FLOATING_SUFFIX ?
| HEXADECIMAL_PREFIX HEXADECIMAL_DIGIT_SEQUENCE BINARY_EXPONENT_PART FLOATING_SUFFIX ?
;
fragment
HEXADECIMAL_FRACTIONAL_CONSTANT : HEXADECIMAL_DIGIT_SEQUENCE ? '.' HEXADECIMAL_DIGIT_SEQUENCE
| HEXADECIMAL_DIGIT_SEQUENCE '.'
;
fragment
BINARY_EXPONENT_PART : 'p' SIGN ? DIGIT_SEQUENCE
| 'P' SIGN ? DIGIT_SEQUENCE
;
fragment
HEXADECIMAL_DIGIT_SEQUENCE : HEXADECIMAL_DIGIT +
;
fragment
FLOATING_SUFFIX : 'f'
| 'l'
| 'F'
| 'L'
;
fragment
ENUMERATION_CONSTANT : IDENTIFIER
;
fragment
CHARACTER_CONSTANT : '\'' C_CHAR_SEQUENCE '\''
| 'L\'' C_CHAR_SEQUENCE '\''
;
fragment
C_CHAR_SEQUENCE : C_CHAR +
;
fragment
C_CHAR : ~('\'' | '\\' )
| ESCAPE_SEQUENCE
;
fragment
ESCAPE_SEQUENCE : SIMPLE_ESCAPE_SEQUENCE
| OCTAL_ESCAPE_SEQUENCE
| HEXADECIMAL_ESCAPE_SEQUENCE
| UNIVERSAL_CHARACTER_NAME
;
fragment
SIMPLE_ESCAPE_SEQUENCE : '\\' ( '\'' | '"' | '?' | '\\' | 'a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v' )
;
fragment
OCTAL_ESCAPE_SEQUENCE : '\\' OCTAL_DIGIT // OCTAL_DIGIT OCTAL_DIGIT ? OCTAL_DIGIT ?
| '\\' OCTAL_DIGIT OCTAL_DIGIT
| ('\\' OCTAL_DIGIT OCTAL_DIGIT OCTAL_DIGIT )=> '\\' OCTAL_DIGIT OCTAL_DIGIT OCTAL_DIGIT
;
fragment
HEXADECIMAL_ESCAPE_SEQUENCE : '\\x' HEXADECIMAL_DIGIT +
;
STRING_LITERAL : '"' S_CHAR_SEQUENCE ? '"'
| 'L"' S_CHAR_SEQUENCE ? '"'
;
fragment
S_CHAR_SEQUENCE : S_CHAR +
;
fragment
S_CHAR : ~('"' | '\\' )
| ESCAPE_SEQUENCE
;
SINGLELINECOMMENT : '//' (~('\n'|'\r'))* ('\n'|'\r'('\n')?)? {$channel=HIDDEN;}
;
MULTILINECOMMENT : '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
;