📄 cpp_parser.g
字号:
bool fd = false; // For friend
StorageClass sc = scInvalid; // auto,register,static,extern,mutable
TypeQualifier tq = tqInvalid; // const,volatile // aka cv_qualifier See type_qualifier
TypeSpecifier ts = tsInvalid; // char,int,double, etc., class,struct,union
FunctionSpecifier fs = fsInvalid; // inline,virtual,explicit
}
:
{
// Global flags to allow for nested declarations
_td = false; // For typedef
_fd = false; // For friend
_sc = scInvalid; // For StorageClass // auto,register,static,extern,mutable
_tq = tqInvalid; // For TypeQualifier // aka cv_qualifier See type_qualifier
_ts = tsInvalid; // For TypeSpecifier
_fs = fsInvalid; // For FunctionSpecifier // inline,virtual,explicit
}
( (options {warnWhenFollowAmbig = false;}
: "typedef" {td=true;}
| "friend" {fd=true;}
| sc = storage_class_specifier // auto,register,static,extern,mutable
| tq = type_qualifier // const,volatile // aka cv_qualifier See type_qualifier
| fs = function_specifier // inline,virtual,explicit
| ("_declspec"|"__declspec") LPAREN ID RPAREN
)*
ts = type_specifier
(tq = type_qualifier)* // const,volatile // aka cv_qualifier See type_qualifier
)
{declarationSpecifier(td,fd,sc,tq,ts,fs);}
;
//storage_class_specifier
storage_class_specifier returns [CPPParser::StorageClass sc = scInvalid]
: "auto" {sc = scAUTO;}
| "register" {sc = scREGISTER;}
| "static" {sc = scSTATIC;}
| "extern" {sc = scEXTERN;}
| "mutable" {sc = scMUTABLE;}
;
//function_specifier
function_specifier returns [CPPParser::FunctionSpecifier fs = fsInvalid]
: ("inline"|"_inline"|"__inline") {fs = fsINLINE;}
| "virtual" {fs = fsVIRTUAL;}
| "explicit" {fs = fsEXPLICIT;}
;
//type_specifier
type_specifier returns [CPPParser::TypeSpecifier ts = tsInvalid]
{//char *s;
TypeQualifier tq = tqInvalid;
}
:
ts = simple_type_specifier
;
//simple_type_specifier
simple_type_specifier returns [CPPParser::TypeSpecifier ts = tsInvalid]
{
char *s;
ts = tsInvalid;
}
: (
{qualifiedItemIsOneOf(qiType|qiCtor)}?
s = qualified_type
|
("typename"|"enum"|ts = class_specifier)
s = qualified_type
{declaratorID(s,qiType);} // This stores typename name in dictionary
|
( "char" {ts |= tsCHAR;}
| "wchar_t" {ts |= tsWCHAR_T;}
| "bool" {ts |= tsBOOL;}
| "short" {ts |= tsSHORT;}
| "int" {ts |= tsINT;}
| ("_int8"|"__int8") {ts |= tsINT;}
| ("_int16"|"__int16") {ts |= tsINT;}
| ("_int32"|"__int32") {ts |= tsLONG;}
| ("_int64"|"__int64") {ts |= tsLONG;}
| ("_w64"|"__w64") {ts |= tsLONG;}
| "long" {ts |= tsLONG;}
| "signed" {ts |= tsSIGNED;}
| "unsigned" {ts |= tsUNSIGNED;}
| "float" {ts |= tsFLOAT;}
| "double" {ts |= tsDOUBLE;}
| "void" {ts |= tsVOID;}
)+
)
;
//qualified_type
qualified_type returns [char *qit = NULL]
{
char *so = NULL;
char qitem01[CPPParser_MaxQualifiedItemSize+1];
qitem01[0] = '\0';
}
:
// JEL 3/29/96 removed this predicate and moved it upwards to
// simple_type_specifier. This was done to allow parsing of ~ID to
// be a unary_expression, which was never reached with this
// predicate on
// {qualifiedItemIsOneOf(qiType|qiCtor)}?
so = scope_override
{
strcpy(qitem01, so);
}
id:ID
{
strcat(qitem01, (id->getText()).data());
qit = qitem01;
}
(options {warnWhenFollowAmbig = false;}:
LESSTHAN template_argument_list GREATERTHAN
)?
;
//class_specifier
class_specifier returns [CPPParser::TypeSpecifier ts = tsInvalid]
:
("class" {ts = tsCLASS;}
|"struct" {ts = tsSTRUCT;}
|"union" {ts = tsUNION;}
)
;
//type_qualifier
type_qualifier returns [CPPParser::TypeQualifier tq = tqInvalid] // aka cv_qualifier
:
("const" {tq = tqCONST;}
|"volatile" {tq = tqVOLATILE;}
)
;
//class_decl_or_def
class_decl_or_def [FunctionSpecifier fs]
{char *saveClass;
char *id;
char qid[CPPParser_MaxQualifiedItemSize+1];
TypeSpecifier ts = tsInvalid; // Available for use
}
:
("class" {ts = tsCLASS;}
|"struct" {ts = tsSTRUCT;}
|"union" {ts = tsUNION;}
)
(("_declspec"|"__declspec") LPAREN expression RPAREN)* // Temp for Evgeniy
( id = qualified_id
{strcpy(qid,id);}
(options{generateAmbigWarnings = false;}:
(SEMICOLON|member_declarator)=>
// Empty
{classForwardDeclaration(qid, ts, fs);} // This stores class name in dictionary
|
(base_clause)?
LCURLY
{saveClass = enclosingClass; enclosingClass = symbols->strdup(qid);
beginClassDefinition(qid, ts);} // This stores class name in dictionary
(member_declaration)*
{endClassDefinition();}
RCURLY
{enclosingClass = saveClass;}
)
|
LCURLY
{saveClass = enclosingClass; enclosingClass = "__anonymous";
beginClassDefinition("anonymous", ts);} // This stores "anonymous" name in dictionary
(member_declaration)*
{endClassDefinition();}
RCURLY
{enclosingClass = saveClass;}
)
;
//base_clause
base_clause
:
COLON base_specifier (COMMA base_specifier)*
;
//base_specifier
base_specifier
{char *qt;}
:
( "virtual" (access_specifier)? qt = qualified_type
| access_specifier ("virtual")? qt = qualified_type
| qt = qualified_type
)
;
//access_specifier
access_specifier
:
( "public"
| "protected"
| "private"
)
;
//enum_specifier
enum_specifier
{
char *id;
}
:
"enum"
(
LCURLY enumerator_list RCURLY
|
id = qualified_id
{beginEnumDefinition(id);} // This stores id name as an enum type in dictionary
(LCURLY enumerator_list RCURLY)?
{endEnumDefinition();}
)
;
//enumerator_list
enumerator_list
:
enumerator (COMMA (enumerator)? )* // Allows comma at end of list
;
//enumerator
enumerator
:
id:ID (ASSIGNEQUAL constant_expression)?
{enumElement((id->getText()).data());} // This stores id name in dictionary
;
/* This matches a generic qualified identifier ::T::B::foo
* (including OPERATOR).
* It might be a good idea to put T::~dtor in here
* as well, but id_expression in expr.g puts it in manually.
* Maybe not, 'cause many people use this assuming only A::B.
* How about a 'qualified_complex_id'?
*/
//qualified_id
qualified_id returns [char *qid = NULL]
{
char *so = NULL;
char *op = NULL;
char qitem02[CPPParser_MaxQualifiedItemSize+1];
qitem02[0] = '\0';
}
:
so = scope_override
{
strcpy(qitem02, so);
}
( id:ID {strcat(qitem02,(id->getText()).data());}
((LESSTHAN template_argument_list GREATERTHAN)=>
LESSTHAN template_argument_list GREATERTHAN)? // {strcat(qitem02,"<...>");}
|
OPERATOR op=optor
{strcat(qitem02,"operator"); strcat(qitem02,op);}
|
TILDE id_expression // 1/08/07
)
{
qid = qitem02;
}
;
//typeID
typeID
:
{isTypeName((LT(1)->getText()).data())}?
ID
;
//init_declarator_list
init_declarator_list
:
member_declarator (COMMA member_declarator)*
;
//member_declarator
member_declarator
:
((ID)? COLON constant_expression)=>(ID)? COLON constant_expression
|
declarator
(
(ASSIGNEQUAL OCTALINT SEMICOLON)=> ASSIGNEQUAL OCTALINT // The value must be zero (for pure virtual)
|
ASSIGNEQUAL
initializer
|
LPAREN expression_list RPAREN
)?
;
//initializer
initializer
:
remainder_expression // assignment_expression
|
LCURLY initializer (COMMA (initializer)? )* RCURLY // Allows comma at end of list
;
//declarator
declarator
:
(ptr_operator)=> ptr_operator // AMPERSAND or STAR etc.
declarator
|
direct_declarator
;
//direct_declarator
direct_declarator
{
char *id;
CPPParser::TypeQualifier tq;
}
:
(qualified_id LPAREN (RPAREN|declaration_specifiers) )=> // Must be function declaration
id = qualified_id
{if (_td==true) // This statement is a typedef
declaratorID(id,qiType);
else
declaratorID(id,qiFun);
}
LPAREN {declaratorParameterList(0);}
(parameter_list)?
RPAREN {declaratorEndParameterList(0);}
(tq = type_qualifier)*
(exception_specification)?
|
(qualified_id LPAREN qualified_id)=> // Must be class instantiation
id = qualified_id
{declaratorID(id,qiVar);}
LPAREN
expression_list
RPAREN
|
(qualified_id LSQUARE)=> // Must be array declaration
id = qualified_id
{if (_td==true) // This statement is a typedef
declaratorID(id,qiType); // This statement is a typedef
else
declaratorID(id,qiVar);
is_address = false; is_pointer = false;
}
(options {warnWhenFollowAmbig = false;}:
LSQUARE (constant_expression)? RSQUARE)+
{declaratorArray();}
|
(qualified_id RPAREN LPAREN)=> // Must be function declaration (see function_direct_declarator)
id = qualified_id
{if (_td==true) // This statement is a typedef
declaratorID(id,qiType); // This statement is a typedef
else
declaratorID(id,qiFun);
is_address = false; is_pointer = false;
}
|
id = qualified_id
{
if (_td==true)
{
declaratorID(id,qiType); // This statement is a typedef
}
else
declaratorID(id,qiVar);
is_address = false; is_pointer = false;
}
|
LPAREN declarator RPAREN
(options {warnWhenFollowAmbig = false;}:
declarator_suffix)? // DW 1/9/04 declarator_suffix made optional as failed on line 2956 in metrics.i
; // According to the grammar a declarator_suffix is not required here
//declarator_suffix
declarator_suffix // Note: Only used above in direct_declarator
{CPPParser::TypeQualifier tq;}
:
(
//(options {warnWhenFollowAmbig = false;}:
(LSQUARE (constant_expression)? RSQUARE)+
{declaratorArray();}
|
{(!((LA(1)==LPAREN)&&(LA(2)==ID))||(qualifiedItemIsOneOf(qiType|qiCtor,1)))}?
LPAREN {declaratorParameterList(0);}
(parameter_list)?
RPAREN {declaratorEndParameterList(0);}
(tq = type_qualifier)*
(exception_specification)?
)
;
//conversion_function_decl_or_def
conversion_function_decl_or_def
{CPPParser::TypeQualifier tq;}
:
OPERATOR declaration_specifiers (STAR | AMPERSAND)? // DW 01/08/03 Use type_specifier here? see syntax
(LESSTHAN template_parameter_list GREATERTHAN)?
LPAREN (parameter_list)? RPAREN
(tq = type_qualifier)* // DW 29/07/05 ? changed to *
(exception_specification)?
( compound_statement
| SEMICOLON {end_of_stmt();}
)
;
//function_declarator
function_declarator [int definition]
:
(ptr_operator)=> ptr_operator function_declarator[definition]
|
function_direct_declarator[definition]
;
//function_direct_declarator
function_direct_declarator [int definition]
{
char *q;
CPPParser::TypeQualifier tq;
}
:
( // fix prompted by (isdigit)() in xlocnum
LPAREN
declarator
RPAREN
|
q = qualified_id
{
declaratorID(q,qiFun);
}
)
{
#ifdef MYCODE
if (definition)
myCode_function_direct_declarator(q);
#endif MYCODE
}
LPAREN
{
functionParameterList();
if (K_and_R == true)
in_parameter_list = false;
else
in_parameter_list = true;
}
(parameter_list)?
{
if (K_and_R == true)
in_parameter_list = true;
else
in_parameter_list = false;
}
RPAREN
(options{warnWhenFollowAmbig = false;}:
tq = type_qualifier)*
(ASSIGNEQUAL OCTALINT)? // The value of the octal must be 0
{functionEndParameterList(definition);}
(exception_specification)?
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -