📄 gnucparser.g
字号:
} :
( "typedef" | "__label__" | declaration )=> declarationList
| (nestedFunctionDef)=> nestedFunctionDef
)*
( statementList )?
{ popScope(); }
RCURLY
{ ##.setType( NCompoundStatement ); ##.setAttribute( "scopeName", scopeName ); }
;
nestedFunctionDef
{ String declName; }
: ( "auto" )? //only for nested functions
( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers
)?
declName = d:declarator[false]
{
AST d2, ds2;
d2 = astFactory.dupList(#d);
ds2 = astFactory.dupList(#ds);
symbolTable.add(declName, #(null, ds2, d2));
pushScope(declName);
}
( declaration )*
{ popScope(); }
compoundStatement[declName]
{ ## = #( #[NFunctionDef], ## );}
;
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"^ expr SEMI!
| "continue" SEMI!
| "break" SEMI!
| "return"^ ( expr )? SEMI!
| ID COLON! (options {warnWhenFollowAmbig=false;}: statement)? { ## = #( #[NLabel], ## ); }
// GNU allows range expressions in case statements
| "case"^ ((constExpr VARARGS)=> rangeExpr | constExpr) COLON! ( options{warnWhenFollowAmbig=false;}:statement )?
| "default"^ COLON! ( options{warnWhenFollowAmbig=false;}: statement )?
// Selection statements:
| "if"^
LPAREN! expr RPAREN! statement
( //standard if-else ambiguity
options {
warnWhenFollowAmbig = false;
} :
"else" statement )?
| "switch"^ LPAREN! expr RPAREN! statement
;
conditionalExpr
: logicalOrExpr
( QUESTION^ (expr)? COLON conditionalExpr )?
;
rangeExpr //used in initializers only
: constExpr VARARGS constExpr
{ ## = #(#[NRangeExpr], ##); }
;
castExpr
: ( LPAREN typeName RPAREN )=>
LPAREN^ typeName RPAREN ( castExpr | lcurlyInitializer )
{ ##.setType(NCast); }
| unaryExpr
;
nonemptyAbstractDeclarator
: (
pointerGroup
( (LPAREN
( nonemptyAbstractDeclarator
| parameterTypeList
)?
( COMMA! )?
RPAREN)
| (LBRACKET (expr)? RBRACKET)
)*
| ( (LPAREN
( nonemptyAbstractDeclarator
| parameterTypeList
)?
( COMMA! )?
RPAREN)
| (LBRACKET (expr)? RBRACKET)
)+
)
{ ## = #( #[NNonemptyAbstractDeclarator], ## ); }
;
unaryExpr
: postfixExpr
| INC^ castExpr
| DEC^ castExpr
| u:unaryOperator castExpr { ## = #( #[NUnaryExpr], ## ); }
| "sizeof"^
( ( LPAREN typeName )=> LPAREN typeName RPAREN
| unaryExpr
)
| "__alignof"^
( ( LPAREN typeName )=> LPAREN typeName RPAREN
| unaryExpr
)
| gnuAsmExpr
;
unaryOperator
: BAND
| STAR
| PLUS
| MINUS
| BNOT //also stands for complex conjugation
| LNOT
| LAND //for label dereference (&&label)
| "__real"
| "__imag"
;
gnuAsmExpr
: "asm"^ ("volatile")?
LPAREN stringConst
( options { warnWhenFollowAmbig = false; }:
COLON (strOptExprPair ( COMMA strOptExprPair)* )?
( options { warnWhenFollowAmbig = false; }:
COLON (strOptExprPair ( COMMA strOptExprPair)* )?
)?
)?
( COLON stringConst ( COMMA stringConst)* )?
RPAREN
{ ##.setType(NGnuAsmExpr); }
;
//GCC requires the PARENs
strOptExprPair
: stringConst ( LPAREN expr RPAREN )?
;
primaryExpr
: ID
| Number
| charConst
| stringConst
// JTC:
// ID should catch the enumerator
// leaving it in gives ambiguous err
// | enumerator
| (LPAREN LCURLY) => LPAREN^ compoundStatement[getAScopeName()] RPAREN
| LPAREN^ expr RPAREN { ##.setType(NExpressionGroup); }
;
{
import isis.anp.common.CToken;
import isis.anp.common.LineObject;
import isis.anp.common.PreprocessorInfoChannel;
import java.io.InputStream;
import java.io.Reader;
import java.util.Hashtable;
import antlr.ANTLRHashString;
import antlr.ByteBuffer;
import antlr.CharBuffer;
import antlr.CharStreamException;
import antlr.CharStreamIOException;
import antlr.InputBuffer;
import antlr.LexerSharedInputState;
import antlr.NoViableAltForCharException;
import antlr.RecognitionException;
import antlr.Token;
import antlr.TokenStream;
import antlr.TokenStreamException;
import antlr.TokenStreamIOException;
import antlr.TokenStreamRecognitionException;
import antlr.collections.impl.BitSet;
}
class GnuCLexer extends StdCLexer;
options
{
k = 3;
importVocab = GnuC;
testLiterals = false;
}
tokens {
LITERAL___extension__ = "__extension__";
}
{
public void initialize(String src)
{
setOriginalSource(src);
initialize();
}
public void initialize()
{
literals.put(new ANTLRHashString("__alignof__", this), new Integer(LITERAL___alignof));
literals.put(new ANTLRHashString("__asm", this), new Integer(LITERAL_asm));
literals.put(new ANTLRHashString("__asm__", this), new Integer(LITERAL_asm));
literals.put(new ANTLRHashString("__attribute__", this), new Integer(LITERAL___attribute));
literals.put(new ANTLRHashString("__complex__", this), new Integer(LITERAL___complex));
literals.put(new ANTLRHashString("__const", this), new Integer(LITERAL_const));
literals.put(new ANTLRHashString("__const__", this), new Integer(LITERAL_const));
literals.put(new ANTLRHashString("__imag__", this), new Integer(LITERAL___imag));
literals.put(new ANTLRHashString("__inline", this), new Integer(LITERAL_inline));
literals.put(new ANTLRHashString("__inline__", this), new Integer(LITERAL_inline));
literals.put(new ANTLRHashString("__real__", this), new Integer(LITERAL___real));
literals.put(new ANTLRHashString("__signed", this), new Integer(LITERAL_signed));
literals.put(new ANTLRHashString("__signed__", this), new Integer(LITERAL_signed));
literals.put(new ANTLRHashString("__typeof", this), new Integer(LITERAL_typeof));
literals.put(new ANTLRHashString("__typeof__", this), new Integer(LITERAL_typeof));
literals.put(new ANTLRHashString("__volatile", this), new Integer(LITERAL_volatile));
literals.put(new ANTLRHashString("__volatile__", this), new Integer(LITERAL_volatile));
}
LineObject lineObject = new LineObject();
String originalSource = "";
PreprocessorInfoChannel preprocessorInfoChannel = new PreprocessorInfoChannel();
int tokenNumber = 0;
boolean countingTokens = true;
int deferredLineCount = 0;
public void setCountingTokens(boolean ct)
{
countingTokens = ct;
if ( countingTokens ) {
tokenNumber = 0;
}
else {
tokenNumber = 1;
}
}
public void setOriginalSource(String src)
{
originalSource = src;
lineObject.setSource(src);
}
public void setSource(String src)
{
lineObject.setSource(src);
}
public PreprocessorInfoChannel getPreprocessorInfoChannel()
{
return preprocessorInfoChannel;
}
public void setPreprocessingDirective(String pre)
{
preprocessorInfoChannel.addLineForTokenNumber( pre, new Integer(tokenNumber) );
}
protected Token makeToken(int t)
{
if ( t != Token.SKIP && countingTokens) {
tokenNumber++;
}
CToken tok = (CToken) super.makeToken(t);
tok.setLine(lineObject.line);
tok.setSource(lineObject.source);
tok.setTokenNumber(tokenNumber);
lineObject.line += deferredLineCount;
deferredLineCount = 0;
return tok;
}
public void deferredNewline() {
deferredLineCount++;
}
public void newline() {
super.newline();
lineObject.newline();
}
}
Whitespace
: ( ( ' ' | '\t' | '\014')
| "\r\n" { newline(); }
| ( '\n' | '\r' ) { newline(); }
) { _ttype = Token.SKIP; }
;
protected
Escape
: '\\'
( options{warnWhenFollowAmbig=false;}:
~('0'..'7' | 'x')
| ('0'..'3') ( options{warnWhenFollowAmbig=false;}: Digit )*
| ('4'..'7') ( options{warnWhenFollowAmbig=false;}: Digit )*
| 'x' ( options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F' )+
)
;
protected IntSuffix
: 'L'
| 'l'
| 'U'
| 'u'
| 'I'
| 'i'
| 'J'
| 'j'
;
protected NumberSuffix
:
IntSuffix
| 'F'
| 'f'
;
Number
: ( ( Digit )+ ( '.' | 'e' | 'E' ) )=> ( Digit )+
( '.' ( Digit )* ( Exponent )?
| Exponent
)
( NumberSuffix
)*
| ( "..." )=> "..." { _ttype = VARARGS; }
| '.' { _ttype = DOT; }
( ( Digit )+ ( Exponent )?
{ _ttype = Number; }
( NumberSuffix
)*
)?
| '0' ( '0'..'7' )*
( NumberSuffix
)*
| '1'..'9' ( Digit )*
( NumberSuffix
)*
| '0' ( 'x' | 'X' ) ( 'a'..'f' | 'A'..'F' | Digit )+
( IntSuffix
)*
;
IDMEAT
:
i:ID {
if ( i.getType() == LITERAL___extension__ ) {
$setType(Token.SKIP);
}
else {
$setType(i.getType());
}
}
;
protected ID
options
{
testLiterals = true;
}
: ( 'a'..'z' | 'A'..'Z' | '_' | '$')
( 'a'..'z' | 'A'..'Z' | '_' | '$' | '0'..'9' )*
;
WideCharLiteral
:
'L' CharLiteral
{ $setType(CharLiteral); }
;
WideStringLiteral
:
'L' StringLiteral
{ $setType(StringLiteral); }
;
StringLiteral
:
'"'
( ('\\' ~('\n'))=> Escape
| ( '\r' { newline(); }
| '\n' {
newline();
}
| '\\' '\n' {
newline();
}
)
| ~( '"' | '\r' | '\n' | '\\' )
)*
'"'
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -