📄 stdcparser.g
字号:
popScope();
}
RPAREN
| LBRACKET ( constExpr )? RBRACKET
)*
{ ## = #( #[NDeclarator], ## ); }
;
parameterTypeList
: parameterDeclaration
( options {
warnWhenFollowAmbig = false;
} :
COMMA!
parameterDeclaration
)*
( COMMA!
VARARGS
)?
;
parameterDeclaration
{ String declName; }
: ds:declSpecifiers
( ( declarator[false] )=> declName = d:declarator[false]
{
AST d2, ds2;
d2 = astFactory.dupList(#d);
ds2 = astFactory.dupList(#ds);
symbolTable.add(declName, #(null, ds2, d2));
}
| nonemptyAbstractDeclarator
)?
{
## = #( #[NParameterDeclaration], ## );
}
;
/* JTC:
* This handles both new and old style functions.
* see declarator rule to see differences in parameters
* and here (declaration SEMI)* is the param type decls for the
* old style. may want to do some checking to check for illegal
* combinations (but I assume all parsed code will be legal?)
*/
functionDef
{ String declName; }
: ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers
| //epsilon
)
declName = d:declarator[true]
{
AST d2, ds2;
d2 = astFactory.dupList(#d);
ds2 = astFactory.dupList(#ds);
symbolTable.add(declName, #(null, ds2, d2));
pushScope(declName);
}
( declaration )* (VARARGS)? ( SEMI! )*
{ popScope(); }
compoundStatement[declName]
{ ## = #( #[NFunctionDef], ## );}
;
functionDeclSpecifiers
{ int specCount = 0; }
: ( options { // this loop properly aborts when
// it finds a non-typedefName ID MBZ
warnWhenFollowAmbig = false;
} :
functionStorageClassSpecifier
| typeQualifier
| ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=>
specCount = typeSpecifier[specCount]
)+
;
declarationList
: ( options { // this loop properly aborts when
// it finds a non-typedefName ID MBZ
warnWhenFollowAmbig = false;
} :
( declarationPredictor )=> declaration
)+
;
declarationPredictor
: (options { //only want to look at declaration if I don't see typedef
warnWhenFollowAmbig = false;
}:
"typedef"
| declaration
)
;
compoundStatement[String scopeName]
: LCURLY!
{
pushScope(scopeName);
}
( ( declarationPredictor)=> declarationList )?
( statementList )?
{ popScope(); }
RCURLY!
{ ## = #( #[NCompoundStatement, scopeName], ##); }
;
statementList
: ( statement )+
;
statement
: SEMI // Empty statements
| compoundStatement[getAScopeName()] // Group of statements
| expr SEMI! { ## = #( #[NStatementExpr], ## ); } // Expressions
// Iteration statements:
| "while"^ LPAREN! expr RPAREN! statement
| "do"^ statement "while"! LPAREN! expr RPAREN! SEMI!
|! "for"
LPAREN ( e1:expr )? SEMI ( e2:expr )? SEMI ( e3:expr )? RPAREN
s:statement
{
if ( #e1 == null) { #e1 = #[ NEmptyExpression ]; }
if ( #e2 == null) { #e2 = #[ NEmptyExpression ]; }
if ( #e3 == null) { #e3 = #[ NEmptyExpression ]; }
## = #( #[LITERAL_for, "for"], #e1, #e2, #e3, #s );
}
// Jump statements:
| "goto"^ ID SEMI!
| "continue" SEMI!
| "break" SEMI!
| "return"^ ( expr )? SEMI!
// Labeled statements:
| ID COLON! (options {warnWhenFollowAmbig=false;}:statement)? { ## = #( #[NLabel], ## ); }
| "case"^ constExpr COLON! statement
| "default"^ COLON! statement
// Selection statements:
| "if"^
LPAREN! expr RPAREN! statement
( //standard if-else ambiguity
options {
warnWhenFollowAmbig = false;
} :
"else" statement )?
| "switch"^ LPAREN! expr RPAREN! statement
;
expr
: assignExpr (options {
/* MBZ:
COMMA is ambiguous between comma expressions and
argument lists. argExprList should get priority,
and it does by being deeper in the expr rule tree
and using (COMMA assignExpr)*
*/
warnWhenFollowAmbig = false;
} :
c:COMMA^ { #c.setType(NCommaExpr); } assignExpr
)*
;
assignExpr
: conditionalExpr ( a:assignOperator! assignExpr { ## = #( #a, ## );} )?
;
assignOperator
: ASSIGN
| DIV_ASSIGN
| PLUS_ASSIGN
| MINUS_ASSIGN
| STAR_ASSIGN
| MOD_ASSIGN
| RSHIFT_ASSIGN
| LSHIFT_ASSIGN
| BAND_ASSIGN
| BOR_ASSIGN
| BXOR_ASSIGN
;
conditionalExpr
: logicalOrExpr
( QUESTION^ expr COLON! conditionalExpr )?
;
constExpr
: conditionalExpr
;
logicalOrExpr
: logicalAndExpr ( LOR^ logicalAndExpr )*
;
logicalAndExpr
: inclusiveOrExpr ( LAND^ inclusiveOrExpr )*
;
inclusiveOrExpr
: exclusiveOrExpr ( BOR^ exclusiveOrExpr )*
;
exclusiveOrExpr
: bitAndExpr ( BXOR^ bitAndExpr )*
;
bitAndExpr
: equalityExpr ( BAND^ equalityExpr )*
;
equalityExpr
: relationalExpr
( ( EQUAL^ | NOT_EQUAL^ ) relationalExpr )*
;
relationalExpr
: shiftExpr
( ( LT^ | LTE^ | GT^ | GTE^ ) shiftExpr )*
;
shiftExpr
: additiveExpr
( ( LSHIFT^ | RSHIFT^ ) additiveExpr )*
;
additiveExpr
: multExpr
( ( PLUS^ | MINUS^ ) multExpr )*
;
multExpr
: castExpr
( ( STAR^ | DIV^ | MOD^ ) castExpr )*
;
castExpr
: ( LPAREN typeName RPAREN )=>
LPAREN! typeName RPAREN! ( castExpr )
{ ## = #( #[NCast, "("], ## ); }
| unaryExpr
;
typeName
: specifierQualifierList (nonemptyAbstractDeclarator)?
;
nonemptyAbstractDeclarator
: (
pointerGroup
( (LPAREN
( nonemptyAbstractDeclarator
| parameterTypeList
)?
RPAREN)
| (LBRACKET (expr)? RBRACKET)
)*
| ( (LPAREN
( nonemptyAbstractDeclarator
| parameterTypeList
)?
RPAREN)
| (LBRACKET (expr)? RBRACKET)
)+
)
{ ## = #( #[NNonemptyAbstractDeclarator], ## ); }
;
/* JTC:
LR rules:
abstractDeclarator
: nonemptyAbstractDeclarator
| // null
;
nonemptyAbstractDeclarator
: LPAREN nonemptyAbstractDeclarator RPAREN
| abstractDeclarator LPAREN RPAREN
| abstractDeclarator (LBRACKET (expr)? RBRACKET)
| STAR abstractDeclarator
;
*/
unaryExpr
: postfixExpr
| INC^ unaryExpr
| DEC^ unaryExpr
| u:unaryOperator castExpr { ## = #( #[NUnaryExpr], ## ); }
| "sizeof"^
( ( LPAREN typeName )=> LPAREN typeName RPAREN
| unaryExpr
)
;
unaryOperator
: BAND
| STAR
| PLUS
| MINUS
| BNOT
| LNOT
;
postfixExpr
: primaryExpr
(
postfixSuffix {## = #( #[NPostfixExpr], ## );}
)?
;
postfixSuffix
:
( PTR ID
| DOT ID
| functionCall
| LBRACKET expr RBRACKET
| INC
| DEC
)+
;
functionCall
:
LPAREN^ (a:argExprList)? RPAREN
{
##.setType( NFunctionCallArgs );
}
;
primaryExpr
: ID
| charConst
| intConst
| floatConst
| stringConst
// JTC:
// ID should catch the enumerator
// leaving it in gives ambiguous err
// | enumerator
| LPAREN! expr RPAREN! { ## = #( #[NExpressionGroup, "("], ## ); }
;
argExprList
: assignExpr ( COMMA! assignExpr )*
;
protected
charConst
: CharLiteral
;
protected
stringConst
: (StringLiteral)+ { ## = #(#[NStringSeq], ##); }
;
protected
intConst
: IntOctalConst
| LongOctalConst
| UnsignedOctalConst
| IntIntConst
| LongIntConst
| UnsignedIntConst
| IntHexConst
| LongHexConst
| UnsignedHexConst
;
protected
floatConst
: FloatDoubleConst
| DoubleDoubleConst
| LongDoubleConst
;
dummy
: NTypedefName
| NInitDecl
| NDeclarator
| NStructDeclarator
| NDeclaration
| NCast
| NPointerGroup
| NExpressionGroup
| NFunctionCallArgs
| NNonemptyAbstractDeclarator
| NInitializer
| NStatementExpr
| NEmptyExpression
| NParameterTypeList
| NFunctionDef
| NCompoundStatement
| NParameterDeclaration
| NCommaExpr
| NUnaryExpr
| NLabel
| NPostfixExpr
| NRangeExpr
| NStringSeq
| NInitializerElementLabel
| NLcurlyInitializer
| NAsmAttribute
| NGnuAsmExpr
| NTypeMissing
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -