/*============================================================================
Name : CExpression.g
Author : luqi
Version : 0.1
Copyright : Your copyright notice
Description : C99 - Expression - have tested <C99.pdf 6.5>
mock type_name and initializer_list rule
============================================================================*/
grammar CExpression;
options {
language = Java;
superClass = DebugParser;
//@ superClass = DebugLexer;
//output = AST;
}
@header
{
package c99.cexpression;
import util.DebugParser;
}
@lexer::header
{
package c99.cexpression;
import util.DebugLexer;
}
/*==========================================================================================================
* Mock Grammar for type_name and initializer_list
*=========================================================================================================*/
type_name : 'type_name'
;
initializer_list : 'initializer_list'
;
/*==========================================================================================================
* 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' unary_expression
| 'sizeof' '(' type_name ')'
;
unary_operator : '&'
| '*'
| '+'
| '-'
| '~'
| '!'
;
cast_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
| 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;}
;