📄 expandedgnucparser.g
字号:
header {
package isis.anp.gnuc;
}
{
import isis.anp.common.CSymbolTable;
import isis.anp.common.TNode;
import antlr.ASTFactory;
import antlr.ASTPair;
import antlr.MismatchedTokenException;
import antlr.NoViableAltException;
import antlr.ParserSharedInputState;
import antlr.RecognitionException;
import antlr.SemanticException;
import antlr.Token;
import antlr.TokenBuffer;
import antlr.TokenStream;
import antlr.TokenStreamException;
import antlr.collections.AST;
import antlr.collections.impl.ASTArray;
import antlr.collections.impl.BitSet;
}class GnuCParser extends Parser;
options {
k= 2;
exportVocab= GnuC;
buildAST= true;
ASTLabelType= "TNode";
codeGenMakeSwitchThreshold= 2;
codeGenBitsetTestThreshold= 3;
importVocab=StdC;
}
{
// Suppport C++-style single-line comments?
public static boolean CPPComments = true;
// access to symbol table
public CSymbolTable symbolTable = new CSymbolTable();
// source for names to unnamed scopes
protected int unnamedScopeCounter = 0;
public boolean isTypedefName(String name) {
boolean returnValue = false;
TNode node = symbolTable.lookupNameInCurrentScope(name);
for (; node != null; node = (TNode) node.getNextSibling() ) {
if(node.getType() == LITERAL_typedef) {
returnValue = true;
break;
}
}
return returnValue;
}
public String getAScopeName() {
return "" + (unnamedScopeCounter++);
}
public void pushScope(String scopeName) {
symbolTable.pushScope(scopeName);
}
public void popScope() {
symbolTable.popScope();
}
int traceDepth = 0;
public void reportError(RecognitionException ex) {
try {
System.err.println("ANTLR Parsing Error: "+ex + " token name:" + tokenNames[LA(1)]);
ex.printStackTrace(System.err);
}
catch (TokenStreamException e) {
System.err.println("ANTLR Parsing Error: "+ex);
ex.printStackTrace(System.err);
}
}
public void reportError(String s) {
System.err.println("ANTLR Parsing Error from String: " + s);
}
public void reportWarning(String s) {
System.err.println("ANTLR Parsing Warning from String: " + s);
}
public void match(int t) throws MismatchedTokenException {
boolean debugging = false;
if ( debugging ) {
for (int x=0; x<traceDepth; x++) System.out.print(" ");
try {
System.out.println("Match("+tokenNames[t]+") with LA(1)="+
tokenNames[LA(1)] + ((inputState.guessing>0)?" [inputState.guessing "+ inputState.guessing + "]":""));
}
catch (TokenStreamException e) {
System.out.println("Match("+tokenNames[t]+") " + ((inputState.guessing>0)?" [inputState.guessing "+ inputState.guessing + "]":""));
}
}
try {
if ( LA(1)!=t ) {
if ( debugging ){
for (int x=0; x<traceDepth; x++) System.out.print(" ");
System.out.println("token mismatch: "+tokenNames[LA(1)]
+ "!="+tokenNames[t]);
}
throw new MismatchedTokenException(tokenNames, LT(1), t, false, getFilename());
} else {
// mark token as consumed -- fetch next token deferred until LA/LT
consume();
}
}
catch (TokenStreamException e) {
}
}
public void traceIn(String rname) {
traceDepth += 1;
for (int x=0; x<traceDepth; x++) System.out.print(" ");
try {
System.out.println("> "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()]
+ ") " + LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]");
}
catch (TokenStreamException e) {
}
}
public void traceOut(String rname) {
for (int x=0; x<traceDepth; x++) System.out.print(" ");
try {
System.out.println("< "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()]
+ ") "+LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]");
}
catch (TokenStreamException e) {
}
traceDepth -= 1;
}
}
translationUnit :( externalList )? /* Empty source files are allowed. */
;
asm_expr :"asm"^
("volatile")? LCURLY expr RCURLY ( SEMI )+
;
idList :ID ( options{warnWhenFollowAmbig=false;}: COMMA ID )*
;
externalDef :( "typedef" | declaration )=> declaration
| ( functionPrefix )=> functionDef
| typelessDeclaration
| asm_expr
| SEMI
;
functionPrefix { String declName; }
:( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers
| //epsilon
)
declName = d:declarator[true]
( declaration )* (VARARGS)? ( SEMI )*
LCURLY
;
typelessDeclaration { AST typeMissing = #[NTypeMissing]; }
:initDeclList[typeMissing] SEMI { ## = #( #[NTypeMissing], ##); }
;
initializer :( ( ( (initializerElementLabel)=> initializerElementLabel )?
( assignExpr | lcurlyInitializer ) { ## = #( #[NInitializer], ## ); }
)
| lcurlyInitializer
)
;
initializerElementLabel :( ( LBRACKET ((constExpr VARARGS)=> rangeExpr | constExpr) RBRACKET (ASSIGN)? )
| ID COLON
| DOT ID ASSIGN
)
{ ## = #( #[NInitializerElementLabel], ##) ; }
;
lcurlyInitializer :LCURLY^ (initializerList ( COMMA! )? )? RCURLY
{ ##.setType( NLcurlyInitializer ); }
;
initializerList :initializer ( options{warnWhenFollowAmbig=false;}:COMMA! initializer )*
;
declarator[boolean isFunctionDefinition] returns [String declName]{ declName = ""; }
:( pointerGroup )?
( id:ID { declName = id.getText(); }
| LPAREN declName = declarator[false] RPAREN
)
( declaratorParamaterList[isFunctionDefinition, declName]
| LBRACKET ( expr )? RBRACKET
)*
{ ## = #( #[NDeclarator], ## ); }
;
declaratorParamaterList[boolean isFunctionDefinition, String declName] :LPAREN^
{
if (isFunctionDefinition) {
pushScope(declName);
}
else {
pushScope("!"+declName);
}
}
(
(declSpecifiers)=> parameterTypeList
| (idList)?
)
{
popScope();
}
( COMMA! )?
RPAREN
{ ##.setType(NParameterTypeList); }
;
parameterTypeList :parameterDeclaration
( options {
warnWhenFollowAmbig = false;
} :
( COMMA | SEMI )
parameterDeclaration
)*
( ( COMMA | SEMI )
VARARGS
)?
;
declarationList :( options { // this loop properly aborts when
// it finds a non-typedefName ID MBZ
warnWhenFollowAmbig = false;
} :
localLabelDeclaration
| ( declarationPredictor )=> declaration
)+
;
localLabelDeclaration :( //GNU note: any __label__ declarations must come before regular declarations.
"__label__"^ ID (options{warnWhenFollowAmbig=false;}: COMMA! ID)* ( COMMA! )? ( SEMI! )+
)
;
declaration { AST ds1 = null; }
:ds:declSpecifiers { ds1 = astFactory.dupList(#ds); }
(
initDeclList[ds1]
)?
( SEMI )+
{ ## = #( #[NDeclaration], ##); }
;
functionStorageClassSpecifier :"extern"
| "static"
| "inline"
;
typeSpecifier[int specCount] returns [int retSpecCount]{ retSpecCount = specCount + 1; }
:( "void"
| "char"
| "short"
| "int"
| "long"
| "float"
| "double"
| "signed"
| "unsigned"
| structOrUnionSpecifier ( options{warnWhenFollowAmbig=false;}: attributeDecl )*
| enumSpecifier
| { specCount==0 }? typedefName
| "typeof"^ LPAREN
( ( typeName )=> typeName
| expr
)
RPAREN
| "__complex"
)
;
structOrUnionSpecifier { String scopeName; }
:sou:structOrUnion!
( ( ID LCURLY )=> i:ID l:LCURLY
{
scopeName = #sou.getText() + " " + #i.getText();
#l.setText(scopeName);
pushScope(scopeName);
}
( structDeclarationList )?
{ popScope();}
RCURLY
| l1:LCURLY
{
scopeName = getAScopeName();
#l1.setText(scopeName);
pushScope(scopeName);
}
( structDeclarationList )?
{ popScope(); }
RCURLY
| ID
)
{
## = #( #sou, ## );
}
;
structDeclaration :specifierQualifierList structDeclaratorList ( COMMA! )? ( SEMI! )+
;
structDeclaratorList :structDeclarator ( options{warnWhenFollowAmbig=false;}: COMMA! structDeclarator )*
;
structDeclarator :( declarator[false] )?
( COLON constExpr )?
( attributeDecl )*
{ ## = #( #[NStructDeclarator], ##); }
;
enumSpecifier :"enum"^
( ( ID LCURLY )=> i:ID LCURLY enumList[i.getText()] RCURLY
| LCURLY enumList["anonymous"] RCURLY
| ID
)
;
enumList[String enumName] :enumerator[enumName] ( options{warnWhenFollowAmbig=false;}: COMMA! enumerator[enumName] )* ( COMMA! )?
;
initDeclList[AST declarationSpecifiers] :initDecl[declarationSpecifiers]
( options{warnWhenFollowAmbig=false;}: COMMA! initDecl[declarationSpecifiers] )*
( COMMA! )?
;
initDecl[AST declarationSpecifiers] { String declName = ""; }
:declName = d:declarator[false]
{ AST ds1, d1;
ds1 = astFactory.dupList(declarationSpecifiers);
d1 = astFactory.dupList(#d);
symbolTable.add(declName, #(null, ds1, d1) );
}
( attributeDecl )*
( ASSIGN initializer
| COLON expr
)?
{ ## = #( #[NInitDecl], ## ); }
;
attributeDecl :"__attribute"^ LPAREN LPAREN attributeList RPAREN RPAREN
| "asm"^ LPAREN stringConst RPAREN { ##.setType( NAsmAttribute ); }
;
attributeList :attribute ( options{warnWhenFollowAmbig=false;}: COMMA attribute)* ( COMMA )?
;
attribute :( ~(LPAREN | RPAREN | COMMA)
| LPAREN attributeList RPAREN
)*
;
compoundStatement[String scopeName] :LCURLY^
{
pushScope(scopeName);
}
( //this ambiguity is ok, declarationList and nestedFunctionDef end properly
options {
warnWhenFollowAmbig = false;
} :
( "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 :constExpr VARARGS constExpr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -