From 775ec79d5d719c1eba9c4687ae066f6b82696e4f Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sun, 18 May 2014 10:01:56 -0700 Subject: gluegen: avoid a suppressed warning annotation by using the ArrayList copy constructor clone() can't be used without warnigns and is no more efficient that the copy constructor, replace the call and kill the suppressed warning annotation. While here, mark the modifier list as private final. Signed-off-by: Harvey Harrison --- src/java/com/jogamp/gluegen/FunctionEmitter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/java') diff --git a/src/java/com/jogamp/gluegen/FunctionEmitter.java b/src/java/com/jogamp/gluegen/FunctionEmitter.java index 8bb2ca5..723af3a 100644 --- a/src/java/com/jogamp/gluegen/FunctionEmitter.java +++ b/src/java/com/jogamp/gluegen/FunctionEmitter.java @@ -47,7 +47,7 @@ public abstract class FunctionEmitter { public static final EmissionModifier STATIC = new EmissionModifier("static"); private boolean isInterfaceVal; - private ArrayList modifiers = new ArrayList(); + private final ArrayList modifiers; private CommentEmitter commentEmitter = null; private PrintWriter defaultOutput; @@ -56,6 +56,7 @@ public abstract class FunctionEmitter { */ public FunctionEmitter(PrintWriter defaultOutput, boolean isInterface) { assert(defaultOutput != null); + this.modifiers = new ArrayList(); this.defaultOutput = defaultOutput; this.isInterfaceVal = isInterface; } @@ -63,9 +64,8 @@ public abstract class FunctionEmitter { /** * Makes this FunctionEmitter a copy of the passed one. */ - @SuppressWarnings("unchecked") public FunctionEmitter(FunctionEmitter arg) { - modifiers = (ArrayList)arg.modifiers.clone(); + modifiers = new ArrayList(arg.modifiers); commentEmitter = arg.commentEmitter; defaultOutput = arg.defaultOutput; isInterfaceVal = arg.isInterfaceVal; -- cgit v1.2.3 From 5a9bee7ad9085cfd71053041aff3cabce2325f22 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sun, 18 May 2014 10:03:43 -0700 Subject: gluegen: remove an unreferenced writer variable Signed-off-by: Harvey Harrison --- src/java/com/jogamp/gluegen/FunctionEmitter.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/java') diff --git a/src/java/com/jogamp/gluegen/FunctionEmitter.java b/src/java/com/jogamp/gluegen/FunctionEmitter.java index 723af3a..01a0e12 100644 --- a/src/java/com/jogamp/gluegen/FunctionEmitter.java +++ b/src/java/com/jogamp/gluegen/FunctionEmitter.java @@ -169,7 +169,6 @@ public abstract class FunctionEmitter { } protected int emitModifiers(PrintWriter writer) { - PrintWriter w = getDefaultOutput(); int numEmitted = 0; for (Iterator it = getModifiers(); it.hasNext(); ) { writer.print(it.next()); -- cgit v1.2.3 From b8d85c035bbd2d6fa8a37f957bcf80acab18015e Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sun, 18 May 2014 10:15:20 -0700 Subject: gluegen: update antlr grammer to produce annotated enum and functionName sets The annotations are all commented out, uncomment them and reduce the type warnings during the build. Signed-off-by: Harvey Harrison --- src/java/com/jogamp/gluegen/jgram/JavaParser.g | 8 ++++---- src/java/com/jogamp/gluegen/jgram/Test.java | 24 +++++++++++------------- 2 files changed, 15 insertions(+), 17 deletions(-) (limited to 'src/java') diff --git a/src/java/com/jogamp/gluegen/jgram/JavaParser.g b/src/java/com/jogamp/gluegen/jgram/JavaParser.g index 18f2970..f67579e 100644 --- a/src/java/com/jogamp/gluegen/jgram/JavaParser.g +++ b/src/java/com/jogamp/gluegen/jgram/JavaParser.g @@ -155,7 +155,7 @@ tokens { } /** Returns the EnumTypes this HeaderParser processed. */ - public Set getParsedEnumNames() { + public Set getParsedEnumNames() { return enumNames; } @@ -167,13 +167,13 @@ tokens { } /** Returns the list of FunctionSymbols this HeaderParser has parsed. */ - public Set getParsedFunctionNames() { + public Set getParsedFunctionNames() { return functionNames; } - private Set/**/ functionNames = new HashSet(); + private Set functionNames = new HashSet(); // hash from name of an enumerated value to the EnumType to which it belongs - private Set/**/ enumNames = new HashSet(); + private Set enumNames = new HashSet(); private int blockDepth = 0; } diff --git a/src/java/com/jogamp/gluegen/jgram/Test.java b/src/java/com/jogamp/gluegen/jgram/Test.java index 8baff02..19d2110 100644 --- a/src/java/com/jogamp/gluegen/jgram/Test.java +++ b/src/java/com/jogamp/gluegen/jgram/Test.java @@ -1,13 +1,11 @@ package com.jogamp.gluegen.jgram; -import java.util.*; - -import java.io.*; -// import antlr.collections.AST; -import antlr.collections.impl.*; -import antlr.debug.misc.*; -import antlr.*; -// import java.awt.event.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.Reader; +import java.util.Iterator; +import java.util.Set; class Test { @@ -74,16 +72,16 @@ class Test { // start parsing at the compilationUnit rule parser.compilationUnit(); - Set set = parser.getParsedEnumNames(); + Set set = parser.getParsedEnumNames(); System.out.println("Enums"); - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - String s = (String) iter.next(); + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + String s = iter.next(); System.out.println(s); } System.out.println("Functions"); set = parser.getParsedFunctionNames(); - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - String s = (String) iter.next(); + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + String s = iter.next(); System.out.println(s); } -- cgit v1.2.3 From e8bc9edd3c39170af038ab23b8cdca9ffd6f2d56 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 31 May 2014 13:39:08 -0700 Subject: gluegen: move all antlr grammars to a top-level directory /src/main/antlr/.. This gets the .g files unmixed from the non-generated java files for the cgram/jgram packages. Signed-off-by: Harvey Harrison --- make/build.xml | 19 +- src/java/com/jogamp/gluegen/cgram/GnuCEmitter.g | 1145 ---------------- src/java/com/jogamp/gluegen/cgram/GnuCParser.g | 878 ------------ src/java/com/jogamp/gluegen/cgram/GnuCTreeParser.g | 867 ------------ src/java/com/jogamp/gluegen/cgram/HeaderParser.g | 785 ----------- src/java/com/jogamp/gluegen/cgram/StdCParser.g | 1401 -------------------- src/java/com/jogamp/gluegen/jgram/JavaParser.g | 1315 ------------------ .../antlr/com/jogamp/gluegen/cgram/GnuCEmitter.g | 1145 ++++++++++++++++ .../antlr/com/jogamp/gluegen/cgram/GnuCParser.g | 878 ++++++++++++ .../com/jogamp/gluegen/cgram/GnuCTreeParser.g | 867 ++++++++++++ .../antlr/com/jogamp/gluegen/cgram/HeaderParser.g | 785 +++++++++++ .../antlr/com/jogamp/gluegen/cgram/StdCParser.g | 1401 ++++++++++++++++++++ .../antlr/com/jogamp/gluegen/jgram/JavaParser.g | 1315 ++++++++++++++++++ 13 files changed, 6400 insertions(+), 6401 deletions(-) delete mode 100644 src/java/com/jogamp/gluegen/cgram/GnuCEmitter.g delete mode 100644 src/java/com/jogamp/gluegen/cgram/GnuCParser.g delete mode 100644 src/java/com/jogamp/gluegen/cgram/GnuCTreeParser.g delete mode 100644 src/java/com/jogamp/gluegen/cgram/HeaderParser.g delete mode 100644 src/java/com/jogamp/gluegen/cgram/StdCParser.g delete mode 100644 src/java/com/jogamp/gluegen/jgram/JavaParser.g create mode 100644 src/main/antlr/com/jogamp/gluegen/cgram/GnuCEmitter.g create mode 100644 src/main/antlr/com/jogamp/gluegen/cgram/GnuCParser.g create mode 100644 src/main/antlr/com/jogamp/gluegen/cgram/GnuCTreeParser.g create mode 100644 src/main/antlr/com/jogamp/gluegen/cgram/HeaderParser.g create mode 100644 src/main/antlr/com/jogamp/gluegen/cgram/StdCParser.g create mode 100644 src/main/antlr/com/jogamp/gluegen/jgram/JavaParser.g (limited to 'src/java') diff --git a/make/build.xml b/make/build.xml index 8791d76..81a82c0 100644 --- a/make/build.xml +++ b/make/build.xml @@ -58,6 +58,7 @@ + @@ -116,15 +117,13 @@ - - - + + - - - + + @@ -631,15 +630,15 @@ - - + + - - + + diff --git a/src/java/com/jogamp/gluegen/cgram/GnuCEmitter.g b/src/java/com/jogamp/gluegen/cgram/GnuCEmitter.g deleted file mode 100644 index 38ded36..0000000 --- a/src/java/com/jogamp/gluegen/cgram/GnuCEmitter.g +++ /dev/null @@ -1,1145 +0,0 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Copyright (c) Non, Inc. 1998 -- All Rights Reserved - -PROJECT: C Compiler -MODULE: GnuCEmitter -FILE: GnuCEmitter.g - -AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 - -DESCRIPTION: - - This tree grammar is for a Gnu C AST. - It turns the tree back into source code. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - - -header { - package com.jogamp.gluegen.cgram; - - import java.io.*; - import java.util.*; - - import antlr.CommonAST; - import antlr.DumpASTVisitor; -} - - -class GnuCEmitter extends GnuCTreeParser; - -options - { - importVocab = GNUC; - buildAST = false; - ASTLabelType = "TNode"; - - // Copied following options from java grammar. - codeGenMakeSwitchThreshold = 2; - codeGenBitsetTestThreshold = 3; - } - - -{ - - -int tabs = 0; -PrintStream currentOutput = System.out; -int lineNum = 1; -String currentSource = ""; -LineObject trueSourceFile; -final int lineDirectiveThreshold = Integer.MAX_VALUE; -PreprocessorInfoChannel preprocessorInfoChannel = null; -Stack sourceFiles = new Stack(); - -public GnuCEmitter( PreprocessorInfoChannel preprocChannel ) -{ - preprocessorInfoChannel = preprocChannel; -} - -void initializePrinting() -{ - Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber( new Integer(1) ); - printPreprocs(preprocs); -/* if ( currentSource.equals("") ) { - trueSourceFile = new LineObject(currentSource); - currentOutput.println("# 1 \"" + currentSource + "\"\n"); - sourceFiles.push(trueSourceFile); - } -*/ -} - -void finalizePrinting() { - // flush any leftover preprocessing instructions to the stream - - printPreprocs( - preprocessorInfoChannel.extractLinesPrecedingTokenNumber( - new Integer( preprocessorInfoChannel.getMaxTokenNumber() + 1 ) )); - //print a newline so file ends at a new line - currentOutput.println(); -} - -void printPreprocs( Vector preprocs ) -{ - // if there was a preprocessingDirective previous to this token then - // print a newline and the directive, line numbers handled later - if ( preprocs.size() > 0 ) { - if ( trueSourceFile != null ) { - currentOutput.println(); //make sure we're starting a new line unless this is the first line directive - } - lineNum++; - Enumeration e = preprocs.elements(); - while (e.hasMoreElements()) - { - Object o = e.nextElement(); - if ( o.getClass().getName().equals("LineObject") ) { - LineObject l = (LineObject) o; - - // we always return to the trueSourceFile, we never enter it from another file - // force it to be returning if in fact we aren't currently in trueSourceFile - if (( trueSourceFile != null ) //trueSource exists - && ( !currentSource.equals(trueSourceFile.getSource()) ) //currently not in trueSource - && ( trueSourceFile.getSource().equals(l.getSource()) ) ) { //returning to trueSource - l.setEnteringFile( false ); - l.setReturningToFile( true ); - } - - - // print the line directive - currentOutput.println(l); - lineNum = l.getLine(); - currentSource = l.getSource(); - - - // the very first line directive always represents the true sourcefile - if ( trueSourceFile == null ) { - trueSourceFile = new LineObject(currentSource); - sourceFiles.push(trueSourceFile); - } - - // keep our own stack of files entered - if ( l.getEnteringFile() ) { - sourceFiles.push(l); - } - - // if returning to a file, pop the exited files off the stack - if ( l.getReturningToFile() ) { - LineObject top = (LineObject) sourceFiles.peek(); - while (( top != trueSourceFile ) && (! l.getSource().equals(top.getSource()) )) { - sourceFiles.pop(); - top = (LineObject) sourceFiles.peek(); - } - } - } - else { // it was a #pragma or such - currentOutput.println(o); - lineNum++; - } - } - } - -} - -void print( TNode t ) { - int tLineNum = t.getLocalLineNum(); - if ( tLineNum == 0 ) tLineNum = lineNum; - - Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber((Integer)t.getAttribute("tokenNumber")); - printPreprocs(preprocs); - - if ( (lineNum != tLineNum) ) { - // we know we'll be newlines or a line directive or it probably - // is just the case that this token is on the next line - // either way start a new line and indent it - currentOutput.println(); - lineNum++; - printTabs(); - } - - if ( lineNum == tLineNum ){ - // do nothing special, we're at the right place - } - else { - int diff = tLineNum - lineNum; - if ( lineNum < tLineNum ) { - // print out the blank lines to bring us up to right line number - for ( ; lineNum < tLineNum ; lineNum++ ) { - currentOutput.println(); - } - printTabs(); - } - else { // just reset lineNum - lineNum = tLineNum; - } - } - currentOutput.print( t.getText() + " " ); -} - - -/* This was my attempt at being smart about line numbers - It didn't work quite right but I don't know why, I didn't - have enough test cases. Worked ok compiling rcs and ghostscript -*/ -void printAddingLineDirectives( TNode t ) { - int tLineNum = t.getLocalLineNum(); - String tSource = (String) t.getAttribute("source"); - - if ( tSource == null ) tSource = currentSource; - if ( tLineNum == 0 ) tLineNum = lineNum; - - Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber((Integer)t.getAttribute("tokenNumber")); - printPreprocs(preprocs); - - if ( (lineNum != tLineNum) || !currentSource.equals(tSource) ) { - // we know we'll be newlines or a line directive or it probably - // is just the case that this token is on the next line - // either way start a new line and indent it - currentOutput.println(); - lineNum++; - printTabs(); - } - - if ( ( lineNum == tLineNum ) && ( currentSource.equals(tSource) ) ){ - // do nothing special, we're at the right place - } - else if ( currentSource.equals(tSource) ) { - int diff = tLineNum - lineNum; - if (diff > 0 && diff < lineDirectiveThreshold) { - // print out the blank lines to bring us up to right line number - for ( ; lineNum < tLineNum ; lineNum++ ) { - currentOutput.println(); - } - } - else { // print line directive to get us to right line number - // preserve flags 3 and 4 if present in current file - if ( ! sourceFiles.empty() ) { - LineObject l = (LineObject) sourceFiles.peek(); - StringBuilder tFlags = new StringBuilder(""); - if (l.getSystemHeader()) { - tFlags.append(" 3"); - } - if (l.getTreatAsC()) { - tFlags.append(" 4"); - } - currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + tFlags.toString()); - lineNum = tLineNum; - } - } - - printTabs(); - } - else { // different source - Enumeration sources = sourceFiles.elements(); - // see if we're returning to a file we entered earlier - boolean returningToEarlierFile = false; - while (sources.hasMoreElements()) { - LineObject l = (LineObject) sources.nextElement(); - if (l.getSource().equals(tSource)) { - returningToEarlierFile = true; - break; - } - } - if (returningToEarlierFile) { - // pop off the files we're exiting, but never pop the trueSourceFile - LineObject l = (LineObject) sourceFiles.peek(); - while ( ( l != trueSourceFile ) &&(! l.getSource().equals(tSource) ) ) { - sourceFiles.pop(); - l = (LineObject) sourceFiles.peek(); - } - - // put in the return flag, plus others as needed - StringBuilder tFlags = new StringBuilder(" 2"); - if (l.getSystemHeader()) { - tFlags.append(" 3"); - } - if (l.getTreatAsC()) { - tFlags.append(" 4"); - } - - currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + tFlags); - lineNum = tLineNum; - currentSource = tSource; - printTabs(); - } - else { // entering a file that wasn't in the original source - // pretend we're entering it from top of stack - currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + " 1"); - lineNum = tLineNum; - currentSource = tSource; - printTabs(); - } - } - currentOutput.print( t.getText() + " " ); -} - -/** It is not ok to print newlines from the String passed in as -it will screw up the line number handling **/ -void print( String s ) { - currentOutput.print( s + " " ); -} - -void printTabs() { - for ( int i = 0; i< tabs; i++ ) { - currentOutput.print( "\t" ); - } -} - -void commaSep( TNode t ) { - print( t ); - if ( t.getNextSibling() != null ) { - print( "," ); - } -} - - int traceDepth = 0; - public void reportError(RecognitionException ex) { - if ( ex != null) { - System.err.println("ANTLR Tree Parsing RecognitionException Error: " + ex.getClass().getName() + " " + ex ); - ex.printStackTrace(System.err); - } - } - public void reportError(NoViableAltException ex) { - System.err.println("ANTLR Tree Parsing NoViableAltException Error: " + ex.toString()); - TNode.printTree( ex.node ); - ex.printStackTrace(System.err); - } - public void reportError(MismatchedTokenException ex) { - if ( ex != null) { - TNode.printTree( ex.node ); - System.err.println("ANTLR Tree Parsing MismatchedTokenException Error: " + ex ); - ex.printStackTrace(System.err); - } - } - public void reportError(String s) { - System.err.println("ANTLR Error from String: " + s); - } - public void reportWarning(String s) { - System.err.println("ANTLR Warning from String: " + s); - } - protected void match(AST t, int ttype) throws MismatchedTokenException { - //System.out.println("match("+ttype+"); cursor is "+t); - super.match(t, ttype); - } - public void match(AST t, BitSet b) throws MismatchedTokenException { - //System.out.println("match("+b+"); cursor is "+t); - super.match(t, b); - } - protected void matchNot(AST t, int ttype) throws MismatchedTokenException { - //System.out.println("matchNot("+ttype+"); cursor is "+t); - super.matchNot(t, ttype); - } - public void traceIn(String rname, AST t) { - traceDepth += 1; - for (int x=0; x typeName - | expr - ) - rp:RPAREN { print( rp ); } - ) - | p:"__complex" { print( p ); } - ; - - -typedefName - : #(NTypedefName i:ID { print( i ); } ) - ; - - -structSpecifier - : #( a:"struct" { print( a ); } - structOrUnionBody - ) - ; - -unionSpecifier - : #( a:"union" { print( a ); } - structOrUnionBody - ) - ; - -structOrUnionBody - : ( (ID LCURLY) => i1:ID lc1:LCURLY { print( i1 ); print ( "{" ); tabs++; } - ( structDeclarationList )? - rc1:RCURLY { tabs--; print( rc1 ); } - | lc2:LCURLY { print( lc2 ); tabs++; } - ( structDeclarationList )? - rc2:RCURLY { tabs--; print( rc2 ); } - | i2:ID { print( i2 ); } - ) - ; - -structDeclarationList - : ( structDeclaration { print( ";" ); } - )+ - ; - - -structDeclaration - : specifierQualifierList structDeclaratorList - ; - - -specifierQualifierList - : ( - typeSpecifier - | typeQualifier - )+ - ; - - -structDeclaratorList - : structDeclarator - ( { print(","); } structDeclarator )* - ; - - -structDeclarator - : - #( NStructDeclarator - ( declarator )? - ( c:COLON { print( c ); } expr )? - ( attributeDecl )* - ) - ; - - -enumSpecifier - : #( a:"enum" { print( a ); } - ( i:ID { print( i ); } )? - ( lc:LCURLY { print( lc ); tabs++; } - enumList - rc:RCURLY { tabs--; print( rc ); } - )? - ) - ; - - -enumList - : - enumerator ( {print(",");} enumerator)* - ; - - -enumerator - : i:ID { print( i ); } - ( b:ASSIGN { print( b ); } - expr - )? - ; - - -attributeDecl: - #( a:"__attribute" { print( a ); } - (b:. { print( b ); } )* - ) - | #( n:NAsmAttribute { print( n ); } - lp:LPAREN { print( lp ); } - expr { print( ")" ); } - rp:RPAREN { print( rp ); } - ) - ; - -initDeclList - : initDecl - ( { print( "," ); } initDecl )* - ; - - -initDecl - { String declName = ""; } - : #(NInitDecl - declarator - ( attributeDecl )* - ( a:ASSIGN { print( a ); } - initializer - | b:COLON { print( b ); } - expr - )? - ) - ; - - -pointerGroup - : #( NPointerGroup - ( a:STAR { print( a ); } - ( typeQualifier )* - )+ - ) - ; - - - -idList - : i:ID { print( i ); } - ( c:COMMA { print( c ); } - id:ID { print( id ); } - )* - ; - - - -initializer - : #( NInitializer (initializerElementLabel)? expr ) - | lcurlyInitializer - ; - -initializerElementLabel - : #( NInitializerElementLabel - ( - ( l:LBRACKET { print( l ); } - expr - r:RBRACKET { print( r ); } - (a1:ASSIGN { print( a1 ); } )? - ) - | i1:ID c:COLON { print( i1 ); print( c ); } - | d:DOT i2:ID a2:ASSIGN { print( d ); print( i2 ); print( a2 ); } - ) - ) - ; - -lcurlyInitializer - : #(n:NLcurlyInitializer { print( n ); tabs++; } - initializerList - rc:RCURLY { tabs--; print( rc ); } - ) - ; - -initializerList - : ( i:initializer { commaSep( i ); } - )* - ; - - -declarator - : #( NDeclarator - ( pointerGroup )? - - ( id:ID { print( id ); } - | lp:LPAREN { print( lp ); } declarator rp:RPAREN { print( rp ); } - ) - - ( #( n:NParameterTypeList { print( n ); } - ( - parameterTypeList - | (idList)? - ) - r:RPAREN { print( r ); } - ) - | lb:LBRACKET { print( lb );} ( expr )? rb:RBRACKET { print( rb ); } - )* - ) - ; - - - -parameterTypeList - : ( parameterDeclaration - ( c:COMMA { print( c ); } - | s:SEMI { print( s ); } - )? - )+ - ( v:VARARGS { print( v ); } )? - ; - - - -parameterDeclaration - : #( NParameterDeclaration - declSpecifiers - (declarator | nonemptyAbstractDeclarator)? - ) - ; - - -functionDef - : #( NFunctionDef - ( functionDeclSpecifiers)? - declarator - (declaration - | v:VARARGS { print( v ); } - )* - compoundStatement - ) - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - -functionDeclSpecifiers - : - ( functionStorageClassSpecifier - | typeQualifier - | typeSpecifier - )+ - ; - -declarationList - : - ( //ANTLR doesn't know that declarationList properly eats all the declarations - //so it warns about the ambiguity - options { - warnWhenFollowAmbig = false; - } : - localLabelDecl - | declaration - )+ - ; - -localLabelDecl - : #(a:"__label__" { print( a ); } - ( i:ID { commaSep( i ); } - )+ - { print( ";" ); } - ) - ; - - - -compoundStatement - : #( cs:NCompoundStatement { print( cs ); tabs++; } - ( declarationList - | functionDef - )* - ( statementList )? - rc:RCURLY { tabs--; print( rc ); } - ) - - ; - -statementList - : ( statement )+ - ; - -statement - : statementBody - ; - -statementBody - : s:SEMI { print( s ); } - - | compoundStatement // Group of statements - - | #(NStatementExpr - expr { print( ";" ); } - ) // Expressions - -// Iteration statements: - - | #( w:"while" { print( w ); print( "(" ); } - expr { print( ")" ); } - statement ) - - | #( d:"do" { print( d ); } - statement - { print( " while ( " ); } - expr - { print( " );" ); } - ) - - | #( f:"for" { print( f ); print( "(" ); } - expr { print( ";" ); } - expr { print( ";" ); } - expr { print( ")" ); } - statement - ) - - -// Jump statements: - - | #( g:"goto" { print( g );} - expr { print( ";" ); } - ) - | c:"continue" { print( c ); print( ";" );} - | b:"break" { print( b ); print( ";" );} - | #( r:"return" { print( r ); } - ( expr )? - { print( ";" ); } - ) - - -// Labeled statements: - | #( NLabel - ni:ID { print( ni ); print( ":" ); } - ( statement )? - ) - - | #( - ca:"case" { print( ca ); } - expr { print( ":" ); } - (statement)? - ) - - | #( - de:"default" { print( de ); print( ":" ); } - (statement)? - ) - - - -// Selection statements: - - | #( i:"if" { print( i ); print( "(" ); } - expr { print( ")" ); } - statement - ( e:"else" { print( e ); } - statement - )? - ) - | #( sw:"switch" { print( sw ); print( "(" ); } - expr { print( ")" ); } - statement - ) - - - - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - - - - - -expr - : - binaryExpr - | conditionalExpr - | castExpr - | unaryExpr - | postfixExpr - | primaryExpr - | emptyExpr - | compoundStatementExpr - | initializer - | rangeExpr - | gnuAsmExpr - ; - -emptyExpr - : NEmptyExpression - ; - -compoundStatementExpr - : #(l:LPAREN { print( l ); } - compoundStatement - r:RPAREN { print( r ); } - ) - ; - -rangeExpr - : #(NRangeExpr expr v:VARARGS{ print( v ); } expr) - ; - -gnuAsmExpr - : #(n:NGnuAsmExpr { print( n ); } - (v:"volatile" { print( v ); } )? - lp:LPAREN { print( lp ); } - stringConst - ( options { warnWhenFollowAmbig = false; }: - c1:COLON { print( c1 );} - (strOptExprPair - ( c2:COMMA { print( c2 ); } strOptExprPair)* - )? - ( options { warnWhenFollowAmbig = false; }: - c3:COLON { print( c3 ); } - (strOptExprPair - ( c4:COMMA { print( c4 ); } strOptExprPair)* - )? - )? - )? - ( c5:COLON { print( c5 ); } - stringConst - ( c6:COMMA { print( c6 ); } - stringConst - )* - )? - rp:RPAREN { print( rp ); } - ) - ; - -strOptExprPair - : stringConst - ( - l:LPAREN { print( l ); } - expr - r:RPAREN { print( r ); } - )? - ; - -binaryOperator - : ASSIGN - | DIV_ASSIGN - | PLUS_ASSIGN - | MINUS_ASSIGN - | STAR_ASSIGN - | MOD_ASSIGN - | RSHIFT_ASSIGN - | LSHIFT_ASSIGN - | BAND_ASSIGN - | BOR_ASSIGN - | BXOR_ASSIGN - | LOR - | LAND - | BOR - | BXOR - | BAND - | EQUAL - | NOT_EQUAL - | LT - | LTE - | GT - | GTE - | LSHIFT - | RSHIFT - | PLUS - | MINUS - | STAR - | DIV - | MOD - | NCommaExpr - ; - -binaryExpr - : b:binaryOperator - // no rules allowed as roots, so here I manually get - // the first and second children of the binary operator - // and then print them out in the right order - { TNode e1, e2; - e1 = (TNode) b.getFirstChild(); - e2 = (TNode) e1.getNextSibling(); - expr( e1 ); - print( b ); - expr( e2 ); - } - - ; - - -conditionalExpr - : #( q:QUESTION - expr { print( q ); } - ( expr )? - c:COLON { print( c ); } - expr - ) - ; - - -castExpr - : #( - c:NCast { print( c ); } - typeName - rp:RPAREN { print( rp ); } - expr - ) - ; - - -typeName - : specifierQualifierList (nonemptyAbstractDeclarator)? - ; - -nonemptyAbstractDeclarator - : #( NNonemptyAbstractDeclarator - ( pointerGroup - ( (lp1:LPAREN { print( lp1 ); } - ( nonemptyAbstractDeclarator - | parameterTypeList - )? - rp1:RPAREN { print( rp1 ); } - ) - | ( - lb1:LBRACKET { print( lb1 ); } - (expr)? - rb1:RBRACKET { print( rb1 ); } - ) - )* - - | ( (lp2:LPAREN { print( lp2 ); } - ( nonemptyAbstractDeclarator - | parameterTypeList - )? - rp2:RPAREN { print( rp2 ); } - ) - | ( - lb2:LBRACKET { print( lb2 ); } - (expr)? - rb2:RBRACKET { print( rb2 ); } - ) - )+ - ) - ) - ; - - - -unaryExpr - : #( i:INC { print( i ); } expr ) - | #( d:DEC { print( d ); } expr ) - | #( NUnaryExpr u:unaryOperator { print( u ); } expr) - | #( s:"sizeof" { print( s ); } - ( ( LPAREN typeName )=> - lps:LPAREN { print( lps ); } - typeName - rps:RPAREN { print( rps ); } - | expr - ) - ) - | #( a:"__alignof" { print( a ); } - ( ( LPAREN typeName )=> - lpa:LPAREN { print( lpa ); } - typeName - rpa:RPAREN { print( rpa ); } - | expr - ) - ) - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - unaryOperator - : BAND - | STAR - | PLUS - | MINUS - | BNOT - | LNOT - | LAND - | "__real" - | "__imag" - ; - - -postfixExpr - : #( NPostfixExpr - primaryExpr - ( a:PTR b:ID { print( a ); print( b ); } - | c:DOT d:ID { print( c ); print( d ); } - | #( n:NFunctionCallArgs { print( n ); } - (argExprList)? - rp:RPAREN { print( rp ); } - ) - | lb:LBRACKET { print( lb ); } - expr - rb:RBRACKET { print( rb ); } - | f:INC { print( f ); } - | g:DEC { print( g ); } - )+ - ) - ; - - - -primaryExpr - : i:ID { print( i ); } - | n:Number { print( n ); } - | charConst - | stringConst - -// JTC: -// ID should catch the enumerator -// leaving it in gives ambiguous err -// | enumerator - - | #( eg:NExpressionGroup { print( eg ); } - expr { print( ")" ); } - ) - ; - - - -argExprList - : expr ( {print( "," );} expr )* - ; - - - -protected -charConst - : c:CharLiteral { print( c ); } - ; - - -protected -stringConst - : #( NStringSeq - ( - s:StringLiteral { print( s ); } - )+ - ) - ; - - -protected -intConst - : IntOctalConst - | LongOctalConst - | UnsignedOctalConst - | IntIntConst - | LongIntConst - | UnsignedIntConst - | IntHexConst - | LongHexConst - | UnsignedHexConst - ; - - -protected -floatConst - : FloatDoubleConst - | DoubleDoubleConst - | LongDoubleConst - ; - - - - - - - - - - diff --git a/src/java/com/jogamp/gluegen/cgram/GnuCParser.g b/src/java/com/jogamp/gluegen/cgram/GnuCParser.g deleted file mode 100644 index e8ca8c5..0000000 --- a/src/java/com/jogamp/gluegen/cgram/GnuCParser.g +++ /dev/null @@ -1,878 +0,0 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Copyright (c) Non, Inc. 1998 -- All Rights Reserved - -PROJECT: C Compiler -MODULE: GnuCParser -FILE: GnuCParser.g - -AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 - -DESCRIPTION: - This is a grammar for the GNU C compiler. It is a - grammar subclass of StdCParser, overriding only those - rules which are different from Standard C. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - - -header { - package com.jogamp.gluegen.cgram; - - import java.io.*; - - import antlr.CommonAST; - import antlr.DumpASTVisitor; -} - - -class GnuCParser extends StdCParser; - -options - { - k = 2; - exportVocab = GNUC; - buildAST = true; - ASTLabelType = "TNode"; - - // Copied following options from java grammar. - codeGenMakeSwitchThreshold = 2; - codeGenBitsetTestThreshold = 3; - } - - -{ - // 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; x0)?" [inputState.guessing "+ inputState.guessing + "]":"")); - - } - - } - try { - if ( LA(1)!=t ) { - if ( debugging ){ - for (int x=0; x "+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 declaration - | ( functionPrefix )=> functionDef - | typelessDeclaration - | asm_expr - | SEMI - ; - -/* these two are here because GCC allows "cat = 13;" as a valid program! */ -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 - ) - ; - -// GCC allows more specific initializers -initializerElementLabel - : ( ( LBRACKET ((constExpr VARARGS)=> rangeExpr | constExpr) RBRACKET (ASSIGN)? ) - | ID COLON - | DOT ID ASSIGN - ) - { ## = #( #[NInitializerElementLabel], ##) ; } - ; - -// GCC allows empty initializer lists -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" - | "int8_t" - | "uint8_t" - | "int16_t" - | "uint16_t" - | "__int32" - | "int32_t" - | "wchar_t" - | "uint32_t" - | "__int64" - | "int64_t" - | "uint64_t" - | "ptrdiff_t" - | "intptr_t" - | "size_t" - | "uintptr_t" - | 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 = (TNode) #[ NEmptyExpression ]; } - if ( #e2 == null) { #e2 = (TNode) #[ NEmptyExpression ]; } - if ( #e3 == null) { #e3 = (TNode) #[ 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 java.io.*; - import java.util.*; - import antlr.*; -} - -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; - List defines = new ArrayList(); - - 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) ); - } - - public void addDefine(String name, String value) - { - defines.add(new Define(name, value)); - } - - /** Returns a list of Define objects corresponding to the - preprocessor definitions seen during parsing. */ - public List getDefines() { - return defines; - } - - 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() { - 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' | '\\' ) - )* - '"' - ; - - - - diff --git a/src/java/com/jogamp/gluegen/cgram/GnuCTreeParser.g b/src/java/com/jogamp/gluegen/cgram/GnuCTreeParser.g deleted file mode 100644 index dbe2f98..0000000 --- a/src/java/com/jogamp/gluegen/cgram/GnuCTreeParser.g +++ /dev/null @@ -1,867 +0,0 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Copyright (c) Non, Inc. 1998 -- All Rights Reserved - -PROJECT: C Compiler -MODULE: GnuCTreeParser -FILE: GnuCTreeParser.g - -AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 - -DESCRIPTION: - - This tree grammar is for a Gnu C AST. No actions in it, - subclass to do something useful. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - - -header { - package com.jogamp.gluegen.cgram; - - import java.io.*; - - import antlr.CommonAST; - import antlr.DumpASTVisitor; -} - - -class GnuCTreeParser extends TreeParser; - -options - { - importVocab = GNUC; - buildAST = false; - ASTLabelType = "TNode"; - - // Copied following options from java grammar. - codeGenMakeSwitchThreshold = 2; - codeGenBitsetTestThreshold = 3; - } - - -{ - int traceDepth = 0; - public void reportError(RecognitionException ex) { - if ( ex != null) { - System.err.println("ANTLR Tree Parsing RecognitionException Error: " + ex.getClass().getName() + " " + ex ); - ex.printStackTrace(System.err); - } - } - public void reportError(NoViableAltException ex) { - System.err.println("ANTLR Tree Parsing NoViableAltException Error: " + ex.toString()); - TNode.printTree( ex.node ); - ex.printStackTrace(System.err); - } - public void reportError(MismatchedTokenException ex) { - if ( ex != null) { - TNode.printTree( ex.node ); - System.err.println("ANTLR Tree Parsing MismatchedTokenException Error: " + ex ); - ex.printStackTrace(System.err); - } - } - public void reportError(String s) { - System.err.println("ANTLR Error from String: " + s); - } - public void reportWarning(String s) { - System.err.println("ANTLR Warning from String: " + s); - } - protected void match(AST t, int ttype) throws MismatchedTokenException { - //System.out.println("match("+ttype+"); cursor is "+t); - super.match(t, ttype); - } - public void match(AST t, BitSet b) throws MismatchedTokenException { - //System.out.println("match("+b+"); cursor is "+t); - super.match(t, b); - } - protected void matchNot(AST t, int ttype) throws MismatchedTokenException { - //System.out.println("matchNot("+ttype+"); cursor is "+t); - super.matchNot(t, ttype); - } - public void traceIn(String rname, AST t) { - traceDepth += 1; - for (int x=0; x typeName - | expr - ) - RPAREN - ) - | "__complex" - ; - - -typedefName - : #(NTypedefName ID) - ; - - -structSpecifier - : #( "struct" structOrUnionBody ) - ; - -unionSpecifier - : #( "union" structOrUnionBody ) - ; - -structOrUnionBody - : ( (ID LCURLY) => ID LCURLY - ( structDeclarationList )? - RCURLY - | LCURLY - ( structDeclarationList )? - RCURLY - | ID - ) - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - -structDeclarationList - : ( structDeclaration )+ - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - - -structDeclaration - : specifierQualifierList structDeclaratorList - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - - -specifierQualifierList - : ( - typeSpecifier - | typeQualifier - )+ - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - - -structDeclaratorList - : ( structDeclarator )+ - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - - -structDeclarator - : - #( NStructDeclarator - ( declarator )? - ( COLON expr )? - ( attributeDecl )* - ) - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - - - -enumSpecifier - : #( "enum" - ( ID )? - ( LCURLY enumList RCURLY )? - ) - ; - - -enumList - : ( enumerator )+ - ; - - -enumerator - : ID ( ASSIGN expr )? - ; - - - -attributeDecl: - #( "__attribute" (.)* ) - | #( NAsmAttribute LPAREN expr RPAREN ) - ; - -initDeclList - : ( initDecl )+ - ; - - -initDecl - { String declName = ""; } - : #( NInitDecl - declarator - ( attributeDecl )* - ( ASSIGN initializer - | COLON expr - )? - ) - ; - - -pointerGroup - : #( NPointerGroup ( STAR ( typeQualifier )* )+ ) - ; - - - -idList - : ID ( COMMA ID )* - ; - - - -initializer - : #( NInitializer (initializerElementLabel)? expr ) - | lcurlyInitializer - ; - -initializerElementLabel - : #( NInitializerElementLabel - ( - ( LBRACKET expr RBRACKET (ASSIGN)? ) - | ID COLON - | DOT ID ASSIGN - ) - ) - ; - -lcurlyInitializer - : #( NLcurlyInitializer - initializerList - RCURLY - ) - ; - -initializerList - : ( initializer )* - ; - - -declarator - : #( NDeclarator - ( pointerGroup )? - - ( id:ID - | LPAREN declarator RPAREN - ) - - ( #( NParameterTypeList - ( - parameterTypeList - | (idList)? - ) - RPAREN - ) - | LBRACKET ( expr )? RBRACKET - )* - ) - ; - - - -parameterTypeList - : ( parameterDeclaration ( COMMA | SEMI )? )+ ( VARARGS )? - ; - - - -parameterDeclaration - : #( NParameterDeclaration - declSpecifiers - (declarator | nonemptyAbstractDeclarator)? - ) - ; - - -functionDef - : #( NFunctionDef - ( functionDeclSpecifiers)? - declarator - (declaration | VARARGS)* - compoundStatement - ) - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - -functionDeclSpecifiers - : - ( functionStorageClassSpecifier - | typeQualifier - | typeSpecifier - )+ - ; - -declarationList - : - ( //ANTLR doesn't know that declarationList properly eats all the declarations - //so it warns about the ambiguity - options { - warnWhenFollowAmbig = false; - } : - localLabelDecl - | declaration - )+ - ; - -localLabelDecl - : #("__label__" (ID)+ ) - ; - - - -compoundStatement - : #( NCompoundStatement - ( declarationList - | functionDef - )* - ( statementList )? - RCURLY - ) - ; - -statementList - : ( statement )+ - ; - -statement - : statementBody - ; - -statementBody - : SEMI // Empty statements - - | compoundStatement // Group of statements - - | #(NStatementExpr expr) // Expressions - -// Iteration statements: - - | #( "while" expr statement ) - | #( "do" statement expr ) - | #( "for" - expr expr expr - statement - ) - - -// Jump statements: - - | #( "goto" expr ) - | "continue" - | "break" - | #( "return" ( expr )? ) - - -// Labeled statements: - | #( NLabel ID (statement)? ) - | #( "case" expr (statement)? ) - | #( "default" (statement)? ) - - - -// Selection statements: - - | #( "if" - expr statement - ( "else" statement )? - ) - | #( "switch" expr statement ) - - - - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - - - - - -expr - : assignExpr - | conditionalExpr - | logicalOrExpr - | logicalAndExpr - | inclusiveOrExpr - | exclusiveOrExpr - | bitAndExpr - | equalityExpr - | relationalExpr - | shiftExpr - | additiveExpr - | multExpr - | castExpr - | unaryExpr - | postfixExpr - | primaryExpr - | commaExpr - | emptyExpr - | compoundStatementExpr - | initializer - | rangeExpr - | gnuAsmExpr - ; - -commaExpr - : #(NCommaExpr expr expr) - ; - -emptyExpr - : NEmptyExpression - ; - -compoundStatementExpr - : #(LPAREN compoundStatement RPAREN) - ; - -rangeExpr - : #(NRangeExpr expr VARARGS expr) - ; - -gnuAsmExpr - : #(NGnuAsmExpr - ("volatile")? - LPAREN stringConst - ( options { warnWhenFollowAmbig = false; }: - COLON (strOptExprPair ( COMMA strOptExprPair)* )? - ( options { warnWhenFollowAmbig = false; }: - COLON (strOptExprPair ( COMMA strOptExprPair)* )? - )? - )? - ( COLON stringConst ( COMMA stringConst)* )? - RPAREN - ) - ; - -strOptExprPair - : stringConst ( LPAREN expr RPAREN )? - ; - -assignExpr - : #( ASSIGN expr expr) - | #( DIV_ASSIGN expr expr) - | #( PLUS_ASSIGN expr expr) - | #( MINUS_ASSIGN expr expr) - | #( STAR_ASSIGN expr expr) - | #( MOD_ASSIGN expr expr) - | #( RSHIFT_ASSIGN expr expr) - | #( LSHIFT_ASSIGN expr expr) - | #( BAND_ASSIGN expr expr) - | #( BOR_ASSIGN expr expr) - | #( BXOR_ASSIGN expr expr) - ; - - -conditionalExpr - : #( QUESTION expr (expr)? COLON expr ) - ; - - -logicalOrExpr - : #( LOR expr expr) - ; - - -logicalAndExpr - : #( LAND expr expr ) - ; - - -inclusiveOrExpr - : #( BOR expr expr ) - ; - - -exclusiveOrExpr - : #( BXOR expr expr ) - ; - - -bitAndExpr - : #( BAND expr expr ) - ; - - - -equalityExpr - : #( EQUAL expr expr) - | #( NOT_EQUAL expr expr) - ; - - -relationalExpr - : #( LT expr expr) - | #( LTE expr expr) - | #( GT expr expr) - | #( GTE expr expr) - ; - - - -shiftExpr - : #( LSHIFT expr expr) - | #( RSHIFT expr expr) - ; - - -additiveExpr - : #( PLUS expr expr) - | #( MINUS expr expr) - ; - - -multExpr - : #( STAR expr expr) - | #( DIV expr expr) - | #( MOD expr expr) - ; - - - -castExpr - : #( NCast typeName RPAREN expr) - ; - - -typeName - : specifierQualifierList (nonemptyAbstractDeclarator)? - ; - -nonemptyAbstractDeclarator - : #( NNonemptyAbstractDeclarator - ( pointerGroup - ( (LPAREN - ( nonemptyAbstractDeclarator - | parameterTypeList - )? - RPAREN) - | (LBRACKET (expr)? RBRACKET) - )* - - | ( (LPAREN - ( nonemptyAbstractDeclarator - | parameterTypeList - )? - RPAREN) - | (LBRACKET (expr)? RBRACKET) - )+ - ) - ) - ; - - - -unaryExpr - : #( INC expr ) - | #( DEC expr ) - | #( NUnaryExpr unaryOperator expr) - | #( "sizeof" - ( ( LPAREN typeName )=> LPAREN typeName RPAREN - | expr - ) - ) - | #( "__alignof" - ( ( LPAREN typeName )=> LPAREN typeName RPAREN - | expr - ) - ) - ; -/* -exception -catch [RecognitionException ex] - { - reportError(ex); - System.out.println("PROBLEM TREE:\n" - + _t.toStringList()); - if (_t!=null) {_t = _t.getNextSibling();} - } -*/ - - unaryOperator - : BAND - | STAR - | PLUS - | MINUS - | BNOT - | LNOT - | LAND - | "__real" - | "__imag" - ; - - -postfixExpr - : #( NPostfixExpr - primaryExpr - ( PTR ID - | DOT ID - | #( NFunctionCallArgs (argExprList)? RPAREN ) - | LBRACKET expr RBRACKET - | INC - | DEC - )+ - ) - ; - - - -primaryExpr - : ID - | Number - | charConst - | stringConst - -// JTC: -// ID should catch the enumerator -// leaving it in gives ambiguous err -// | enumerator - - | #( NExpressionGroup expr ) - ; - - - -argExprList - : ( expr )+ - ; - - - -protected -charConst - : CharLiteral - ; - - -protected -stringConst - : #(NStringSeq (StringLiteral)+) - ; - - -protected -intConst - : IntOctalConst - | LongOctalConst - | UnsignedOctalConst - | IntIntConst - | LongIntConst - | UnsignedIntConst - | IntHexConst - | LongHexConst - | UnsignedHexConst - ; - - -protected -floatConst - : FloatDoubleConst - | DoubleDoubleConst - | LongDoubleConst - ; - - - - - - - - - diff --git a/src/java/com/jogamp/gluegen/cgram/HeaderParser.g b/src/java/com/jogamp/gluegen/cgram/HeaderParser.g deleted file mode 100644 index 0b4d5ec..0000000 --- a/src/java/com/jogamp/gluegen/cgram/HeaderParser.g +++ /dev/null @@ -1,785 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -header { - package com.jogamp.gluegen.cgram; - - import java.io.*; - import java.util.*; - - import antlr.CommonAST; - import com.jogamp.gluegen.cgram.types.*; -} - -class HeaderParser extends GnuCTreeParser; -options { - k = 1; -} - -{ - /** Name assigned to a anonymous EnumType (e.g., "enum { ... }"). */ - public static final String ANONYMOUS_ENUM_NAME = ""; - - boolean debug = false; - - public boolean getDebug() { - return debug; - } - - public void setDebug(boolean debug) { - this.debug = debug; - } - - /** Set the dictionary mapping typedef names to types for this - HeaderParser. Must be done before parsing. */ - public void setTypedefDictionary(TypeDictionary dict) { - this.typedefDictionary = dict; - } - - /** Returns the typedef dictionary this HeaderParser uses. */ - public TypeDictionary getTypedefDictionary() { - return typedefDictionary; - } - - /** Set the dictionary mapping struct names (i.e., the "foo" in - "struct foo { ... };") to types for this HeaderParser. Must be done - before parsing. */ - public void setStructDictionary(TypeDictionary dict) { - this.structDictionary = dict; - } - - /** Returns the struct name dictionary this HeaderParser uses. */ - public TypeDictionary getStructDictionary() { - return structDictionary; - } - - /** Get the canonicalization map, which is a regular HashMap - mapping Type to Type and which is used for looking up the unique - instances of e.g. pointer-to-structure types that have been typedefed - and therefore have names. */ - public Map getCanonMap() { - return canonMap; - } - - /** Pre-define the list of EnumTypes for this HeaderParser. Must be - done before parsing. */ - public void setEnums(List/**/ enumTypes) { - // FIXME: Need to take the input set of EnumTypes, extract all - // the enumerates from each EnumType, and fill in the enumHash - // so that each enumerate maps to the enumType to which it - // belongs. - throw new RuntimeException("setEnums is Unimplemented!"); - } - - /** Returns the EnumTypes this HeaderParser processed. */ - public List/**/ getEnums() { - return new ArrayList(enumHash.values()); - } - - /** Clears the list of functions this HeaderParser has parsed. - Useful when reusing the same HeaderParser for more than one - header file. */ - public void clearParsedFunctions() { - functions.clear(); - } - - /** Returns the list of FunctionSymbols this HeaderParser has parsed. */ - public List getParsedFunctions() { - return functions; - } - - private CompoundType lookupInStructDictionary(String typeName, - CompoundTypeKind kind, - int cvAttrs) { - CompoundType t = (CompoundType) structDictionary.get(typeName); - if (t == null) { - t = CompoundType.create(null, null, kind, cvAttrs); - t.setStructName(typeName); - structDictionary.put(typeName, t); - } - return t; - } - - private Type lookupInTypedefDictionary(String typeName) { - Type t = typedefDictionary.get(typeName); - if (t == null) { - throw new RuntimeException("Undefined reference to typedef name " + typeName); - } - return t; - } - - static class ParameterDeclaration { - private String id; - private Type type; - - ParameterDeclaration(String id, Type type) { - this.id = id; - this.type = type; - } - String id() { return id; } - Type type() { return type; } - } - - // A box for a Type. Allows type to be passed down to be modified by recursive rules. - static class TypeBox { - private Type origType; - private Type type; - private boolean isTypedef; - - TypeBox(Type type) { - this(type, false); - } - - TypeBox(Type type, boolean isTypedef) { - this.origType = type; - this.isTypedef = isTypedef; - } - - Type type() { - if (type == null) { - return origType; - } - return type; - } - void setType(Type type) { - this.type = type; - } - void reset() { - type = null; - } - - boolean isTypedef() { return isTypedef; } - - // for easier debugging - public String toString() { - String tStr = "Type=NULL_REF"; - if (type == origType) { - tStr = "Type=ORIG_TYPE"; - } else if (type != null) { - tStr = "Type: name=\"" + type.getCVAttributesString() + " " + - type.getName() + "\"; signature=\"" + type + "\"; class " + - type.getClass().getName(); - } - String oStr = "OrigType=NULL_REF"; - if (origType != null) { - oStr = "OrigType: name=\"" + origType.getCVAttributesString() + " " + - origType.getName() + "\"; signature=\"" + origType + "\"; class " + - origType.getClass().getName(); - } - return "<["+tStr + "] [" + oStr + "] " + " isTypedef=" + isTypedef+">"; - } - } - - private String getTypeString(Type t) { - StringBuilder sb = new StringBuilder(); - sb.append("["); - sb.append(t); - sb.append(", size: "); - if(null!=t) { - SizeThunk st = t.getSize(); - if(null!=st) { - sb.append(st.getClass().getName()); - } else { - sb.append("undef"); - } - } - sb.append("]"); - return sb.toString(); - } - - private void debugPrintln(String msg) { - if(debug) { - System.err.println(msg); - } - } - - private void debugPrint(String msg) { - if(debug) { - System.err.print(msg); - } - } - - private boolean doDeclaration; // Used to only process function typedefs - private String declId; - private List parameters; - private TypeDictionary typedefDictionary; - private TypeDictionary structDictionary; - private List/**/ functions = new ArrayList(); - // hash from name of an enumerated value to the EnumType to which it belongs - private HashMap/**/ enumHash = new HashMap(); - - // Storage class specifiers - private static final int AUTO = 1 << 0; - private static final int REGISTER = 1 << 1; - private static final int TYPEDEF = 1 << 2; - // Function storage class specifiers - private static final int EXTERN = 1 << 3; - private static final int STATIC = 1 << 4; - private static final int INLINE = 1 << 5; - // Type qualifiers - private static final int CONST = 1 << 6; - private static final int VOLATILE = 1 << 7; - private static final int SIGNED = 1 << 8; - private static final int UNSIGNED = 1 << 9; - - private void initDeclaration() { - doDeclaration = false; - declId = null; - } - - private void doDeclaration() { - doDeclaration = true; - } - - private void processDeclaration(Type returnType) { - if (doDeclaration) { - FunctionSymbol sym = new FunctionSymbol(declId, new FunctionType(null, null, returnType, 0)); - if (parameters != null) { // handle funcs w/ empty parameter lists (e.g., "foo()") - for (Iterator iter = parameters.iterator(); iter.hasNext(); ) { - ParameterDeclaration pd = (ParameterDeclaration) iter.next(); - sym.addArgument(pd.type(), pd.id()); - } - } - functions.add(sym); - } - } - - private int attrs2CVAttrs(int attrs) { - int cvAttrs = 0; - if ((attrs & CONST) != 0) { - cvAttrs |= CVAttributes.CONST; - } - if ((attrs & VOLATILE) != 0) { - cvAttrs |= CVAttributes.VOLATILE; - } - return cvAttrs; - } - - /** Helper routine which handles creating a pointer or array type - for [] expressions */ - private void handleArrayExpr(TypeBox tb, AST t) { - if (t != null) { - try { - int len = parseIntConstExpr(t); - tb.setType(canonicalize(new ArrayType(tb.type(), SizeThunk.mul(SizeThunk.constant(len), tb.type().getSize()), len, 0))); - return; - } catch (RecognitionException e) { - // Fall through - } - } - tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, - tb.type(), - 0))); - } - - private int parseIntConstExpr(AST t) throws RecognitionException { - return intConstExpr(t); - } - - /** Utility function: creates a new EnumType with the given name, or - returns an existing one if it has already been created. */ - private EnumType getEnumType(String enumTypeName) { - EnumType enumType = null; - Iterator it = enumHash.values().iterator(); - while (it.hasNext()) { - EnumType potentialMatch = (EnumType)it.next(); - if (potentialMatch.getName().equals(enumTypeName)) { - enumType = potentialMatch; - break; - } - } - - if (enumType == null) { - // This isn't quite correct. In theory the enum should expand to - // the size of the largest element, so if there were a long long - // entry the enum should expand to e.g. int64. However, using - // "long" here (which is what used to be the case) was - // definitely incorrect and caused problems. - enumType = new EnumType(enumTypeName, SizeThunk.INT32); - } - - return enumType; - } - - // Map used to canonicalize types. For example, we may typedef - // struct foo { ... } *pfoo; subsequent references to struct foo* should - // point to the same PointerType object that had its name set to "pfoo". - private Map canonMap = new HashMap(); - private Type canonicalize(Type t) { - Type res = (Type) canonMap.get(t); - if (res != null) { - return res; - } - canonMap.put(t, t); - return t; - } -} - -declarator[TypeBox tb] returns [String s] { - initDeclaration(); - s = null; - List params = null; - String funcPointerName = null; - TypeBox dummyTypeBox = null; -} - : #( NDeclarator - ( pointerGroup[tb] )? - - ( id:ID { s = id.getText(); } - | LPAREN funcPointerName = declarator[dummyTypeBox] RPAREN - ) - - ( #( NParameterTypeList - ( - params = parameterTypeList - | (idList)? - ) - RPAREN - ) { - if (id != null) { - declId = id.getText(); - parameters = params; // FIXME: Ken, why are we setting this class member here? - doDeclaration(); - } else if ( funcPointerName != null ) { - /* TypeBox becomes function pointer in this case */ - FunctionType ft = new FunctionType(null, null, tb.type(), 0); - if (params == null) { - // If the function pointer has no declared parameters, it's a - // void function. I'm not sure if the parameter name is - // ever referenced anywhere when the type is VoidType, so - // just in case I'll set it to a comment string so it will - // still compile if written out to code anywhere. - ft.addArgument(new VoidType(0), "/*unnamed-void*/"); - } else { - for (Iterator iter = params.iterator(); iter.hasNext(); ) { - ParameterDeclaration pd = (ParameterDeclaration) iter.next(); - ft.addArgument(pd.type(), pd.id()); - } - } - tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, - ft, - 0))); - s = funcPointerName; - } - } - | LBRACKET ( e:expr )? RBRACKET { handleArrayExpr(tb, e); } - )* - ) - ; - -typelessDeclaration { - TypeBox tb = null; -} - : #(NTypeMissing initDeclList[tb] SEMI) - ; - -declaration { - TypeBox tb = null; -} - : #( NDeclaration - tb = declSpecifiers - ( - initDeclList[tb] - )? - ( SEMI )+ - ) { processDeclaration(tb.type()); } - ; - -parameterTypeList returns [List l] { l = new ArrayList(); ParameterDeclaration decl = null; } - : ( decl = parameterDeclaration { if (decl != null) l.add(decl); } ( COMMA | SEMI )? )+ ( VARARGS )? - ; - -parameterDeclaration returns [ParameterDeclaration pd] { - Type t = null; - String decl = null; - pd = null; - TypeBox tb = null; -} - : #( NParameterDeclaration - tb = declSpecifiers - (decl = declarator[tb] | nonemptyAbstractDeclarator[tb])? - ) { pd = new ParameterDeclaration(decl, tb.type()); } - ; - -functionDef { - TypeBox tb = null; -} - : #( NFunctionDef - ( functionDeclSpecifiers)? - declarator[tb] - (declaration | VARARGS)* - compoundStatement - ) - ; - -declSpecifiers returns [TypeBox tb] { - tb = null; - Type t = null; - int x = 0; - int y = 0; -} - : ( y = storageClassSpecifier { x |= y; } - | y = typeQualifier { x |= y; } - | t = typeSpecifier[x] - )+ -{ - if (t == null && - (x & (SIGNED | UNSIGNED)) != 0) { - t = new IntType("int", SizeThunk.INTxx, ((x & UNSIGNED) != 0), attrs2CVAttrs(x)); - } - tb = new TypeBox(t, ((x & TYPEDEF) != 0)); -} - ; - -storageClassSpecifier returns [int x] { x = 0; } - : "auto" { x |= AUTO; } - | "register" { x |= REGISTER; } - | "typedef" { x |= TYPEDEF; } - | x = functionStorageClassSpecifier - ; - - -functionStorageClassSpecifier returns [int x] { x = 0; } - : "extern" { x |= EXTERN; } - | "static" { x |= STATIC; } - | "inline" { x |= INLINE; } - ; - - -typeQualifier returns [int x] { x = 0; } - : "const" { x |= CONST; } - | "volatile" { x |= VOLATILE; } - | "signed" { x |= SIGNED; } - | "unsigned" { x |= UNSIGNED; } - ; - -typeSpecifier[int attributes] returns [Type t] { - t = null; - int cvAttrs = attrs2CVAttrs(attributes); - boolean unsigned = ((attributes & UNSIGNED) != 0); -} - : "void" { t = new VoidType(cvAttrs); } - | "char" { t = new IntType("char" , SizeThunk.INT8, unsigned, cvAttrs); } - | "short" { t = new IntType("short", SizeThunk.INT16, unsigned, cvAttrs); } - | "int" { t = new IntType("int" , SizeThunk.INTxx, unsigned, cvAttrs); } - | "long" { t = new IntType("long" , SizeThunk.LONG, unsigned, cvAttrs); } - | "float" { t = new FloatType("float", SizeThunk.FLOAT, cvAttrs); } - | "double" { t = new DoubleType("double", SizeThunk.DOUBLE, cvAttrs); } - | "__int32" { t = new IntType("__int32", SizeThunk.INT32, unsigned, cvAttrs); } - | "__int64" { t = new IntType("__int64", SizeThunk.INT64, unsigned, cvAttrs); } - | "int8_t" { t = new IntType("int8_t", SizeThunk.INT8, false, cvAttrs); /* TS: always signed */ } - | "uint8_t" { t = new IntType("uint8_t", SizeThunk.INT8, true, cvAttrs); /* TS: always unsigned */ } - | "int16_t" { t = new IntType("int16_t", SizeThunk.INT16, false, cvAttrs); /* TS: always signed */ } - | "uint16_t" { t = new IntType("uint16_t", SizeThunk.INT16, true, cvAttrs); /* TS: always unsigned */ } - | "int32_t" { t = new IntType("int32_t", SizeThunk.INT32, false, cvAttrs); /* TS: always signed */ } - | "wchar_t" { t = new IntType("wchar_t", SizeThunk.INT32, false, cvAttrs); /* TS: always signed */ } - | "uint32_t" { t = new IntType("uint32_t", SizeThunk.INT32, true, cvAttrs, true); /* TS: always unsigned */ } - | "int64_t" { t = new IntType("int64_t", SizeThunk.INT64, false, cvAttrs); /* TS: always signed */ } - | "uint64_t" { t = new IntType("uint64_t", SizeThunk.INT64, true, cvAttrs, true); /* TS: always unsigned */ } - | "ptrdiff_t" { t = new IntType("ptrdiff_t", SizeThunk.POINTER, false, cvAttrs); /* TS: always signed */ } - | "intptr_t" { t = new IntType("intptr_t", SizeThunk.POINTER, false, cvAttrs); /* TS: always signed */ } - | "size_t" { t = new IntType("size_t", SizeThunk.POINTER, true, cvAttrs, true); /* TS: always unsigned */ } - | "uintptr_t" { t = new IntType("uintptr_t", SizeThunk.POINTER, true, cvAttrs, true); /* TS: always unsigned */ } - | t = structSpecifier[cvAttrs] ( attributeDecl )* - | t = unionSpecifier [cvAttrs] ( attributeDecl )* - | t = enumSpecifier [cvAttrs] - | t = typedefName [cvAttrs] - | #("typeof" LPAREN - ( (typeName )=> typeName - | expr - ) - RPAREN - ) - | "__complex" - ; - -typedefName[int cvAttrs] returns [Type t] { t = null; } - : #(NTypedefName id : ID) - { - Type tdict = lookupInTypedefDictionary(id.getText()); - t = canonicalize(tdict.getCVVariant(cvAttrs)); - debugPrintln("Adding typedef canon : [" + id.getText() + "] -> [" + tdict + "] -> "+getTypeString(t)); - } - ; - -structSpecifier[int cvAttrs] returns [Type t] { t = null; } - : #( "struct" t = structOrUnionBody[CompoundTypeKind.STRUCT, cvAttrs] ) - ; - -unionSpecifier[int cvAttrs] returns [Type t] { t = null; } - : #( "union" t = structOrUnionBody[CompoundTypeKind.UNION, cvAttrs] ) - ; - -structOrUnionBody[CompoundTypeKind kind, int cvAttrs] returns [CompoundType t] { - t = null; -} - : ( (ID LCURLY) => id:ID LCURLY { - t = (CompoundType) canonicalize(lookupInStructDictionary(id.getText(), kind, cvAttrs)); - } ( structDeclarationList[t] )? - RCURLY { t.setBodyParsed(); } - | LCURLY { t = CompoundType.create(null, null, kind, cvAttrs); } - ( structDeclarationList[t] )? - RCURLY { t.setBodyParsed(); } - | id2:ID { t = (CompoundType) canonicalize(lookupInStructDictionary(id2.getText(), kind, cvAttrs)); } - ) - ; - -structDeclarationList[CompoundType t] - : ( structDeclaration[t] )+ - ; - -structDeclaration[CompoundType containingType] { - Type t = null; - boolean addedAny = false; -} - : t = specifierQualifierList addedAny = structDeclaratorList[containingType, t] { - if (!addedAny) { - if (t != null) { - CompoundType ct = t.asCompound(); - if (ct.isUnion()) { - // Anonymous union - containingType.addField(new Field(null, t, null)); - } - } - } - } - ; - -specifierQualifierList returns [Type t] { - t = null; int x = 0; int y = 0; -} - : ( - t = typeSpecifier[x] - | y = typeQualifier { x |= y; } - )+ { - if (t == null && - (x & (SIGNED | UNSIGNED)) != 0) { - t = new IntType("int", SizeThunk.INTxx, ((x & UNSIGNED) != 0), attrs2CVAttrs(x)); - } -} - ; - -structDeclaratorList[CompoundType containingType, Type t] returns [boolean addedAny] { - addedAny = false; - boolean y = false; -} - : ( y = structDeclarator[containingType, t] { addedAny = y; })+ - ; - -structDeclarator[CompoundType containingType, Type t] returns [boolean addedAny] { - addedAny = false; - String s = null; - TypeBox tb = new TypeBox(t); -} - : - #( NStructDeclarator - ( s = declarator[tb] { containingType.addField(new Field(s, tb.type(), null)); addedAny = true; } )? - ( COLON expr { /* FIXME: bit types not handled yet */ } ) ? - ( attributeDecl )* - ) - ; - -// FIXME: this will not correctly set the name of the enumeration when -// encountering a declaration like this: -// -// typedef enum { } enumName; -// -// In this case calling getName() on the EnumType return value will -// incorrectly return HeaderParser.ANONYMOUS_ENUM_NAME instead of -// "enumName" -// -// I haven't implemented it yet because I'm not sure how to get the -// "enumName" *before* executing the enumList rule. -enumSpecifier [int cvAttrs] returns [Type t] { - t = null; -} - : #( "enum" - ( ( ID LCURLY )=> i:ID LCURLY enumList[(EnumType)(t = getEnumType(i.getText()))] RCURLY - | LCURLY enumList[(EnumType)(t = getEnumType(ANONYMOUS_ENUM_NAME))] RCURLY - | ID { t = getEnumType(i.getText()); } - ) - ) - ; - -enumList[EnumType enumeration] { - long defaultEnumerantValue = 0; -} - : ( defaultEnumerantValue = enumerator[enumeration, defaultEnumerantValue] )+ - ; - -enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValue] { - newDefaultValue = defaultValue; -} - : eName:ID ( ASSIGN eVal:expr )? { - long value = 0; - if (eVal != null) { - String vTxt = eVal.getAllChildrenText(); - if (enumHash.containsKey(vTxt)) { - EnumType oldEnumType = (EnumType) enumHash.get(vTxt); - value = oldEnumType.getEnumValue(vTxt); - } else { - try { - value = Long.decode(vTxt).longValue(); - } catch (NumberFormatException e) { - System.err.println("NumberFormatException: ID[" + eName.getText() + "], VALUE=[" + vTxt + "]"); - throw e; - } - } - } else { - value = defaultValue; - } - - newDefaultValue = value+1; - String eTxt = eName.getText(); - if (enumHash.containsKey(eTxt)) { - EnumType oldEnumType = (EnumType) enumHash.get(eTxt); - long oldValue = oldEnumType.getEnumValue(eTxt); - System.err.println("WARNING: redefinition of enumerated value '" + eTxt + "';" + - " existing definition is in enumeration '" + oldEnumType.getName() + - "' with value " + oldValue + " and new definition is in enumeration '" + - enumeration.getName() + "' with value " + value); - // remove old definition - oldEnumType.removeEnumerate(eTxt); - } - // insert new definition - enumeration.addEnum(eTxt, value); - enumHash.put(eTxt, enumeration); - debugPrintln("ENUM [" + enumeration.getName() + "]: " + eTxt + " = " + enumeration.getEnumValue(eTxt) + - " (new default = " + newDefaultValue + ")"); - } - ; - -initDeclList[TypeBox tb] - : ( initDecl[tb] )+ - ; - -initDecl[TypeBox tb] { - String declName = null; -} - : #( NInitDecl - declName = declarator[tb] { - debugPrintln("GOT declName: " + declName + " TB=" + tb); - } - ( attributeDecl )* - ( ASSIGN initializer - | COLON expr - )? - ) -{ - if ((declName != null) && (tb != null) && tb.isTypedef()) { - Type t = tb.type(); - debugPrint("Adding typedef mapping: [" + declName + "] -> "+getTypeString(t)); - if (!t.hasTypedefName()) { - t.setName(declName); - debugPrint(" - declName -> "+getTypeString(t)); - } else { - // copy type to preserve declName ! - t = (Type) t.clone(); - t.setName(declName); - debugPrint(" - copy -> "+getTypeString(t)); - } - t = canonicalize(t); - debugPrintln(" - canon -> "+getTypeString(t)); - typedefDictionary.put(declName, t); - // Clear out PointerGroup effects in case another typedef variant follows - tb.reset(); - } -} - ; - -pointerGroup[TypeBox tb] { int x = 0; int y = 0; } - : #( NPointerGroup ( STAR { x = 0; y = 0; } ( y = typeQualifier { x |= y; } )* - { - debugPrintln("IN PTR GROUP: TB=" + tb); - if (tb != null) { - tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, - tb.type(), - attrs2CVAttrs(x)))); - } - } - )+ ) - ; - - -functionDeclSpecifiers - : - ( functionStorageClassSpecifier - | typeQualifier - | typeSpecifier[0] - )+ - ; - -typeName { - TypeBox tb = null; -} - : specifierQualifierList (nonemptyAbstractDeclarator[tb])? - ; - - -/* FIXME: the handling of types in this rule has not been well thought - out and is known to be incomplete. Currently it is only used to handle - pointerGroups for unnamed parameters. */ -nonemptyAbstractDeclarator[TypeBox tb] - : #( NNonemptyAbstractDeclarator - ( pointerGroup[tb] - ( (LPAREN - ( nonemptyAbstractDeclarator[tb] - | parameterTypeList - )? - RPAREN) - | (LBRACKET (e1:expr)? RBRACKET) { handleArrayExpr(tb, e1); } - )* - - | ( (LPAREN - ( nonemptyAbstractDeclarator[tb] - | parameterTypeList - )? - RPAREN) - | (LBRACKET (e2:expr)? RBRACKET) { handleArrayExpr(tb, e2); } - )+ - ) - ) - ; - -/* Helper routine for parsing expressions which evaluate to integer - constants. Can be made more complicated as necessary. */ -intConstExpr returns [int i] { i = -1; } - : n:Number { return Integer.parseInt(n.getText()); } - ; diff --git a/src/java/com/jogamp/gluegen/cgram/StdCParser.g b/src/java/com/jogamp/gluegen/cgram/StdCParser.g deleted file mode 100644 index 7b34656..0000000 --- a/src/java/com/jogamp/gluegen/cgram/StdCParser.g +++ /dev/null @@ -1,1401 +0,0 @@ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - Copyright (c) Non, Inc. 1997 -- All Rights Reserved - -PROJECT: C Compiler -MODULE: Parser -FILE: stdc.g - -AUTHOR: John D. Mitchell (john@non.net), Jul 12, 1997 - -REVISION HISTORY: - - Name Date Description - ---- ---- ----------- - JDM 97.07.12 Initial version. - JTC 97.11.18 Declaration vs declarator & misc. hacking. - JDM 97.11.20 Fixed: declaration vs funcDef, - parenthesized expressions, - declarator iteration, - varargs recognition, - empty source file recognition, - and some typos. - - -DESCRIPTION: - - This grammar supports the Standard C language. - - Note clearly that this grammar does *NOT* deal with - preprocessor functionality (including things like trigraphs) - Nor does this grammar deal with multi-byte characters nor strings - containing multi-byte characters [these constructs are "exercises - for the reader" as it were :-)]. - - Please refer to the ISO/ANSI C Language Standard if you believe - this grammar to be in error. Please cite chapter and verse in any - correspondence to the author to back up your claim. - -TODO: - - - typedefName is commented out, needs a symbol table to resolve - ambiguity. - - - trees - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - - -header { - package com.jogamp.gluegen.cgram; - - import java.io.*; - - import antlr.CommonAST; - import antlr.DumpASTVisitor; -} - - -class StdCParser extends Parser; - -options - { - k = 2; - exportVocab = STDC; - buildAST = true; - ASTLabelType = "TNode"; - - // Copied following options from java grammar. - codeGenMakeSwitchThreshold = 2; - codeGenBitsetTestThreshold = 3; - } - - -{ - // 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; x0)?" [inputState.guessing "+ inputState.guessing + "]":"")); - - } - - } - try { - if ( LA(1)!=t ) { - if ( debugging ){ - for (int x=0; x "+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 declaration - | functionDef - | asm_expr - ; - - -asm_expr - : "asm"^ - ("volatile")? LCURLY! expr RCURLY! SEMI! - ; - - -declaration - { AST ds1 = null; } - : ds:declSpecifiers { ds1 = astFactory.dupList(#ds); } - ( - initDeclList[ds1] - )? - SEMI! - { ## = #( #[NDeclaration], ##); } - - ; - - -declSpecifiers - { int specCount=0; } - : ( options { // this loop properly aborts when - // it finds a non-typedefName ID MBZ - warnWhenFollowAmbig = false; - } : - s:storageClassSpecifier - | typeQualifier - | ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=> - specCount = typeSpecifier[specCount] - )+ - ; - -storageClassSpecifier - : "auto" - | "register" - | "typedef" - | functionStorageClassSpecifier - ; - - -functionStorageClassSpecifier - : "extern" - | "static" - ; - - -typeQualifier - : "const" - | "volatile" - ; - -typeSpecifier [int specCount] returns [int retSpecCount] - { retSpecCount = specCount + 1; } - : - ( "void" - | "char" - | "short" - | "int" - | "long" - | "float" - | "double" - | "signed" - | "unsigned" - | "int8_t" - | "uint8_t" - | "int16_t" - | "uint16_t" - | "__int32" - | "int32_t" - | "wchar_t" - | "uint32_t" - | "__int64" - | "int64_t" - | "uint64_t" - | "ptrdiff_t" - | "intptr_t" - | "size_t" - | "uintptr_t" - | structOrUnionSpecifier - | enumSpecifier - | { specCount == 0 }? typedefName - ) - ; - - -typedefName - : { isTypedefName ( LT(1).getText() ) }? - i:ID { ## = #(#[NTypedefName], #i); } - ; - -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, ## ); - } - ; - - -structOrUnion - : "struct" - | "union" - ; - - -structDeclarationList - : ( structDeclaration )+ - ; - - -structDeclaration - : specifierQualifierList structDeclaratorList ( SEMI! )+ - ; - - -specifierQualifierList - { int specCount = 0; } - : ( options { // this loop properly aborts when - // it finds a non-typedefName ID MBZ - warnWhenFollowAmbig = false; - } : - ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=> - specCount = typeSpecifier[specCount] - | typeQualifier - )+ - ; - - -structDeclaratorList - : structDeclarator ( COMMA! structDeclarator )* - ; - - -structDeclarator - : - ( COLON constExpr - | declarator[false] ( COLON constExpr )? - ) - { ## = #( #[NStructDeclarator], ##); } - ; - - -enumSpecifier - : "enum"^ - ( ( ID LCURLY )=> i:ID LCURLY enumList[i.getText()] RCURLY! - | LCURLY enumList["anonymous"] RCURLY! - | ID - ) - ; - - -enumList[String enumName] - : enumerator[enumName] ( COMMA! enumerator[enumName] )* - ; - -enumerator[String enumName] - : i:ID { symbolTable.add( i.getText(), - #( null, - #[LITERAL_enum, "enum"], - #[ ID, enumName] - ) - ); - } - (ASSIGN constExpr)? - ; - - -initDeclList[AST declarationSpecifiers] - : initDecl[declarationSpecifiers] - ( COMMA! initDecl[declarationSpecifiers] )* - ; - - -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) ); - } - ( ASSIGN initializer - | COLON expr - )? - { ## = #( #[NInitDecl], ## ); } - - ; - -pointerGroup - : ( STAR ( typeQualifier )* )+ { ## = #( #[NPointerGroup], ##); } - ; - - - -idList - : ID ( COMMA! ID )* - ; - - -initializer - : ( assignExpr - | LCURLY initializerList ( COMMA! )? RCURLY! - ) - { ## = #( #[NInitializer], ## ); } - ; - - -initializerList - : initializer ( COMMA! initializer )* - ; - - -declarator[boolean isFunctionDefinition] returns [String declName] - { declName = ""; } - : - ( pointerGroup )? - - ( id:ID { declName = id.getText(); } - | LPAREN declName = declarator[false] RPAREN - ) - - ( ! LPAREN - { - if (isFunctionDefinition) { - pushScope(declName); - } - else { - pushScope("!"+declName); - } - } - ( - (declSpecifiers)=> p:parameterTypeList - { - ## = #( null, ##, #( #[NParameterTypeList], #p ) ); - } - - | (i:idList)? - { - ## = #( null, ##, #( #[NParameterTypeList], #i ) ); - } - ) - { - 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 = (TNode) #[ NEmptyExpression ]; } - if ( #e2 == null) { #e2 = (TNode) #[ NEmptyExpression ]; } - if ( #e3 == null) { #e3 = (TNode) #[ 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 - ; - - - - - - -{ - import java.io.*; - import antlr.*; -} - -class StdCLexer extends Lexer; - -options - { - k = 3; - exportVocab = STDC; - testLiterals = false; - } - -{ - 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) ); - } - - public void addDefine(String name, String value) - { - } - - 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() { - lineObject.newline(); - } - - - - - - -} - -protected -Vocabulary - : '\3'..'\377' - ; - - -/* Operators: */ - -ASSIGN : '=' ; -COLON : ':' ; -COMMA : ',' ; -QUESTION : '?' ; -SEMI : ';' ; -PTR : "->" ; - - -// DOT & VARARGS are commented out since they are generated as part of -// the Number rule below due to some bizarre lexical ambiguity shme. - -// DOT : '.' ; -protected -DOT:; - -// VARARGS : "..." ; -protected -VARARGS:; - - -LPAREN : '(' ; -RPAREN : ')' ; -LBRACKET : '[' ; -RBRACKET : ']' ; -LCURLY : '{' ; -RCURLY : '}' ; - -EQUAL : "==" ; -NOT_EQUAL : "!=" ; -LTE : "<=" ; -LT : "<" ; -GTE : ">=" ; -GT : ">" ; - -DIV : '/' ; -DIV_ASSIGN : "/=" ; -PLUS : '+' ; -PLUS_ASSIGN : "+=" ; -INC : "++" ; -MINUS : '-' ; -MINUS_ASSIGN : "-=" ; -DEC : "--" ; -STAR : '*' ; -STAR_ASSIGN : "*=" ; -MOD : '%' ; -MOD_ASSIGN : "%=" ; -RSHIFT : ">>" ; -RSHIFT_ASSIGN : ">>=" ; -LSHIFT : "<<" ; -LSHIFT_ASSIGN : "<<=" ; - -LAND : "&&" ; -LNOT : '!' ; -LOR : "||" ; - -BAND : '&' ; -BAND_ASSIGN : "&=" ; -BNOT : '~' ; -BOR : '|' ; -BOR_ASSIGN : "|=" ; -BXOR : '^' ; -BXOR_ASSIGN : "^=" ; - - -Whitespace - : ( ( '\003'..'\010' | '\t' | '\013' | '\f' | '\016'.. '\037' | '\177'..'\377' | ' ' ) - | "\r\n" { newline(); } - | ( '\n' | '\r' ) { newline(); } - ) { _ttype = Token.SKIP; } - ; - - -Comment - : "/*" - ( { LA(2) != '/' }? '*' - | "\r\n" { deferredNewline(); } - | ( '\r' | '\n' ) { deferredNewline(); } - | ~( '*'| '\r' | '\n' ) - )* - "*/" { _ttype = Token.SKIP; - } - ; - - -CPPComment - : - "//" ( ~('\n') )* - { - _ttype = Token.SKIP; - } - ; - -protected NonWhitespace - : (~('\r' | '\n'))* - ; - - -PREPROC_DIRECTIVE -options { - paraphrase = "a line directive"; -} - - : - '#' - ( ( "line" || (( ' ' | '\t' | '\014')+ '0'..'9')) => LineDirective - | ( (Space)* "define" (Space)* i:ID (Space)* (n:DefineExpr)? - nw:NonWhitespace - ("\r\n" | "\r" | "\n") ) { - if (n != null) { - //System.out.println("addDefine: #define " + i.getText() + " " + n.getText()); - addDefine(i.getText(), n.getText()); - } else { - setPreprocessingDirective("#define " + i.getText() + " " + nw.getText()); - } - } - | (~'\n')* { setPreprocessingDirective(getText()); } - ) - { - _ttype = Token.SKIP; - } - ; - -DefineExpr: - ((LPAREN) (Space)* (DefineExpr2) (Space)* (RPAREN)) | (DefineExpr2) -; - -DefineExpr2: - (Number) - ((Space)* (LSHIFT | RSHIFT | PLUS | MINUS | STAR | DIV | MOD) (Space)* (DefineExpr))? -; - - -protected Space: - ( ' ' | '\t' | '\014') - ; - -protected LineDirective -{ - boolean oldCountingTokens = countingTokens; - countingTokens = false; -} -: - { - lineObject = new LineObject(); - deferredLineCount = 0; - } - ("line")? //this would be for if the directive started "#line", but not there for GNU directives - (Space)+ - n:Number { lineObject.setLine(Integer.parseInt(n.getText())); } - (Space)+ - ( fn:StringLiteral { try { - lineObject.setSource(fn.getText().substring(1,fn.getText().length()-1)); - } - catch (StringIndexOutOfBoundsException e) { /*not possible*/ } - } - | fi:ID { lineObject.setSource(fi.getText()); } - )? - (Space)* - ("1" { lineObject.setEnteringFile(true); } )? - (Space)* - ("2" { lineObject.setReturningToFile(true); } )? - (Space)* - ("3" { lineObject.setSystemHeader(true); } )? - (Space)* - ("4" { lineObject.setTreatAsC(true); } )? - (~('\r' | '\n'))* - ("\r\n" | "\r" | "\n") - { - preprocessorInfoChannel.addLineForTokenNumber(new LineObject(lineObject), new Integer(tokenNumber)); - countingTokens = oldCountingTokens; - } - ; - - - -/* Literals: */ - -/* - * Note that we do NOT handle tri-graphs nor multi-byte sequences. - */ - - -/* - * Note that we can't have empty character constants (even though we - * can have empty strings :-). - */ -CharLiteral - : '\'' ( Escape | ~( '\'' ) ) '\'' - ; - - -/* - * Can't have raw imbedded newlines in string constants. Strict reading of - * the standard gives odd dichotomy between newlines & carriage returns. - * Go figure. - */ -StringLiteral - : '"' - ( Escape - | ( - '\r' { deferredNewline(); } - | '\n' { - deferredNewline(); - _ttype = BadStringLiteral; - } - | '\\' '\n' { - deferredNewline(); - } - ) - | ~( '"' | '\r' | '\n' | '\\' ) - )* - '"' - ; - - -protected BadStringLiteral - : // Imaginary token. - ; - - -/* - * Handle the various escape sequences. - * - * Note carefully that these numeric escape *sequences* are *not* of the - * same form as the C language numeric *constants*. - * - * There is no such thing as a binary numeric escape sequence. - * - * Octal escape sequences are either 1, 2, or 3 octal digits exactly. - * - * There is no such thing as a decimal escape sequence. - * - * Hexadecimal escape sequences are begun with a leading \x and continue - * until a non-hexadecimal character is found. - * - * No real handling of tri-graph sequences, yet. - */ - -protected -Escape - : '\\' - ( options{warnWhenFollowAmbig=false;}: - 'a' - | 'b' - | 'f' - | 'n' - | 'r' - | 't' - | 'v' - | '"' - | '\'' - | '\\' - | '?' - | ('0'..'3') ( options{warnWhenFollowAmbig=false;}: Digit ( options{warnWhenFollowAmbig=false;}: Digit )? )? - | ('4'..'7') ( options{warnWhenFollowAmbig=false;}: Digit )? - | 'x' ( options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F' )+ - ) - ; - - -/* Numeric Constants: */ - -protected -Digit - : '0'..'9' - ; - -protected -LongSuffix - : 'l' - | 'L' - ; - -protected -UnsignedSuffix - : 'u' - | 'U' - ; - -protected -FloatSuffix - : 'f' - | 'F' - ; - -protected -Exponent - : ( 'e' | 'E' ) ( '+' | '-' )? ( Digit )+ - ; - - -protected -DoubleDoubleConst:; - -protected -FloatDoubleConst:; - -protected -LongDoubleConst:; - -protected -IntOctalConst:; - -protected -LongOctalConst:; - -protected -UnsignedOctalConst:; - -protected -IntIntConst:; - -protected -LongIntConst:; - -protected -UnsignedIntConst:; - -protected -IntHexConst:; - -protected -LongHexConst:; - -protected -UnsignedHexConst:; - - - - -Number - : ( ( Digit )+ ( '.' | 'e' | 'E' ) )=> ( Digit )+ - ( '.' ( Digit )* ( Exponent )? - | Exponent - ) { _ttype = DoubleDoubleConst; } - ( FloatSuffix { _ttype = FloatDoubleConst; } - | LongSuffix { _ttype = LongDoubleConst; } - )? - - | ( "..." )=> "..." { _ttype = VARARGS; } - - | '.' { _ttype = DOT; } - ( ( Digit )+ ( Exponent )? - { _ttype = DoubleDoubleConst; } - ( FloatSuffix { _ttype = FloatDoubleConst; } - | LongSuffix { _ttype = LongDoubleConst; } - )? - )? - - | '0' ( '0'..'7' )* { _ttype = IntOctalConst; } - ( LongSuffix { _ttype = LongOctalConst; } - | UnsignedSuffix { _ttype = UnsignedOctalConst; } - )? - - | '1'..'9' ( Digit )* { _ttype = IntIntConst; } - ( LongSuffix { _ttype = LongIntConst; } - | UnsignedSuffix { _ttype = UnsignedIntConst; } - )? - - | '0' ( 'x' | 'X' ) ( 'a'..'f' | 'A'..'F' | Digit )+ - { _ttype = IntHexConst; } - ( LongSuffix { _ttype = LongHexConst; } - | UnsignedSuffix { _ttype = UnsignedHexConst; } - )? - ; - - -ID - options - { - testLiterals = true; - } - : ( 'a'..'z' | 'A'..'Z' | '_' ) - ( 'a'..'z' | 'A'..'Z' | '_' | '0'..'9' )* - ; - - diff --git a/src/java/com/jogamp/gluegen/jgram/JavaParser.g b/src/java/com/jogamp/gluegen/jgram/JavaParser.g deleted file mode 100644 index f67579e..0000000 --- a/src/java/com/jogamp/gluegen/jgram/JavaParser.g +++ /dev/null @@ -1,1315 +0,0 @@ -/* Java 1.3 Recognizer - * - * Run 'java Main [-showtree] directory-full-of-java-files' - * - * [The -showtree option pops up a Swing frame that shows - * the AST constructed from the parser.] - * - * Run 'java Main ' - * - * Contributing authors: - * John Mitchell johnm@non.net - * Terence Parr parrt@magelang.com - * John Lilley jlilley@empathy.com - * Scott Stanchfield thetick@magelang.com - * Markus Mohnen mohnen@informatik.rwth-aachen.de - * Peter Williams pete.williams@sun.com - * Allan Jacobs Allan.Jacobs@eng.sun.com - * Steve Messick messick@redhills.com - * John Pybus john@pybus.org - * - * Version 1.00 December 9, 1997 -- initial release - * Version 1.01 December 10, 1997 - * fixed bug in octal def (0..7 not 0..8) - * Version 1.10 August 1998 (parrt) - * added tree construction - * fixed definition of WS,comments for mac,pc,unix newlines - * added unary plus - * Version 1.11 (Nov 20, 1998) - * Added "shutup" option to turn off last ambig warning. - * Fixed inner class def to allow named class defs as statements - * synchronized requires compound not simple statement - * add [] after builtInType DOT class in primaryExpression - * "const" is reserved but not valid..removed from modifiers - * Version 1.12 (Feb 2, 1999) - * Changed LITERAL_xxx to xxx in tree grammar. - * Updated java.g to use tokens {...} now for 2.6.0 (new feature). - * - * Version 1.13 (Apr 23, 1999) - * Didn't have (stat)? for else clause in tree parser. - * Didn't gen ASTs for interface extends. Updated tree parser too. - * Updated to 2.6.0. - * Version 1.14 (Jun 20, 1999) - * Allowed final/abstract on local classes. - * Removed local interfaces from methods - * Put instanceof precedence where it belongs...in relationalExpr - * It also had expr not type as arg; fixed it. - * Missing ! on SEMI in classBlock - * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus). - * fixed: didn't like Object[].class in parser or tree parser - * Version 1.15 (Jun 26, 1999) - * Screwed up rule with instanceof in it. :( Fixed. - * Tree parser didn't like (expr).something; fixed. - * Allowed multiple inheritance in tree grammar. oops. - * Version 1.16 (August 22, 1999) - * Extending an interface built a wacky tree: had extra EXTENDS. - * Tree grammar didn't allow multiple superinterfaces. - * Tree grammar didn't allow empty var initializer: {} - * Version 1.17 (October 12, 1999) - * ESC lexer rule allowed 399 max not 377 max. - * java.tree.g didn't handle the expression of synchronized - * statements. - * Version 1.18 (August 12, 2001) - * Terence updated to Java 2 Version 1.3 by - * observing/combining work of Allan Jacobs and Steve - * Messick. Handles 1.3 src. Summary: - * o primary didn't include boolean.class kind of thing - * o constructor calls parsed explicitly now: - * see explicitConstructorInvocation - * o add strictfp modifier - * o missing objBlock after new expression in tree grammar - * o merged local class definition alternatives, moved after declaration - * o fixed problem with ClassName.super.field - * o reordered some alternatives to make things more efficient - * o long and double constants were not differentiated from int/float - * o whitespace rule was inefficient: matched only one char - * o add an examples directory with some nasty 1.3 cases - * o made Main.java use buffered IO and a Reader for Unicode support - * o supports UNICODE? - * Using Unicode charVocabulay makes code file big, but only - * in the bitsets at the end. I need to make ANTLR generate - * unicode bitsets more efficiently. - * Version 1.19 (April 25, 2002) - * Terence added in nice fixes by John Pybus concerning floating - * constants and problems with super() calls. John did a nice - * reorg of the primary/postfix expression stuff to read better - * and makes f.g.super() parse properly (it was METHOD_CALL not - * a SUPER_CTOR_CALL). Also: - * - * o "finally" clause was a root...made it a child of "try" - * o Added stuff for asserts too for Java 1.4, but *commented out* - * as it is not backward compatible. - * - * Version 1.20 (October 27, 2002) - * - * Terence ended up reorging John Pybus' stuff to - * remove some nondeterminisms and some syntactic predicates. - * Note that the grammar is stricter now; e.g., this(...) must - * be the first statement. - * - * Trinary ?: operator wasn't working as array name: - * (isBig ? bigDigits : digits)[i]; - * - * Checked parser/tree parser on source for - * Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4, - * and the 110k-line jGuru server source. - * - * Version 1.21 (October 17, 2003) - * Fixed lots of problems including: - * Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g - * He found a problem/fix with floating point that start with 0 - * Ray also fixed problem that (int.class) was not recognized. - * Thorsten van Ellen noticed that \n are allowed incorrectly in strings. - * TJP fixed CHAR_LITERAL analogously. - * - * Version 1.22 (April 14, 2004) - * Changed vocab to be ..\uFFFE to avoid -1 char. removed dummy VOCAB rule. - * - * This grammar is in the PUBLIC DOMAIN - */ - -header { - package com.jogamp.gluegen.jgram; - - import java.util.*; - - import antlr.CommonAST; -} - -class JavaParser extends Parser; - -options { - k = 2; // two token lookahead - exportVocab=Java; // Call its vocabulary "Java" - codeGenMakeSwitchThreshold = 2; // Some optimizations - codeGenBitsetTestThreshold = 3; - defaultErrorHandler = false; // Don't generate parser error handlers - buildAST = true; - //buildAST = false; -} - -tokens { - BLOCK; MODIFIERS; OBJBLOCK; SLIST; CTOR_DEF; METHOD_DEF; VARIABLE_DEF; - INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF; - PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE; - PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP; - POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT; - IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION; - FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract"; - STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; -} - -{ - public void clearParsedEnumNames() { - enumNames.clear(); - } - - /** Returns the EnumTypes this HeaderParser processed. */ - public Set getParsedEnumNames() { - return enumNames; - } - - /** Clears the list of functions this HeaderParser has parsed. - Useful when reusing the same HeaderParser for more than one - header file. */ - public void clearParsedFunctionNames() { - functionNames.clear(); - } - - /** Returns the list of FunctionSymbols this HeaderParser has parsed. */ - public Set getParsedFunctionNames() { - return functionNames; - } - - private Set functionNames = new HashSet(); - // hash from name of an enumerated value to the EnumType to which it belongs - private Set enumNames = new HashSet(); - - private int blockDepth = 0; -} - -// Compilation Unit: In Java, this is a single file. This is the start -// rule for this parser -compilationUnit - : // A compilation unit starts with an optional package definition - ( packageDefinition - | /* nothing */ - ) - - // Next we have a series of zero or more import statements - ( importDefinition )* - - // Wrapping things up with any number of class or interface - // definitions - ( typeDefinition )* - - EOF! - ; - - -// Package statement: "package" followed by an identifier. -packageDefinition - options {defaultErrorHandler = true;} // let ANTLR handle errors - : p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI! - ; - - -// Import statement: import followed by a package or class name -importDefinition - options {defaultErrorHandler = true;} - : i:"import"^ {#i.setType(IMPORT);} identifierStar SEMI! - ; - -// A type definition in a file is either a class or interface definition. -typeDefinition - options {defaultErrorHandler = true;} - : m:modifiers! - ( classDefinition[#m] - | interfaceDefinition[#m] - ) - | SEMI! - ; - -/** A declaration is the creation of a reference or primitive-type variable - * Create a separate Type/Var tree for each var in the var list. - */ -declaration! - : m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t] - {#declaration = #v;} - ; - -// A type specification is a type name with possible brackets afterwards -// (which would make it an array type). -typeSpec[boolean addImagNode] - : classTypeSpec[addImagNode] - | builtInTypeSpec[addImagNode] - ; - -// A class type specification is a class type with possible brackets afterwards -// (which would make it an array type). -classTypeSpec[boolean addImagNode] - : identifier (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* - { - if ( addImagNode ) { - #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec); - } - } - ; - -// A builtin type specification is a builtin type with possible brackets -// afterwards (which would make it an array type). -builtInTypeSpec[boolean addImagNode] - : builtInType (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* - { - if ( addImagNode ) { - #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec); - } - } - ; - -// A type name. which is either a (possibly qualified) class name or -// a primitive (builtin) type -type - : identifier - | builtInType - ; - -// The primitive types. -builtInType - : "void" - | "boolean" - | "byte" - | "char" - | "short" - | "int" - | "float" - | "long" - | "double" - ; - -// A (possibly-qualified) java identifier. We start with the first IDENT -// and expand its name by adding dots and following IDENTS -identifier - : IDENT ( DOT^ IDENT )* - ; - -identifierStar - : IDENT - ( DOT^ IDENT )* - ( DOT^ STAR )? - ; - -// A list of zero or more modifiers. We could have used (modifier)* in -// place of a call to modifiers, but I thought it was a good idea to keep -// this rule separate so they can easily be collected in a Vector if -// someone so desires -modifiers - : ( modifier )* - {#modifiers = #([MODIFIERS, "MODIFIERS"], #modifiers);} - ; - -// modifiers for Java classes, interfaces, class/instance vars and methods -modifier - : "private" - | "public" - | "protected" - | "static" - | "transient" - | "final" - | "abstract" - | "native" - | "threadsafe" - | "synchronized" -// | "const" // reserved word, but not valid - | "volatile" - | "strictfp" - ; - -// Definition of a Java class -classDefinition![AST modifiers] - : "class" IDENT - // it _might_ have a superclass... - sc:superClassClause - // it might implement some interfaces... - ic:implementsClause - // now parse the body of the class - cb:classBlock - {#classDefinition = #(#[CLASS_DEF,"CLASS_DEF"], - modifiers,IDENT,sc,ic,cb);} - ; - -superClassClause! - : ( "extends" id:identifier )? - {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],id);} - ; - -// Definition of a Java Interface -interfaceDefinition![AST modifiers] - : "interface" IDENT - // it might extend some other interfaces - ie:interfaceExtends - // now parse the body of the interface (looks like a class...) - cb:classBlock - {#interfaceDefinition = #(#[INTERFACE_DEF,"INTERFACE_DEF"], - modifiers,IDENT,ie,cb);} - ; - - -// This is the body of a class. You can have fields and extra semicolons, -// That's about it (until you see what a field is...) -classBlock - : LCURLY! { blockDepth++; } - ( field | SEMI! )* - RCURLY! { blockDepth--; } - {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);} - ; - -// An interface can extend several other interfaces... -interfaceExtends - : ( - e:"extends"! - identifier ( COMMA! identifier )* - )? - {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"], - #interfaceExtends);} - ; - -// A class can implement several interfaces... -implementsClause - : ( - i:"implements"! identifier ( COMMA! identifier )* - )? - {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"], - #implementsClause);} - ; - -// Now the various things that can be defined inside a class or interface... -// Note that not all of these are really valid in an interface (constructors, -// for example), and if this grammar were used for a compiler there would -// need to be some semantic checks to make sure we're doing the right thing... -field! - : // method, constructor, or variable declaration - mods:modifiers - ( h:ctorHead s:constructorBody // constructor - {#field = #(#[CTOR_DEF,"CTOR_DEF"], mods, h, s);} - - | cd:classDefinition[#mods] // inner class - {#field = #cd;} - - | id:interfaceDefinition[#mods] // inner interface - {#field = #id;} - - | t:typeSpec[false] // method or variable declaration(s) - ( fn:IDENT // the name of the method - - // parse the formal parameter declarations. - LPAREN! param:parameterDeclarationList RPAREN! - - rt:declaratorBrackets[#t] - - // get the list of exceptions that this method is - // declared to throw - (tc:throwsClause)? - - ( s2:compoundStatement | SEMI ) - {#field = #(#[METHOD_DEF,"METHOD_DEF"], - mods, - #(#[TYPE,"TYPE"],rt), - fn, - param, - tc, - s2); - if(blockDepth==1) { - functionNames.add(fn.getText()); } } - | v:variableDefinitions[#mods,#t] SEMI -// {#field = #(#[VARIABLE_DEF,"VARIABLE_DEF"], v);} - {#field = #v;} - ) - ) - - // "static { ... }" class initializer - | "static" s3:compoundStatement - {#field = #(#[STATIC_INIT,"STATIC_INIT"], s3);} - - // "{ ... }" instance initializer - | s4:compoundStatement - {#field = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} - ; - -constructorBody - : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; } - ( options { greedy=true; } : explicitConstructorInvocation)? - (statement)* - RCURLY! { blockDepth--; } - ; - -/** Catch obvious constructor calls, but not the expr.super(...) calls */ -explicitConstructorInvocation - : "this"! lp1:LPAREN^ argList RPAREN! SEMI! - {#lp1.setType(CTOR_CALL);} - | "super"! lp2:LPAREN^ argList RPAREN! SEMI! - {#lp2.setType(SUPER_CTOR_CALL);} - ; - -variableDefinitions[AST mods, AST t] - : variableDeclarator[getASTFactory().dupTree(mods), - getASTFactory().dupTree(t)] - ( COMMA! - variableDeclarator[getASTFactory().dupTree(mods), - getASTFactory().dupTree(t)] - )* - ; - -/** Declaration of a variable. This can be a class/instance variable, - * or a local variable in a method - * It can also include possible initialization. - */ -variableDeclarator![AST mods, AST t] - : id:IDENT d:declaratorBrackets[t] v:varInitializer - {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],d), id, v); - if(blockDepth==1) { - enumNames.add(id.getText()); - } - } - ; - -declaratorBrackets[AST typ] - : {#declaratorBrackets=typ;} - (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* - ; - -varInitializer - : ( ASSIGN^ initializer )? - ; - -// This is an initializer used to set up an array. -arrayInitializer - : lc:LCURLY^ {#lc.setType(ARRAY_INIT); blockDepth++; } - ( initializer - ( - // CONFLICT: does a COMMA after an initializer start a new - // initializer or start the option ',' at end? - // ANTLR generates proper code by matching - // the comma as soon as possible. - options { - warnWhenFollowAmbig = false; - } - : - COMMA! initializer - )* - (COMMA!)? - )? - RCURLY! { blockDepth--; } - ; - - -// The two "things" that can initialize an array element are an expression -// and another (nested) array initializer. -initializer - : expression - | arrayInitializer - ; - -// This is the header of a method. It includes the name and parameters -// for the method. -// This also watches for a list of exception classes in a "throws" clause. -ctorHead - : IDENT // the name of the method - - // parse the formal parameter declarations. - LPAREN! parameterDeclarationList RPAREN! - - // get the list of exceptions that this method is declared to throw - (throwsClause)? - ; - -// This is a list of exception classes that the method is declared to throw -throwsClause - : "throws"^ identifier ( COMMA! identifier )* - ; - - -// A list of formal parameters -parameterDeclarationList - : ( parameterDeclaration ( COMMA! parameterDeclaration )* )? - {#parameterDeclarationList = #(#[PARAMETERS,"PARAMETERS"], - #parameterDeclarationList);} - ; - -// A formal parameter. -parameterDeclaration! - : pm:parameterModifier t:typeSpec[false] id:IDENT - pd:declaratorBrackets[#t] - {#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"], - pm, #([TYPE,"TYPE"],pd), id);} - ; - -parameterModifier - : (f:"final")? - {#parameterModifier = #(#[MODIFIERS,"MODIFIERS"], f);} - ; - -// Compound statement. This is used in many contexts: -// Inside a class definition prefixed with "static": -// it is a class initializer -// Inside a class definition without "static": -// it is an instance initializer -// As the body of a method -// As a completely indepdent braced block of code inside a method -// it starts a new scope for variable definitions - -compoundStatement - : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; } - // include the (possibly-empty) list of statements - (statement)* - RCURLY! { blockDepth--; } - ; - - -statement - // A list of statements in curly braces -- start a new scope! - : compoundStatement - - // declarations are ambiguous with "ID DOT" relative to expression - // statements. Must backtrack to be sure. Could use a semantic - // predicate to test symbol table to see what the type was coming - // up, but that's pretty hard without a symbol table ;) - | (declaration)=> declaration SEMI! - - // An expression statement. This could be a method call, - // assignment statement, or any other expression evaluated for - // side-effects. - | expression SEMI! - - // class definition - | m:modifiers! classDefinition[#m] - - // Attach a label to the front of a statement - | IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement - - // If-else statement - | "if"^ LPAREN! expression RPAREN! statement - ( - // CONFLICT: the old "dangling-else" problem... - // ANTLR generates proper code matching - // as soon as possible. Hush warning. - options { - warnWhenFollowAmbig = false; - } - : - "else"! statement - )? - - // For statement - | "for"^ - LPAREN! - forInit SEMI! // initializer - forCond SEMI! // condition test - forIter // updater - RPAREN! - statement // statement to loop over - - // While statement - | "while"^ LPAREN! expression RPAREN! statement - - // do-while statement - | "do"^ statement "while"! LPAREN! expression RPAREN! SEMI! - - // get out of a loop (or switch) - | "break"^ (IDENT)? SEMI! - - // do next iteration of a loop - | "continue"^ (IDENT)? SEMI! - - // Return an expression - | "return"^ (expression)? SEMI! - - // switch/case statement - | "switch"^ LPAREN! expression RPAREN! LCURLY! { blockDepth++; } - ( casesGroup )* - RCURLY! { blockDepth--; } - - // exception try-catch block - | tryBlock - - // throw an exception - | "throw"^ expression SEMI! - - // synchronize a statement - | "synchronized"^ LPAREN! expression RPAREN! compoundStatement - - // asserts (uncomment if you want 1.4 compatibility) - // | "assert"^ expression ( COLON! expression )? SEMI! - - // empty statement - | s:SEMI {#s.setType(EMPTY_STAT);} - ; - -casesGroup - : ( // CONFLICT: to which case group do the statements bind? - // ANTLR generates proper code: it groups the - // many "case"/"default" labels together then - // follows them with the statements - options { - greedy = true; - } - : - aCase - )+ - caseSList - {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);} - ; - -aCase - : ("case"^ expression | "default") COLON! - ; - -caseSList - : (statement)* - {#caseSList = #(#[SLIST,"SLIST"],#caseSList);} - ; - -// The initializer for a for loop -forInit - // if it looks like a declaration, it is - : ( (declaration)=> declaration - // otherwise it could be an expression list... - | expressionList - )? - {#forInit = #(#[FOR_INIT,"FOR_INIT"],#forInit);} - ; - -forCond - : (expression)? - {#forCond = #(#[FOR_CONDITION,"FOR_CONDITION"],#forCond);} - ; - -forIter - : (expressionList)? - {#forIter = #(#[FOR_ITERATOR,"FOR_ITERATOR"],#forIter);} - ; - -// an exception handler try/catch block -tryBlock - : "try"^ compoundStatement - (handler)* - ( finallyClause )? - ; - -finallyClause - : "finally"^ compoundStatement - ; - -// an exception handler -handler - : "catch"^ LPAREN! parameterDeclaration RPAREN! compoundStatement - ; - - -// expressions -// Note that most of these expressions follow the pattern -// thisLevelExpression : -// nextHigherPrecedenceExpression -// (OPERATOR nextHigherPrecedenceExpression)* -// which is a standard recursive definition for a parsing an expression. -// The operators in java have the following precedences: -// lowest (13) = *= /= %= += -= <<= >>= >>>= &= ^= |= -// (12) ?: -// (11) || -// (10) && -// ( 9) | -// ( 8) ^ -// ( 7) & -// ( 6) == != -// ( 5) < <= > >= -// ( 4) << >> -// ( 3) +(binary) -(binary) -// ( 2) * / % -// ( 1) ++ -- +(unary) -(unary) ~ ! (type) -// [] () (method call) . (dot -- identifier qualification) -// new () (explicit parenthesis) -// -// the last two are not usually on a precedence chart; I put them in -// to point out that new has a higher precedence than '.', so you -// can validy use -// new Frame().show() -// -// Note that the above precedence levels map to the rules below... -// Once you have a precedence chart, writing the appropriate rules as below -// is usually very straightfoward - - - -// the mother of all expressions -expression - : assignmentExpression - {#expression = #(#[EXPR,"EXPR"],#expression);} - ; - - -// This is a list of expressions. -expressionList - : expression (COMMA! expression)* - {#expressionList = #(#[ELIST,"ELIST"], expressionList);} - ; - - -// assignment expression (level 13) -assignmentExpression - : conditionalExpression - ( ( ASSIGN^ - | PLUS_ASSIGN^ - | MINUS_ASSIGN^ - | STAR_ASSIGN^ - | DIV_ASSIGN^ - | MOD_ASSIGN^ - | SR_ASSIGN^ - | BSR_ASSIGN^ - | SL_ASSIGN^ - | BAND_ASSIGN^ - | BXOR_ASSIGN^ - | BOR_ASSIGN^ - ) - assignmentExpression - )? - ; - - -// conditional test (level 12) -conditionalExpression - : logicalOrExpression - ( QUESTION^ assignmentExpression COLON! conditionalExpression )? - ; - - -// logical or (||) (level 11) -logicalOrExpression - : logicalAndExpression (LOR^ logicalAndExpression)* - ; - - -// logical and (&&) (level 10) -logicalAndExpression - : inclusiveOrExpression (LAND^ inclusiveOrExpression)* - ; - - -// bitwise or non-short-circuiting or (|) (level 9) -inclusiveOrExpression - : exclusiveOrExpression (BOR^ exclusiveOrExpression)* - ; - - -// exclusive or (^) (level 8) -exclusiveOrExpression - : andExpression (BXOR^ andExpression)* - ; - - -// bitwise or non-short-circuiting and (&) (level 7) -andExpression - : equalityExpression (BAND^ equalityExpression)* - ; - - -// equality/inequality (==/!=) (level 6) -equalityExpression - : relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)* - ; - - -// boolean relational expressions (level 5) -relationalExpression - : shiftExpression - ( ( ( LT^ - | GT^ - | LE^ - | GE^ - ) - shiftExpression - )* - | "instanceof"^ typeSpec[true] - ) - ; - - -// bit shift expressions (level 4) -shiftExpression - : additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)* - ; - - -// binary addition/subtraction (level 3) -additiveExpression - : multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)* - ; - - -// multiplication/division/modulo (level 2) -multiplicativeExpression - : unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)* - ; - -unaryExpression - : INC^ unaryExpression - | DEC^ unaryExpression - | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression - | PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression - | unaryExpressionNotPlusMinus - ; - -unaryExpressionNotPlusMinus - : BNOT^ unaryExpression - | LNOT^ unaryExpression - - // use predicate to skip cases like: (int.class) - | (LPAREN builtInTypeSpec[true] RPAREN) => - lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN! - unaryExpression - - // Have to backtrack to see if operator follows. If no operator - // follows, it's a typecast. No semantic checking needed to parse. - // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)" - | (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=> - lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN! - unaryExpressionNotPlusMinus - - | postfixExpression - ; - -// qualified names, array expressions, method invocation, post inc/dec -postfixExpression - : - /* - "this"! lp1:LPAREN^ argList RPAREN! - {#lp1.setType(CTOR_CALL);} - - | "super"! lp2:LPAREN^ argList RPAREN! - {#lp2.setType(SUPER_CTOR_CALL);} - | - */ - primaryExpression - - ( - /* - options { - // the use of postfixExpression in SUPER_CTOR_CALL adds DOT - // to the lookahead set, and gives loads of false non-det - // warnings. - // shut them off. - generateAmbigWarnings=false; - } - : */ - DOT^ IDENT - ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} - argList - RPAREN! - )? - | DOT^ "this" - - | DOT^ "super" - ( // (new Outer()).super() (create enclosing instance) - lp3:LPAREN^ argList RPAREN! - {#lp3.setType(SUPER_CTOR_CALL);} - | DOT^ IDENT - ( lps:LPAREN^ {#lps.setType(METHOD_CALL);} - argList - RPAREN! - )? - ) - | DOT^ newExpression - | lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK! - )* - - ( // possibly add on a post-increment or post-decrement. - // allows INC/DEC on too much, but semantics can check - in:INC^ {#in.setType(POST_INC);} - | de:DEC^ {#de.setType(POST_DEC);} - )? - ; - -// the basic element of an expression -primaryExpression - : identPrimary ( options {greedy=true;} : DOT^ "class" )? - | constant - | "true" - | "false" - | "null" - | newExpression - | "this" - | "super" - | LPAREN! assignmentExpression RPAREN! - // look for int.class and int[].class - | builtInType - ( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )* - DOT^ "class" - ; - -/** Match a, a.b.c refs, a.b.c(...) refs, a.b.c[], a.b.c[].class, - * and a.b.c.class refs. Also this(...) and super(...). Match - * this or super. - */ -identPrimary - : IDENT - ( - options { - // .ident could match here or in postfixExpression. - // We do want to match here. Turn off warning. - greedy=true; - } - : DOT^ IDENT - )* - ( - options { - // ARRAY_DECLARATOR here conflicts with INDEX_OP in - // postfixExpression on LBRACK RBRACK. - // We want to match [] here, so greedy. This overcomes - // limitation of linear approximate lookahead. - greedy=true; - } - : ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} argList RPAREN! ) - | ( options {greedy=true;} : - lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! - )+ - )? - ; - -/** object instantiation. - * Trees are built as illustrated by the following input/tree pairs: - * - * new T() - * - * new - * | - * T -- ELIST - * | - * arg1 -- arg2 -- .. -- argn - * - * new int[] - * - * new - * | - * int -- ARRAY_DECLARATOR - * - * new int[] {1,2} - * - * new - * | - * int -- ARRAY_DECLARATOR -- ARRAY_INIT - * | - * EXPR -- EXPR - * | | - * 1 2 - * - * new int[3] - * new - * | - * int -- ARRAY_DECLARATOR - * | - * EXPR - * | - * 3 - * - * new int[1][2] - * - * new - * | - * int -- ARRAY_DECLARATOR - * | - * ARRAY_DECLARATOR -- EXPR - * | | - * EXPR 1 - * | - * 2 - * - */ -newExpression - : "new"^ type - ( LPAREN! argList RPAREN! (classBlock)? - - //java 1.1 - // Note: This will allow bad constructs like - // new int[4][][3] {exp,exp}. - // There needs to be a semantic check here... - // to make sure: - // a) [ expr ] and [ ] are not mixed - // b) [ expr ] and an init are not used together - - | newArrayDeclarator (arrayInitializer)? - ) - ; - -argList - : ( expressionList - | /*nothing*/ - {#argList = #[ELIST,"ELIST"];} - ) - ; - -newArrayDeclarator - : ( - // CONFLICT: - // newExpression is a primaryExpression which can be - // followed by an array index reference. This is ok, - // as the generated code will stay in this loop as - // long as it sees an LBRACK (proper behavior) - options { - warnWhenFollowAmbig = false; - } - : - lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} - (expression)? - RBRACK! - )+ - ; - -constant - : NUM_INT - | CHAR_LITERAL - | STRING_LITERAL - | NUM_FLOAT - | NUM_LONG - | NUM_DOUBLE - ; - -//---------------------------------------------------------------------------- -// The Java scanner -//---------------------------------------------------------------------------- -class JavaLexer extends Lexer; - -options { - exportVocab=Java; // call the vocabulary "Java" - testLiterals=false; // don't automatically test for literals - k=4; // four characters of lookahead - charVocabulary='\u0003'..'\u7FFE'; - // without inlining some bitset tests, couldn't do unicode; - // I need to make ANTLR generate smaller bitsets; see - // bottom of JavaLexer.java - codeGenBitsetTestThreshold=20; -} - -// OPERATORS -QUESTION : '?' ; -LPAREN : '(' ; -RPAREN : ')' ; -LBRACK : '[' ; -RBRACK : ']' ; -LCURLY : '{' ; -RCURLY : '}' ; -COLON : ':' ; -COMMA : ',' ; -//DOT : '.' ; -ASSIGN : '=' ; -EQUAL : "==" ; -LNOT : '!' ; -BNOT : '~' ; -NOT_EQUAL : "!=" ; -DIV : '/' ; -DIV_ASSIGN : "/=" ; -PLUS : '+' ; -PLUS_ASSIGN : "+=" ; -INC : "++" ; -MINUS : '-' ; -MINUS_ASSIGN : "-=" ; -DEC : "--" ; -STAR : '*' ; -STAR_ASSIGN : "*=" ; -MOD : '%' ; -MOD_ASSIGN : "%=" ; -SR : ">>" ; -SR_ASSIGN : ">>=" ; -BSR : ">>>" ; -BSR_ASSIGN : ">>>=" ; -GE : ">=" ; -GT : ">" ; -SL : "<<" ; -SL_ASSIGN : "<<=" ; -LE : "<=" ; -LT : '<' ; -BXOR : '^' ; -BXOR_ASSIGN : "^=" ; -BOR : '|' ; -BOR_ASSIGN : "|=" ; -LOR : "||" ; -BAND : '&' ; -BAND_ASSIGN : "&=" ; -LAND : "&&" ; -SEMI : ';' ; - - -// Whitespace -- ignored -WS : ( ' ' - | '\t' - | '\f' - // handle newlines - | ( options {generateAmbigWarnings=false;} - : "\r\n" // Evil DOS - | '\r' // Macintosh - | '\n' // Unix (the right way) - ) - { newline(); } - )+ - { _ttype = Token.SKIP; } - ; - -// Single-line comments -SL_COMMENT - : "//" - (~('\n'|'\r'))* ('\n'|'\r'('\n')?)? - {$setType(Token.SKIP); newline();} - ; - -// multiple-line comments -ML_COMMENT - : "/*" - ( /* '\r' '\n' can be matched in one alternative or by matching - '\r' in one iteration and '\n' in another. I am trying to - handle any flavor of newline that comes in, but the language - that allows both "\r\n" and "\r" and "\n" to all be valid - newline is ambiguous. Consequently, the resulting grammar - must be ambiguous. I'm shutting this warning off. - */ - options { - generateAmbigWarnings=false; - } - : - { LA(2)!='/' }? '*' - | '\r' '\n' {newline();} - | '\r' {newline();} - | '\n' {newline();} - | ~('*'|'\n'|'\r') - )* - "*/" - {$setType(Token.SKIP);} - ; - - -// character literals -CHAR_LITERAL - : '\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\'' - ; - -// string literals -STRING_LITERAL - : '"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"' - ; - - -// escape sequence -- note that this is protected; it can only be called -// from another lexer rule -- it will not ever directly return a token to -// the parser -// There are various ambiguities hushed in this rule. The optional -// '0'...'9' digit matches should be matched here rather than letting -// them go back to STRING_LITERAL to be matched. ANTLR does the -// right thing by matching immediately; hence, it's ok to shut off -// the FOLLOW ambig warnings. -protected -ESC - : '\\' - ( 'n' - | 'r' - | 't' - | 'b' - | 'f' - | '"' - | '\'' - | '\\' - | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT - | '0'..'3' - ( - options { - warnWhenFollowAmbig = false; - } - : '0'..'7' - ( - options { - warnWhenFollowAmbig = false; - } - : '0'..'7' - )? - )? - | '4'..'7' - ( - options { - warnWhenFollowAmbig = false; - } - : '0'..'7' - )? - ) - ; - - -// hexadecimal digit (again, note it's protected!) -protected -HEX_DIGIT - : ('0'..'9'|'A'..'F'|'a'..'f') - ; - - -// an identifier. Note that testLiterals is set to true! This means -// that after we match the rule, we look in the literals table to see -// if it's a literal or really an identifer -IDENT - options {testLiterals=true;} - : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* - ; - - -// a numeric literal -NUM_INT - {boolean isDecimal=false; Token t=null;} - : '.' {_ttype = DOT;} - ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})? - { - if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { - _ttype = NUM_FLOAT; - } - else { - _ttype = NUM_DOUBLE; // assume double - } - } - )? - - | ( '0' {isDecimal = true;} // special case for just '0' - ( ('x'|'X') - ( // hex - // the 'e'|'E' and float suffix stuff look - // like hex digits, hence the (...)+ doesn't - // know when to stop: ambig. ANTLR resolves - // it correctly by matching immediately. It - // is therefor ok to hush warning. - options { - warnWhenFollowAmbig=false; - } - : HEX_DIGIT - )+ - - | //float or double with leading zero - (('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+ - - | ('0'..'7')+ // octal - )? - | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal - ) - ( ('l'|'L') { _ttype = NUM_LONG; } - - // only check to see if it's a float if looks like decimal so far - | {isDecimal}? - ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})? - | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})? - | f4:FLOAT_SUFFIX {t=f4;} - ) - { - if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { - _ttype = NUM_FLOAT; - } - else { - _ttype = NUM_DOUBLE; // assume double - } - } - )? - ; - - -// a couple protected methods to assist in matching floating point numbers -protected -EXPONENT - : ('e'|'E') ('+'|'-')? ('0'..'9')+ - ; - - -protected -FLOAT_SUFFIX - : 'f'|'F'|'d'|'D' - ; - diff --git a/src/main/antlr/com/jogamp/gluegen/cgram/GnuCEmitter.g b/src/main/antlr/com/jogamp/gluegen/cgram/GnuCEmitter.g new file mode 100644 index 0000000..38ded36 --- /dev/null +++ b/src/main/antlr/com/jogamp/gluegen/cgram/GnuCEmitter.g @@ -0,0 +1,1145 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Copyright (c) Non, Inc. 1998 -- All Rights Reserved + +PROJECT: C Compiler +MODULE: GnuCEmitter +FILE: GnuCEmitter.g + +AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 + +DESCRIPTION: + + This tree grammar is for a Gnu C AST. + It turns the tree back into source code. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + + +header { + package com.jogamp.gluegen.cgram; + + import java.io.*; + import java.util.*; + + import antlr.CommonAST; + import antlr.DumpASTVisitor; +} + + +class GnuCEmitter extends GnuCTreeParser; + +options + { + importVocab = GNUC; + buildAST = false; + ASTLabelType = "TNode"; + + // Copied following options from java grammar. + codeGenMakeSwitchThreshold = 2; + codeGenBitsetTestThreshold = 3; + } + + +{ + + +int tabs = 0; +PrintStream currentOutput = System.out; +int lineNum = 1; +String currentSource = ""; +LineObject trueSourceFile; +final int lineDirectiveThreshold = Integer.MAX_VALUE; +PreprocessorInfoChannel preprocessorInfoChannel = null; +Stack sourceFiles = new Stack(); + +public GnuCEmitter( PreprocessorInfoChannel preprocChannel ) +{ + preprocessorInfoChannel = preprocChannel; +} + +void initializePrinting() +{ + Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber( new Integer(1) ); + printPreprocs(preprocs); +/* if ( currentSource.equals("") ) { + trueSourceFile = new LineObject(currentSource); + currentOutput.println("# 1 \"" + currentSource + "\"\n"); + sourceFiles.push(trueSourceFile); + } +*/ +} + +void finalizePrinting() { + // flush any leftover preprocessing instructions to the stream + + printPreprocs( + preprocessorInfoChannel.extractLinesPrecedingTokenNumber( + new Integer( preprocessorInfoChannel.getMaxTokenNumber() + 1 ) )); + //print a newline so file ends at a new line + currentOutput.println(); +} + +void printPreprocs( Vector preprocs ) +{ + // if there was a preprocessingDirective previous to this token then + // print a newline and the directive, line numbers handled later + if ( preprocs.size() > 0 ) { + if ( trueSourceFile != null ) { + currentOutput.println(); //make sure we're starting a new line unless this is the first line directive + } + lineNum++; + Enumeration e = preprocs.elements(); + while (e.hasMoreElements()) + { + Object o = e.nextElement(); + if ( o.getClass().getName().equals("LineObject") ) { + LineObject l = (LineObject) o; + + // we always return to the trueSourceFile, we never enter it from another file + // force it to be returning if in fact we aren't currently in trueSourceFile + if (( trueSourceFile != null ) //trueSource exists + && ( !currentSource.equals(trueSourceFile.getSource()) ) //currently not in trueSource + && ( trueSourceFile.getSource().equals(l.getSource()) ) ) { //returning to trueSource + l.setEnteringFile( false ); + l.setReturningToFile( true ); + } + + + // print the line directive + currentOutput.println(l); + lineNum = l.getLine(); + currentSource = l.getSource(); + + + // the very first line directive always represents the true sourcefile + if ( trueSourceFile == null ) { + trueSourceFile = new LineObject(currentSource); + sourceFiles.push(trueSourceFile); + } + + // keep our own stack of files entered + if ( l.getEnteringFile() ) { + sourceFiles.push(l); + } + + // if returning to a file, pop the exited files off the stack + if ( l.getReturningToFile() ) { + LineObject top = (LineObject) sourceFiles.peek(); + while (( top != trueSourceFile ) && (! l.getSource().equals(top.getSource()) )) { + sourceFiles.pop(); + top = (LineObject) sourceFiles.peek(); + } + } + } + else { // it was a #pragma or such + currentOutput.println(o); + lineNum++; + } + } + } + +} + +void print( TNode t ) { + int tLineNum = t.getLocalLineNum(); + if ( tLineNum == 0 ) tLineNum = lineNum; + + Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber((Integer)t.getAttribute("tokenNumber")); + printPreprocs(preprocs); + + if ( (lineNum != tLineNum) ) { + // we know we'll be newlines or a line directive or it probably + // is just the case that this token is on the next line + // either way start a new line and indent it + currentOutput.println(); + lineNum++; + printTabs(); + } + + if ( lineNum == tLineNum ){ + // do nothing special, we're at the right place + } + else { + int diff = tLineNum - lineNum; + if ( lineNum < tLineNum ) { + // print out the blank lines to bring us up to right line number + for ( ; lineNum < tLineNum ; lineNum++ ) { + currentOutput.println(); + } + printTabs(); + } + else { // just reset lineNum + lineNum = tLineNum; + } + } + currentOutput.print( t.getText() + " " ); +} + + +/* This was my attempt at being smart about line numbers + It didn't work quite right but I don't know why, I didn't + have enough test cases. Worked ok compiling rcs and ghostscript +*/ +void printAddingLineDirectives( TNode t ) { + int tLineNum = t.getLocalLineNum(); + String tSource = (String) t.getAttribute("source"); + + if ( tSource == null ) tSource = currentSource; + if ( tLineNum == 0 ) tLineNum = lineNum; + + Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber((Integer)t.getAttribute("tokenNumber")); + printPreprocs(preprocs); + + if ( (lineNum != tLineNum) || !currentSource.equals(tSource) ) { + // we know we'll be newlines or a line directive or it probably + // is just the case that this token is on the next line + // either way start a new line and indent it + currentOutput.println(); + lineNum++; + printTabs(); + } + + if ( ( lineNum == tLineNum ) && ( currentSource.equals(tSource) ) ){ + // do nothing special, we're at the right place + } + else if ( currentSource.equals(tSource) ) { + int diff = tLineNum - lineNum; + if (diff > 0 && diff < lineDirectiveThreshold) { + // print out the blank lines to bring us up to right line number + for ( ; lineNum < tLineNum ; lineNum++ ) { + currentOutput.println(); + } + } + else { // print line directive to get us to right line number + // preserve flags 3 and 4 if present in current file + if ( ! sourceFiles.empty() ) { + LineObject l = (LineObject) sourceFiles.peek(); + StringBuilder tFlags = new StringBuilder(""); + if (l.getSystemHeader()) { + tFlags.append(" 3"); + } + if (l.getTreatAsC()) { + tFlags.append(" 4"); + } + currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + tFlags.toString()); + lineNum = tLineNum; + } + } + + printTabs(); + } + else { // different source + Enumeration sources = sourceFiles.elements(); + // see if we're returning to a file we entered earlier + boolean returningToEarlierFile = false; + while (sources.hasMoreElements()) { + LineObject l = (LineObject) sources.nextElement(); + if (l.getSource().equals(tSource)) { + returningToEarlierFile = true; + break; + } + } + if (returningToEarlierFile) { + // pop off the files we're exiting, but never pop the trueSourceFile + LineObject l = (LineObject) sourceFiles.peek(); + while ( ( l != trueSourceFile ) &&(! l.getSource().equals(tSource) ) ) { + sourceFiles.pop(); + l = (LineObject) sourceFiles.peek(); + } + + // put in the return flag, plus others as needed + StringBuilder tFlags = new StringBuilder(" 2"); + if (l.getSystemHeader()) { + tFlags.append(" 3"); + } + if (l.getTreatAsC()) { + tFlags.append(" 4"); + } + + currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + tFlags); + lineNum = tLineNum; + currentSource = tSource; + printTabs(); + } + else { // entering a file that wasn't in the original source + // pretend we're entering it from top of stack + currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + " 1"); + lineNum = tLineNum; + currentSource = tSource; + printTabs(); + } + } + currentOutput.print( t.getText() + " " ); +} + +/** It is not ok to print newlines from the String passed in as +it will screw up the line number handling **/ +void print( String s ) { + currentOutput.print( s + " " ); +} + +void printTabs() { + for ( int i = 0; i< tabs; i++ ) { + currentOutput.print( "\t" ); + } +} + +void commaSep( TNode t ) { + print( t ); + if ( t.getNextSibling() != null ) { + print( "," ); + } +} + + int traceDepth = 0; + public void reportError(RecognitionException ex) { + if ( ex != null) { + System.err.println("ANTLR Tree Parsing RecognitionException Error: " + ex.getClass().getName() + " " + ex ); + ex.printStackTrace(System.err); + } + } + public void reportError(NoViableAltException ex) { + System.err.println("ANTLR Tree Parsing NoViableAltException Error: " + ex.toString()); + TNode.printTree( ex.node ); + ex.printStackTrace(System.err); + } + public void reportError(MismatchedTokenException ex) { + if ( ex != null) { + TNode.printTree( ex.node ); + System.err.println("ANTLR Tree Parsing MismatchedTokenException Error: " + ex ); + ex.printStackTrace(System.err); + } + } + public void reportError(String s) { + System.err.println("ANTLR Error from String: " + s); + } + public void reportWarning(String s) { + System.err.println("ANTLR Warning from String: " + s); + } + protected void match(AST t, int ttype) throws MismatchedTokenException { + //System.out.println("match("+ttype+"); cursor is "+t); + super.match(t, ttype); + } + public void match(AST t, BitSet b) throws MismatchedTokenException { + //System.out.println("match("+b+"); cursor is "+t); + super.match(t, b); + } + protected void matchNot(AST t, int ttype) throws MismatchedTokenException { + //System.out.println("matchNot("+ttype+"); cursor is "+t); + super.matchNot(t, ttype); + } + public void traceIn(String rname, AST t) { + traceDepth += 1; + for (int x=0; x typeName + | expr + ) + rp:RPAREN { print( rp ); } + ) + | p:"__complex" { print( p ); } + ; + + +typedefName + : #(NTypedefName i:ID { print( i ); } ) + ; + + +structSpecifier + : #( a:"struct" { print( a ); } + structOrUnionBody + ) + ; + +unionSpecifier + : #( a:"union" { print( a ); } + structOrUnionBody + ) + ; + +structOrUnionBody + : ( (ID LCURLY) => i1:ID lc1:LCURLY { print( i1 ); print ( "{" ); tabs++; } + ( structDeclarationList )? + rc1:RCURLY { tabs--; print( rc1 ); } + | lc2:LCURLY { print( lc2 ); tabs++; } + ( structDeclarationList )? + rc2:RCURLY { tabs--; print( rc2 ); } + | i2:ID { print( i2 ); } + ) + ; + +structDeclarationList + : ( structDeclaration { print( ";" ); } + )+ + ; + + +structDeclaration + : specifierQualifierList structDeclaratorList + ; + + +specifierQualifierList + : ( + typeSpecifier + | typeQualifier + )+ + ; + + +structDeclaratorList + : structDeclarator + ( { print(","); } structDeclarator )* + ; + + +structDeclarator + : + #( NStructDeclarator + ( declarator )? + ( c:COLON { print( c ); } expr )? + ( attributeDecl )* + ) + ; + + +enumSpecifier + : #( a:"enum" { print( a ); } + ( i:ID { print( i ); } )? + ( lc:LCURLY { print( lc ); tabs++; } + enumList + rc:RCURLY { tabs--; print( rc ); } + )? + ) + ; + + +enumList + : + enumerator ( {print(",");} enumerator)* + ; + + +enumerator + : i:ID { print( i ); } + ( b:ASSIGN { print( b ); } + expr + )? + ; + + +attributeDecl: + #( a:"__attribute" { print( a ); } + (b:. { print( b ); } )* + ) + | #( n:NAsmAttribute { print( n ); } + lp:LPAREN { print( lp ); } + expr { print( ")" ); } + rp:RPAREN { print( rp ); } + ) + ; + +initDeclList + : initDecl + ( { print( "," ); } initDecl )* + ; + + +initDecl + { String declName = ""; } + : #(NInitDecl + declarator + ( attributeDecl )* + ( a:ASSIGN { print( a ); } + initializer + | b:COLON { print( b ); } + expr + )? + ) + ; + + +pointerGroup + : #( NPointerGroup + ( a:STAR { print( a ); } + ( typeQualifier )* + )+ + ) + ; + + + +idList + : i:ID { print( i ); } + ( c:COMMA { print( c ); } + id:ID { print( id ); } + )* + ; + + + +initializer + : #( NInitializer (initializerElementLabel)? expr ) + | lcurlyInitializer + ; + +initializerElementLabel + : #( NInitializerElementLabel + ( + ( l:LBRACKET { print( l ); } + expr + r:RBRACKET { print( r ); } + (a1:ASSIGN { print( a1 ); } )? + ) + | i1:ID c:COLON { print( i1 ); print( c ); } + | d:DOT i2:ID a2:ASSIGN { print( d ); print( i2 ); print( a2 ); } + ) + ) + ; + +lcurlyInitializer + : #(n:NLcurlyInitializer { print( n ); tabs++; } + initializerList + rc:RCURLY { tabs--; print( rc ); } + ) + ; + +initializerList + : ( i:initializer { commaSep( i ); } + )* + ; + + +declarator + : #( NDeclarator + ( pointerGroup )? + + ( id:ID { print( id ); } + | lp:LPAREN { print( lp ); } declarator rp:RPAREN { print( rp ); } + ) + + ( #( n:NParameterTypeList { print( n ); } + ( + parameterTypeList + | (idList)? + ) + r:RPAREN { print( r ); } + ) + | lb:LBRACKET { print( lb );} ( expr )? rb:RBRACKET { print( rb ); } + )* + ) + ; + + + +parameterTypeList + : ( parameterDeclaration + ( c:COMMA { print( c ); } + | s:SEMI { print( s ); } + )? + )+ + ( v:VARARGS { print( v ); } )? + ; + + + +parameterDeclaration + : #( NParameterDeclaration + declSpecifiers + (declarator | nonemptyAbstractDeclarator)? + ) + ; + + +functionDef + : #( NFunctionDef + ( functionDeclSpecifiers)? + declarator + (declaration + | v:VARARGS { print( v ); } + )* + compoundStatement + ) + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + +functionDeclSpecifiers + : + ( functionStorageClassSpecifier + | typeQualifier + | typeSpecifier + )+ + ; + +declarationList + : + ( //ANTLR doesn't know that declarationList properly eats all the declarations + //so it warns about the ambiguity + options { + warnWhenFollowAmbig = false; + } : + localLabelDecl + | declaration + )+ + ; + +localLabelDecl + : #(a:"__label__" { print( a ); } + ( i:ID { commaSep( i ); } + )+ + { print( ";" ); } + ) + ; + + + +compoundStatement + : #( cs:NCompoundStatement { print( cs ); tabs++; } + ( declarationList + | functionDef + )* + ( statementList )? + rc:RCURLY { tabs--; print( rc ); } + ) + + ; + +statementList + : ( statement )+ + ; + +statement + : statementBody + ; + +statementBody + : s:SEMI { print( s ); } + + | compoundStatement // Group of statements + + | #(NStatementExpr + expr { print( ";" ); } + ) // Expressions + +// Iteration statements: + + | #( w:"while" { print( w ); print( "(" ); } + expr { print( ")" ); } + statement ) + + | #( d:"do" { print( d ); } + statement + { print( " while ( " ); } + expr + { print( " );" ); } + ) + + | #( f:"for" { print( f ); print( "(" ); } + expr { print( ";" ); } + expr { print( ";" ); } + expr { print( ")" ); } + statement + ) + + +// Jump statements: + + | #( g:"goto" { print( g );} + expr { print( ";" ); } + ) + | c:"continue" { print( c ); print( ";" );} + | b:"break" { print( b ); print( ";" );} + | #( r:"return" { print( r ); } + ( expr )? + { print( ";" ); } + ) + + +// Labeled statements: + | #( NLabel + ni:ID { print( ni ); print( ":" ); } + ( statement )? + ) + + | #( + ca:"case" { print( ca ); } + expr { print( ":" ); } + (statement)? + ) + + | #( + de:"default" { print( de ); print( ":" ); } + (statement)? + ) + + + +// Selection statements: + + | #( i:"if" { print( i ); print( "(" ); } + expr { print( ")" ); } + statement + ( e:"else" { print( e ); } + statement + )? + ) + | #( sw:"switch" { print( sw ); print( "(" ); } + expr { print( ")" ); } + statement + ) + + + + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + + + + + +expr + : + binaryExpr + | conditionalExpr + | castExpr + | unaryExpr + | postfixExpr + | primaryExpr + | emptyExpr + | compoundStatementExpr + | initializer + | rangeExpr + | gnuAsmExpr + ; + +emptyExpr + : NEmptyExpression + ; + +compoundStatementExpr + : #(l:LPAREN { print( l ); } + compoundStatement + r:RPAREN { print( r ); } + ) + ; + +rangeExpr + : #(NRangeExpr expr v:VARARGS{ print( v ); } expr) + ; + +gnuAsmExpr + : #(n:NGnuAsmExpr { print( n ); } + (v:"volatile" { print( v ); } )? + lp:LPAREN { print( lp ); } + stringConst + ( options { warnWhenFollowAmbig = false; }: + c1:COLON { print( c1 );} + (strOptExprPair + ( c2:COMMA { print( c2 ); } strOptExprPair)* + )? + ( options { warnWhenFollowAmbig = false; }: + c3:COLON { print( c3 ); } + (strOptExprPair + ( c4:COMMA { print( c4 ); } strOptExprPair)* + )? + )? + )? + ( c5:COLON { print( c5 ); } + stringConst + ( c6:COMMA { print( c6 ); } + stringConst + )* + )? + rp:RPAREN { print( rp ); } + ) + ; + +strOptExprPair + : stringConst + ( + l:LPAREN { print( l ); } + expr + r:RPAREN { print( r ); } + )? + ; + +binaryOperator + : ASSIGN + | DIV_ASSIGN + | PLUS_ASSIGN + | MINUS_ASSIGN + | STAR_ASSIGN + | MOD_ASSIGN + | RSHIFT_ASSIGN + | LSHIFT_ASSIGN + | BAND_ASSIGN + | BOR_ASSIGN + | BXOR_ASSIGN + | LOR + | LAND + | BOR + | BXOR + | BAND + | EQUAL + | NOT_EQUAL + | LT + | LTE + | GT + | GTE + | LSHIFT + | RSHIFT + | PLUS + | MINUS + | STAR + | DIV + | MOD + | NCommaExpr + ; + +binaryExpr + : b:binaryOperator + // no rules allowed as roots, so here I manually get + // the first and second children of the binary operator + // and then print them out in the right order + { TNode e1, e2; + e1 = (TNode) b.getFirstChild(); + e2 = (TNode) e1.getNextSibling(); + expr( e1 ); + print( b ); + expr( e2 ); + } + + ; + + +conditionalExpr + : #( q:QUESTION + expr { print( q ); } + ( expr )? + c:COLON { print( c ); } + expr + ) + ; + + +castExpr + : #( + c:NCast { print( c ); } + typeName + rp:RPAREN { print( rp ); } + expr + ) + ; + + +typeName + : specifierQualifierList (nonemptyAbstractDeclarator)? + ; + +nonemptyAbstractDeclarator + : #( NNonemptyAbstractDeclarator + ( pointerGroup + ( (lp1:LPAREN { print( lp1 ); } + ( nonemptyAbstractDeclarator + | parameterTypeList + )? + rp1:RPAREN { print( rp1 ); } + ) + | ( + lb1:LBRACKET { print( lb1 ); } + (expr)? + rb1:RBRACKET { print( rb1 ); } + ) + )* + + | ( (lp2:LPAREN { print( lp2 ); } + ( nonemptyAbstractDeclarator + | parameterTypeList + )? + rp2:RPAREN { print( rp2 ); } + ) + | ( + lb2:LBRACKET { print( lb2 ); } + (expr)? + rb2:RBRACKET { print( rb2 ); } + ) + )+ + ) + ) + ; + + + +unaryExpr + : #( i:INC { print( i ); } expr ) + | #( d:DEC { print( d ); } expr ) + | #( NUnaryExpr u:unaryOperator { print( u ); } expr) + | #( s:"sizeof" { print( s ); } + ( ( LPAREN typeName )=> + lps:LPAREN { print( lps ); } + typeName + rps:RPAREN { print( rps ); } + | expr + ) + ) + | #( a:"__alignof" { print( a ); } + ( ( LPAREN typeName )=> + lpa:LPAREN { print( lpa ); } + typeName + rpa:RPAREN { print( rpa ); } + | expr + ) + ) + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + unaryOperator + : BAND + | STAR + | PLUS + | MINUS + | BNOT + | LNOT + | LAND + | "__real" + | "__imag" + ; + + +postfixExpr + : #( NPostfixExpr + primaryExpr + ( a:PTR b:ID { print( a ); print( b ); } + | c:DOT d:ID { print( c ); print( d ); } + | #( n:NFunctionCallArgs { print( n ); } + (argExprList)? + rp:RPAREN { print( rp ); } + ) + | lb:LBRACKET { print( lb ); } + expr + rb:RBRACKET { print( rb ); } + | f:INC { print( f ); } + | g:DEC { print( g ); } + )+ + ) + ; + + + +primaryExpr + : i:ID { print( i ); } + | n:Number { print( n ); } + | charConst + | stringConst + +// JTC: +// ID should catch the enumerator +// leaving it in gives ambiguous err +// | enumerator + + | #( eg:NExpressionGroup { print( eg ); } + expr { print( ")" ); } + ) + ; + + + +argExprList + : expr ( {print( "," );} expr )* + ; + + + +protected +charConst + : c:CharLiteral { print( c ); } + ; + + +protected +stringConst + : #( NStringSeq + ( + s:StringLiteral { print( s ); } + )+ + ) + ; + + +protected +intConst + : IntOctalConst + | LongOctalConst + | UnsignedOctalConst + | IntIntConst + | LongIntConst + | UnsignedIntConst + | IntHexConst + | LongHexConst + | UnsignedHexConst + ; + + +protected +floatConst + : FloatDoubleConst + | DoubleDoubleConst + | LongDoubleConst + ; + + + + + + + + + + diff --git a/src/main/antlr/com/jogamp/gluegen/cgram/GnuCParser.g b/src/main/antlr/com/jogamp/gluegen/cgram/GnuCParser.g new file mode 100644 index 0000000..e8ca8c5 --- /dev/null +++ b/src/main/antlr/com/jogamp/gluegen/cgram/GnuCParser.g @@ -0,0 +1,878 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Copyright (c) Non, Inc. 1998 -- All Rights Reserved + +PROJECT: C Compiler +MODULE: GnuCParser +FILE: GnuCParser.g + +AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 + +DESCRIPTION: + This is a grammar for the GNU C compiler. It is a + grammar subclass of StdCParser, overriding only those + rules which are different from Standard C. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + + +header { + package com.jogamp.gluegen.cgram; + + import java.io.*; + + import antlr.CommonAST; + import antlr.DumpASTVisitor; +} + + +class GnuCParser extends StdCParser; + +options + { + k = 2; + exportVocab = GNUC; + buildAST = true; + ASTLabelType = "TNode"; + + // Copied following options from java grammar. + codeGenMakeSwitchThreshold = 2; + codeGenBitsetTestThreshold = 3; + } + + +{ + // 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; x0)?" [inputState.guessing "+ inputState.guessing + "]":"")); + + } + + } + try { + if ( LA(1)!=t ) { + if ( debugging ){ + for (int x=0; x "+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 declaration + | ( functionPrefix )=> functionDef + | typelessDeclaration + | asm_expr + | SEMI + ; + +/* these two are here because GCC allows "cat = 13;" as a valid program! */ +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 + ) + ; + +// GCC allows more specific initializers +initializerElementLabel + : ( ( LBRACKET ((constExpr VARARGS)=> rangeExpr | constExpr) RBRACKET (ASSIGN)? ) + | ID COLON + | DOT ID ASSIGN + ) + { ## = #( #[NInitializerElementLabel], ##) ; } + ; + +// GCC allows empty initializer lists +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" + | "int8_t" + | "uint8_t" + | "int16_t" + | "uint16_t" + | "__int32" + | "int32_t" + | "wchar_t" + | "uint32_t" + | "__int64" + | "int64_t" + | "uint64_t" + | "ptrdiff_t" + | "intptr_t" + | "size_t" + | "uintptr_t" + | 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 = (TNode) #[ NEmptyExpression ]; } + if ( #e2 == null) { #e2 = (TNode) #[ NEmptyExpression ]; } + if ( #e3 == null) { #e3 = (TNode) #[ 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 java.io.*; + import java.util.*; + import antlr.*; +} + +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; + List defines = new ArrayList(); + + 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) ); + } + + public void addDefine(String name, String value) + { + defines.add(new Define(name, value)); + } + + /** Returns a list of Define objects corresponding to the + preprocessor definitions seen during parsing. */ + public List getDefines() { + return defines; + } + + 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() { + 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' | '\\' ) + )* + '"' + ; + + + + diff --git a/src/main/antlr/com/jogamp/gluegen/cgram/GnuCTreeParser.g b/src/main/antlr/com/jogamp/gluegen/cgram/GnuCTreeParser.g new file mode 100644 index 0000000..dbe2f98 --- /dev/null +++ b/src/main/antlr/com/jogamp/gluegen/cgram/GnuCTreeParser.g @@ -0,0 +1,867 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Copyright (c) Non, Inc. 1998 -- All Rights Reserved + +PROJECT: C Compiler +MODULE: GnuCTreeParser +FILE: GnuCTreeParser.g + +AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 + +DESCRIPTION: + + This tree grammar is for a Gnu C AST. No actions in it, + subclass to do something useful. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + + +header { + package com.jogamp.gluegen.cgram; + + import java.io.*; + + import antlr.CommonAST; + import antlr.DumpASTVisitor; +} + + +class GnuCTreeParser extends TreeParser; + +options + { + importVocab = GNUC; + buildAST = false; + ASTLabelType = "TNode"; + + // Copied following options from java grammar. + codeGenMakeSwitchThreshold = 2; + codeGenBitsetTestThreshold = 3; + } + + +{ + int traceDepth = 0; + public void reportError(RecognitionException ex) { + if ( ex != null) { + System.err.println("ANTLR Tree Parsing RecognitionException Error: " + ex.getClass().getName() + " " + ex ); + ex.printStackTrace(System.err); + } + } + public void reportError(NoViableAltException ex) { + System.err.println("ANTLR Tree Parsing NoViableAltException Error: " + ex.toString()); + TNode.printTree( ex.node ); + ex.printStackTrace(System.err); + } + public void reportError(MismatchedTokenException ex) { + if ( ex != null) { + TNode.printTree( ex.node ); + System.err.println("ANTLR Tree Parsing MismatchedTokenException Error: " + ex ); + ex.printStackTrace(System.err); + } + } + public void reportError(String s) { + System.err.println("ANTLR Error from String: " + s); + } + public void reportWarning(String s) { + System.err.println("ANTLR Warning from String: " + s); + } + protected void match(AST t, int ttype) throws MismatchedTokenException { + //System.out.println("match("+ttype+"); cursor is "+t); + super.match(t, ttype); + } + public void match(AST t, BitSet b) throws MismatchedTokenException { + //System.out.println("match("+b+"); cursor is "+t); + super.match(t, b); + } + protected void matchNot(AST t, int ttype) throws MismatchedTokenException { + //System.out.println("matchNot("+ttype+"); cursor is "+t); + super.matchNot(t, ttype); + } + public void traceIn(String rname, AST t) { + traceDepth += 1; + for (int x=0; x typeName + | expr + ) + RPAREN + ) + | "__complex" + ; + + +typedefName + : #(NTypedefName ID) + ; + + +structSpecifier + : #( "struct" structOrUnionBody ) + ; + +unionSpecifier + : #( "union" structOrUnionBody ) + ; + +structOrUnionBody + : ( (ID LCURLY) => ID LCURLY + ( structDeclarationList )? + RCURLY + | LCURLY + ( structDeclarationList )? + RCURLY + | ID + ) + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + +structDeclarationList + : ( structDeclaration )+ + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + + +structDeclaration + : specifierQualifierList structDeclaratorList + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + + +specifierQualifierList + : ( + typeSpecifier + | typeQualifier + )+ + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + + +structDeclaratorList + : ( structDeclarator )+ + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + + +structDeclarator + : + #( NStructDeclarator + ( declarator )? + ( COLON expr )? + ( attributeDecl )* + ) + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + + + +enumSpecifier + : #( "enum" + ( ID )? + ( LCURLY enumList RCURLY )? + ) + ; + + +enumList + : ( enumerator )+ + ; + + +enumerator + : ID ( ASSIGN expr )? + ; + + + +attributeDecl: + #( "__attribute" (.)* ) + | #( NAsmAttribute LPAREN expr RPAREN ) + ; + +initDeclList + : ( initDecl )+ + ; + + +initDecl + { String declName = ""; } + : #( NInitDecl + declarator + ( attributeDecl )* + ( ASSIGN initializer + | COLON expr + )? + ) + ; + + +pointerGroup + : #( NPointerGroup ( STAR ( typeQualifier )* )+ ) + ; + + + +idList + : ID ( COMMA ID )* + ; + + + +initializer + : #( NInitializer (initializerElementLabel)? expr ) + | lcurlyInitializer + ; + +initializerElementLabel + : #( NInitializerElementLabel + ( + ( LBRACKET expr RBRACKET (ASSIGN)? ) + | ID COLON + | DOT ID ASSIGN + ) + ) + ; + +lcurlyInitializer + : #( NLcurlyInitializer + initializerList + RCURLY + ) + ; + +initializerList + : ( initializer )* + ; + + +declarator + : #( NDeclarator + ( pointerGroup )? + + ( id:ID + | LPAREN declarator RPAREN + ) + + ( #( NParameterTypeList + ( + parameterTypeList + | (idList)? + ) + RPAREN + ) + | LBRACKET ( expr )? RBRACKET + )* + ) + ; + + + +parameterTypeList + : ( parameterDeclaration ( COMMA | SEMI )? )+ ( VARARGS )? + ; + + + +parameterDeclaration + : #( NParameterDeclaration + declSpecifiers + (declarator | nonemptyAbstractDeclarator)? + ) + ; + + +functionDef + : #( NFunctionDef + ( functionDeclSpecifiers)? + declarator + (declaration | VARARGS)* + compoundStatement + ) + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + +functionDeclSpecifiers + : + ( functionStorageClassSpecifier + | typeQualifier + | typeSpecifier + )+ + ; + +declarationList + : + ( //ANTLR doesn't know that declarationList properly eats all the declarations + //so it warns about the ambiguity + options { + warnWhenFollowAmbig = false; + } : + localLabelDecl + | declaration + )+ + ; + +localLabelDecl + : #("__label__" (ID)+ ) + ; + + + +compoundStatement + : #( NCompoundStatement + ( declarationList + | functionDef + )* + ( statementList )? + RCURLY + ) + ; + +statementList + : ( statement )+ + ; + +statement + : statementBody + ; + +statementBody + : SEMI // Empty statements + + | compoundStatement // Group of statements + + | #(NStatementExpr expr) // Expressions + +// Iteration statements: + + | #( "while" expr statement ) + | #( "do" statement expr ) + | #( "for" + expr expr expr + statement + ) + + +// Jump statements: + + | #( "goto" expr ) + | "continue" + | "break" + | #( "return" ( expr )? ) + + +// Labeled statements: + | #( NLabel ID (statement)? ) + | #( "case" expr (statement)? ) + | #( "default" (statement)? ) + + + +// Selection statements: + + | #( "if" + expr statement + ( "else" statement )? + ) + | #( "switch" expr statement ) + + + + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + + + + + +expr + : assignExpr + | conditionalExpr + | logicalOrExpr + | logicalAndExpr + | inclusiveOrExpr + | exclusiveOrExpr + | bitAndExpr + | equalityExpr + | relationalExpr + | shiftExpr + | additiveExpr + | multExpr + | castExpr + | unaryExpr + | postfixExpr + | primaryExpr + | commaExpr + | emptyExpr + | compoundStatementExpr + | initializer + | rangeExpr + | gnuAsmExpr + ; + +commaExpr + : #(NCommaExpr expr expr) + ; + +emptyExpr + : NEmptyExpression + ; + +compoundStatementExpr + : #(LPAREN compoundStatement RPAREN) + ; + +rangeExpr + : #(NRangeExpr expr VARARGS expr) + ; + +gnuAsmExpr + : #(NGnuAsmExpr + ("volatile")? + LPAREN stringConst + ( options { warnWhenFollowAmbig = false; }: + COLON (strOptExprPair ( COMMA strOptExprPair)* )? + ( options { warnWhenFollowAmbig = false; }: + COLON (strOptExprPair ( COMMA strOptExprPair)* )? + )? + )? + ( COLON stringConst ( COMMA stringConst)* )? + RPAREN + ) + ; + +strOptExprPair + : stringConst ( LPAREN expr RPAREN )? + ; + +assignExpr + : #( ASSIGN expr expr) + | #( DIV_ASSIGN expr expr) + | #( PLUS_ASSIGN expr expr) + | #( MINUS_ASSIGN expr expr) + | #( STAR_ASSIGN expr expr) + | #( MOD_ASSIGN expr expr) + | #( RSHIFT_ASSIGN expr expr) + | #( LSHIFT_ASSIGN expr expr) + | #( BAND_ASSIGN expr expr) + | #( BOR_ASSIGN expr expr) + | #( BXOR_ASSIGN expr expr) + ; + + +conditionalExpr + : #( QUESTION expr (expr)? COLON expr ) + ; + + +logicalOrExpr + : #( LOR expr expr) + ; + + +logicalAndExpr + : #( LAND expr expr ) + ; + + +inclusiveOrExpr + : #( BOR expr expr ) + ; + + +exclusiveOrExpr + : #( BXOR expr expr ) + ; + + +bitAndExpr + : #( BAND expr expr ) + ; + + + +equalityExpr + : #( EQUAL expr expr) + | #( NOT_EQUAL expr expr) + ; + + +relationalExpr + : #( LT expr expr) + | #( LTE expr expr) + | #( GT expr expr) + | #( GTE expr expr) + ; + + + +shiftExpr + : #( LSHIFT expr expr) + | #( RSHIFT expr expr) + ; + + +additiveExpr + : #( PLUS expr expr) + | #( MINUS expr expr) + ; + + +multExpr + : #( STAR expr expr) + | #( DIV expr expr) + | #( MOD expr expr) + ; + + + +castExpr + : #( NCast typeName RPAREN expr) + ; + + +typeName + : specifierQualifierList (nonemptyAbstractDeclarator)? + ; + +nonemptyAbstractDeclarator + : #( NNonemptyAbstractDeclarator + ( pointerGroup + ( (LPAREN + ( nonemptyAbstractDeclarator + | parameterTypeList + )? + RPAREN) + | (LBRACKET (expr)? RBRACKET) + )* + + | ( (LPAREN + ( nonemptyAbstractDeclarator + | parameterTypeList + )? + RPAREN) + | (LBRACKET (expr)? RBRACKET) + )+ + ) + ) + ; + + + +unaryExpr + : #( INC expr ) + | #( DEC expr ) + | #( NUnaryExpr unaryOperator expr) + | #( "sizeof" + ( ( LPAREN typeName )=> LPAREN typeName RPAREN + | expr + ) + ) + | #( "__alignof" + ( ( LPAREN typeName )=> LPAREN typeName RPAREN + | expr + ) + ) + ; +/* +exception +catch [RecognitionException ex] + { + reportError(ex); + System.out.println("PROBLEM TREE:\n" + + _t.toStringList()); + if (_t!=null) {_t = _t.getNextSibling();} + } +*/ + + unaryOperator + : BAND + | STAR + | PLUS + | MINUS + | BNOT + | LNOT + | LAND + | "__real" + | "__imag" + ; + + +postfixExpr + : #( NPostfixExpr + primaryExpr + ( PTR ID + | DOT ID + | #( NFunctionCallArgs (argExprList)? RPAREN ) + | LBRACKET expr RBRACKET + | INC + | DEC + )+ + ) + ; + + + +primaryExpr + : ID + | Number + | charConst + | stringConst + +// JTC: +// ID should catch the enumerator +// leaving it in gives ambiguous err +// | enumerator + + | #( NExpressionGroup expr ) + ; + + + +argExprList + : ( expr )+ + ; + + + +protected +charConst + : CharLiteral + ; + + +protected +stringConst + : #(NStringSeq (StringLiteral)+) + ; + + +protected +intConst + : IntOctalConst + | LongOctalConst + | UnsignedOctalConst + | IntIntConst + | LongIntConst + | UnsignedIntConst + | IntHexConst + | LongHexConst + | UnsignedHexConst + ; + + +protected +floatConst + : FloatDoubleConst + | DoubleDoubleConst + | LongDoubleConst + ; + + + + + + + + + diff --git a/src/main/antlr/com/jogamp/gluegen/cgram/HeaderParser.g b/src/main/antlr/com/jogamp/gluegen/cgram/HeaderParser.g new file mode 100644 index 0000000..0b4d5ec --- /dev/null +++ b/src/main/antlr/com/jogamp/gluegen/cgram/HeaderParser.g @@ -0,0 +1,785 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +header { + package com.jogamp.gluegen.cgram; + + import java.io.*; + import java.util.*; + + import antlr.CommonAST; + import com.jogamp.gluegen.cgram.types.*; +} + +class HeaderParser extends GnuCTreeParser; +options { + k = 1; +} + +{ + /** Name assigned to a anonymous EnumType (e.g., "enum { ... }"). */ + public static final String ANONYMOUS_ENUM_NAME = ""; + + boolean debug = false; + + public boolean getDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + /** Set the dictionary mapping typedef names to types for this + HeaderParser. Must be done before parsing. */ + public void setTypedefDictionary(TypeDictionary dict) { + this.typedefDictionary = dict; + } + + /** Returns the typedef dictionary this HeaderParser uses. */ + public TypeDictionary getTypedefDictionary() { + return typedefDictionary; + } + + /** Set the dictionary mapping struct names (i.e., the "foo" in + "struct foo { ... };") to types for this HeaderParser. Must be done + before parsing. */ + public void setStructDictionary(TypeDictionary dict) { + this.structDictionary = dict; + } + + /** Returns the struct name dictionary this HeaderParser uses. */ + public TypeDictionary getStructDictionary() { + return structDictionary; + } + + /** Get the canonicalization map, which is a regular HashMap + mapping Type to Type and which is used for looking up the unique + instances of e.g. pointer-to-structure types that have been typedefed + and therefore have names. */ + public Map getCanonMap() { + return canonMap; + } + + /** Pre-define the list of EnumTypes for this HeaderParser. Must be + done before parsing. */ + public void setEnums(List/**/ enumTypes) { + // FIXME: Need to take the input set of EnumTypes, extract all + // the enumerates from each EnumType, and fill in the enumHash + // so that each enumerate maps to the enumType to which it + // belongs. + throw new RuntimeException("setEnums is Unimplemented!"); + } + + /** Returns the EnumTypes this HeaderParser processed. */ + public List/**/ getEnums() { + return new ArrayList(enumHash.values()); + } + + /** Clears the list of functions this HeaderParser has parsed. + Useful when reusing the same HeaderParser for more than one + header file. */ + public void clearParsedFunctions() { + functions.clear(); + } + + /** Returns the list of FunctionSymbols this HeaderParser has parsed. */ + public List getParsedFunctions() { + return functions; + } + + private CompoundType lookupInStructDictionary(String typeName, + CompoundTypeKind kind, + int cvAttrs) { + CompoundType t = (CompoundType) structDictionary.get(typeName); + if (t == null) { + t = CompoundType.create(null, null, kind, cvAttrs); + t.setStructName(typeName); + structDictionary.put(typeName, t); + } + return t; + } + + private Type lookupInTypedefDictionary(String typeName) { + Type t = typedefDictionary.get(typeName); + if (t == null) { + throw new RuntimeException("Undefined reference to typedef name " + typeName); + } + return t; + } + + static class ParameterDeclaration { + private String id; + private Type type; + + ParameterDeclaration(String id, Type type) { + this.id = id; + this.type = type; + } + String id() { return id; } + Type type() { return type; } + } + + // A box for a Type. Allows type to be passed down to be modified by recursive rules. + static class TypeBox { + private Type origType; + private Type type; + private boolean isTypedef; + + TypeBox(Type type) { + this(type, false); + } + + TypeBox(Type type, boolean isTypedef) { + this.origType = type; + this.isTypedef = isTypedef; + } + + Type type() { + if (type == null) { + return origType; + } + return type; + } + void setType(Type type) { + this.type = type; + } + void reset() { + type = null; + } + + boolean isTypedef() { return isTypedef; } + + // for easier debugging + public String toString() { + String tStr = "Type=NULL_REF"; + if (type == origType) { + tStr = "Type=ORIG_TYPE"; + } else if (type != null) { + tStr = "Type: name=\"" + type.getCVAttributesString() + " " + + type.getName() + "\"; signature=\"" + type + "\"; class " + + type.getClass().getName(); + } + String oStr = "OrigType=NULL_REF"; + if (origType != null) { + oStr = "OrigType: name=\"" + origType.getCVAttributesString() + " " + + origType.getName() + "\"; signature=\"" + origType + "\"; class " + + origType.getClass().getName(); + } + return "<["+tStr + "] [" + oStr + "] " + " isTypedef=" + isTypedef+">"; + } + } + + private String getTypeString(Type t) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + sb.append(t); + sb.append(", size: "); + if(null!=t) { + SizeThunk st = t.getSize(); + if(null!=st) { + sb.append(st.getClass().getName()); + } else { + sb.append("undef"); + } + } + sb.append("]"); + return sb.toString(); + } + + private void debugPrintln(String msg) { + if(debug) { + System.err.println(msg); + } + } + + private void debugPrint(String msg) { + if(debug) { + System.err.print(msg); + } + } + + private boolean doDeclaration; // Used to only process function typedefs + private String declId; + private List parameters; + private TypeDictionary typedefDictionary; + private TypeDictionary structDictionary; + private List/**/ functions = new ArrayList(); + // hash from name of an enumerated value to the EnumType to which it belongs + private HashMap/**/ enumHash = new HashMap(); + + // Storage class specifiers + private static final int AUTO = 1 << 0; + private static final int REGISTER = 1 << 1; + private static final int TYPEDEF = 1 << 2; + // Function storage class specifiers + private static final int EXTERN = 1 << 3; + private static final int STATIC = 1 << 4; + private static final int INLINE = 1 << 5; + // Type qualifiers + private static final int CONST = 1 << 6; + private static final int VOLATILE = 1 << 7; + private static final int SIGNED = 1 << 8; + private static final int UNSIGNED = 1 << 9; + + private void initDeclaration() { + doDeclaration = false; + declId = null; + } + + private void doDeclaration() { + doDeclaration = true; + } + + private void processDeclaration(Type returnType) { + if (doDeclaration) { + FunctionSymbol sym = new FunctionSymbol(declId, new FunctionType(null, null, returnType, 0)); + if (parameters != null) { // handle funcs w/ empty parameter lists (e.g., "foo()") + for (Iterator iter = parameters.iterator(); iter.hasNext(); ) { + ParameterDeclaration pd = (ParameterDeclaration) iter.next(); + sym.addArgument(pd.type(), pd.id()); + } + } + functions.add(sym); + } + } + + private int attrs2CVAttrs(int attrs) { + int cvAttrs = 0; + if ((attrs & CONST) != 0) { + cvAttrs |= CVAttributes.CONST; + } + if ((attrs & VOLATILE) != 0) { + cvAttrs |= CVAttributes.VOLATILE; + } + return cvAttrs; + } + + /** Helper routine which handles creating a pointer or array type + for [] expressions */ + private void handleArrayExpr(TypeBox tb, AST t) { + if (t != null) { + try { + int len = parseIntConstExpr(t); + tb.setType(canonicalize(new ArrayType(tb.type(), SizeThunk.mul(SizeThunk.constant(len), tb.type().getSize()), len, 0))); + return; + } catch (RecognitionException e) { + // Fall through + } + } + tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, + tb.type(), + 0))); + } + + private int parseIntConstExpr(AST t) throws RecognitionException { + return intConstExpr(t); + } + + /** Utility function: creates a new EnumType with the given name, or + returns an existing one if it has already been created. */ + private EnumType getEnumType(String enumTypeName) { + EnumType enumType = null; + Iterator it = enumHash.values().iterator(); + while (it.hasNext()) { + EnumType potentialMatch = (EnumType)it.next(); + if (potentialMatch.getName().equals(enumTypeName)) { + enumType = potentialMatch; + break; + } + } + + if (enumType == null) { + // This isn't quite correct. In theory the enum should expand to + // the size of the largest element, so if there were a long long + // entry the enum should expand to e.g. int64. However, using + // "long" here (which is what used to be the case) was + // definitely incorrect and caused problems. + enumType = new EnumType(enumTypeName, SizeThunk.INT32); + } + + return enumType; + } + + // Map used to canonicalize types. For example, we may typedef + // struct foo { ... } *pfoo; subsequent references to struct foo* should + // point to the same PointerType object that had its name set to "pfoo". + private Map canonMap = new HashMap(); + private Type canonicalize(Type t) { + Type res = (Type) canonMap.get(t); + if (res != null) { + return res; + } + canonMap.put(t, t); + return t; + } +} + +declarator[TypeBox tb] returns [String s] { + initDeclaration(); + s = null; + List params = null; + String funcPointerName = null; + TypeBox dummyTypeBox = null; +} + : #( NDeclarator + ( pointerGroup[tb] )? + + ( id:ID { s = id.getText(); } + | LPAREN funcPointerName = declarator[dummyTypeBox] RPAREN + ) + + ( #( NParameterTypeList + ( + params = parameterTypeList + | (idList)? + ) + RPAREN + ) { + if (id != null) { + declId = id.getText(); + parameters = params; // FIXME: Ken, why are we setting this class member here? + doDeclaration(); + } else if ( funcPointerName != null ) { + /* TypeBox becomes function pointer in this case */ + FunctionType ft = new FunctionType(null, null, tb.type(), 0); + if (params == null) { + // If the function pointer has no declared parameters, it's a + // void function. I'm not sure if the parameter name is + // ever referenced anywhere when the type is VoidType, so + // just in case I'll set it to a comment string so it will + // still compile if written out to code anywhere. + ft.addArgument(new VoidType(0), "/*unnamed-void*/"); + } else { + for (Iterator iter = params.iterator(); iter.hasNext(); ) { + ParameterDeclaration pd = (ParameterDeclaration) iter.next(); + ft.addArgument(pd.type(), pd.id()); + } + } + tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, + ft, + 0))); + s = funcPointerName; + } + } + | LBRACKET ( e:expr )? RBRACKET { handleArrayExpr(tb, e); } + )* + ) + ; + +typelessDeclaration { + TypeBox tb = null; +} + : #(NTypeMissing initDeclList[tb] SEMI) + ; + +declaration { + TypeBox tb = null; +} + : #( NDeclaration + tb = declSpecifiers + ( + initDeclList[tb] + )? + ( SEMI )+ + ) { processDeclaration(tb.type()); } + ; + +parameterTypeList returns [List l] { l = new ArrayList(); ParameterDeclaration decl = null; } + : ( decl = parameterDeclaration { if (decl != null) l.add(decl); } ( COMMA | SEMI )? )+ ( VARARGS )? + ; + +parameterDeclaration returns [ParameterDeclaration pd] { + Type t = null; + String decl = null; + pd = null; + TypeBox tb = null; +} + : #( NParameterDeclaration + tb = declSpecifiers + (decl = declarator[tb] | nonemptyAbstractDeclarator[tb])? + ) { pd = new ParameterDeclaration(decl, tb.type()); } + ; + +functionDef { + TypeBox tb = null; +} + : #( NFunctionDef + ( functionDeclSpecifiers)? + declarator[tb] + (declaration | VARARGS)* + compoundStatement + ) + ; + +declSpecifiers returns [TypeBox tb] { + tb = null; + Type t = null; + int x = 0; + int y = 0; +} + : ( y = storageClassSpecifier { x |= y; } + | y = typeQualifier { x |= y; } + | t = typeSpecifier[x] + )+ +{ + if (t == null && + (x & (SIGNED | UNSIGNED)) != 0) { + t = new IntType("int", SizeThunk.INTxx, ((x & UNSIGNED) != 0), attrs2CVAttrs(x)); + } + tb = new TypeBox(t, ((x & TYPEDEF) != 0)); +} + ; + +storageClassSpecifier returns [int x] { x = 0; } + : "auto" { x |= AUTO; } + | "register" { x |= REGISTER; } + | "typedef" { x |= TYPEDEF; } + | x = functionStorageClassSpecifier + ; + + +functionStorageClassSpecifier returns [int x] { x = 0; } + : "extern" { x |= EXTERN; } + | "static" { x |= STATIC; } + | "inline" { x |= INLINE; } + ; + + +typeQualifier returns [int x] { x = 0; } + : "const" { x |= CONST; } + | "volatile" { x |= VOLATILE; } + | "signed" { x |= SIGNED; } + | "unsigned" { x |= UNSIGNED; } + ; + +typeSpecifier[int attributes] returns [Type t] { + t = null; + int cvAttrs = attrs2CVAttrs(attributes); + boolean unsigned = ((attributes & UNSIGNED) != 0); +} + : "void" { t = new VoidType(cvAttrs); } + | "char" { t = new IntType("char" , SizeThunk.INT8, unsigned, cvAttrs); } + | "short" { t = new IntType("short", SizeThunk.INT16, unsigned, cvAttrs); } + | "int" { t = new IntType("int" , SizeThunk.INTxx, unsigned, cvAttrs); } + | "long" { t = new IntType("long" , SizeThunk.LONG, unsigned, cvAttrs); } + | "float" { t = new FloatType("float", SizeThunk.FLOAT, cvAttrs); } + | "double" { t = new DoubleType("double", SizeThunk.DOUBLE, cvAttrs); } + | "__int32" { t = new IntType("__int32", SizeThunk.INT32, unsigned, cvAttrs); } + | "__int64" { t = new IntType("__int64", SizeThunk.INT64, unsigned, cvAttrs); } + | "int8_t" { t = new IntType("int8_t", SizeThunk.INT8, false, cvAttrs); /* TS: always signed */ } + | "uint8_t" { t = new IntType("uint8_t", SizeThunk.INT8, true, cvAttrs); /* TS: always unsigned */ } + | "int16_t" { t = new IntType("int16_t", SizeThunk.INT16, false, cvAttrs); /* TS: always signed */ } + | "uint16_t" { t = new IntType("uint16_t", SizeThunk.INT16, true, cvAttrs); /* TS: always unsigned */ } + | "int32_t" { t = new IntType("int32_t", SizeThunk.INT32, false, cvAttrs); /* TS: always signed */ } + | "wchar_t" { t = new IntType("wchar_t", SizeThunk.INT32, false, cvAttrs); /* TS: always signed */ } + | "uint32_t" { t = new IntType("uint32_t", SizeThunk.INT32, true, cvAttrs, true); /* TS: always unsigned */ } + | "int64_t" { t = new IntType("int64_t", SizeThunk.INT64, false, cvAttrs); /* TS: always signed */ } + | "uint64_t" { t = new IntType("uint64_t", SizeThunk.INT64, true, cvAttrs, true); /* TS: always unsigned */ } + | "ptrdiff_t" { t = new IntType("ptrdiff_t", SizeThunk.POINTER, false, cvAttrs); /* TS: always signed */ } + | "intptr_t" { t = new IntType("intptr_t", SizeThunk.POINTER, false, cvAttrs); /* TS: always signed */ } + | "size_t" { t = new IntType("size_t", SizeThunk.POINTER, true, cvAttrs, true); /* TS: always unsigned */ } + | "uintptr_t" { t = new IntType("uintptr_t", SizeThunk.POINTER, true, cvAttrs, true); /* TS: always unsigned */ } + | t = structSpecifier[cvAttrs] ( attributeDecl )* + | t = unionSpecifier [cvAttrs] ( attributeDecl )* + | t = enumSpecifier [cvAttrs] + | t = typedefName [cvAttrs] + | #("typeof" LPAREN + ( (typeName )=> typeName + | expr + ) + RPAREN + ) + | "__complex" + ; + +typedefName[int cvAttrs] returns [Type t] { t = null; } + : #(NTypedefName id : ID) + { + Type tdict = lookupInTypedefDictionary(id.getText()); + t = canonicalize(tdict.getCVVariant(cvAttrs)); + debugPrintln("Adding typedef canon : [" + id.getText() + "] -> [" + tdict + "] -> "+getTypeString(t)); + } + ; + +structSpecifier[int cvAttrs] returns [Type t] { t = null; } + : #( "struct" t = structOrUnionBody[CompoundTypeKind.STRUCT, cvAttrs] ) + ; + +unionSpecifier[int cvAttrs] returns [Type t] { t = null; } + : #( "union" t = structOrUnionBody[CompoundTypeKind.UNION, cvAttrs] ) + ; + +structOrUnionBody[CompoundTypeKind kind, int cvAttrs] returns [CompoundType t] { + t = null; +} + : ( (ID LCURLY) => id:ID LCURLY { + t = (CompoundType) canonicalize(lookupInStructDictionary(id.getText(), kind, cvAttrs)); + } ( structDeclarationList[t] )? + RCURLY { t.setBodyParsed(); } + | LCURLY { t = CompoundType.create(null, null, kind, cvAttrs); } + ( structDeclarationList[t] )? + RCURLY { t.setBodyParsed(); } + | id2:ID { t = (CompoundType) canonicalize(lookupInStructDictionary(id2.getText(), kind, cvAttrs)); } + ) + ; + +structDeclarationList[CompoundType t] + : ( structDeclaration[t] )+ + ; + +structDeclaration[CompoundType containingType] { + Type t = null; + boolean addedAny = false; +} + : t = specifierQualifierList addedAny = structDeclaratorList[containingType, t] { + if (!addedAny) { + if (t != null) { + CompoundType ct = t.asCompound(); + if (ct.isUnion()) { + // Anonymous union + containingType.addField(new Field(null, t, null)); + } + } + } + } + ; + +specifierQualifierList returns [Type t] { + t = null; int x = 0; int y = 0; +} + : ( + t = typeSpecifier[x] + | y = typeQualifier { x |= y; } + )+ { + if (t == null && + (x & (SIGNED | UNSIGNED)) != 0) { + t = new IntType("int", SizeThunk.INTxx, ((x & UNSIGNED) != 0), attrs2CVAttrs(x)); + } +} + ; + +structDeclaratorList[CompoundType containingType, Type t] returns [boolean addedAny] { + addedAny = false; + boolean y = false; +} + : ( y = structDeclarator[containingType, t] { addedAny = y; })+ + ; + +structDeclarator[CompoundType containingType, Type t] returns [boolean addedAny] { + addedAny = false; + String s = null; + TypeBox tb = new TypeBox(t); +} + : + #( NStructDeclarator + ( s = declarator[tb] { containingType.addField(new Field(s, tb.type(), null)); addedAny = true; } )? + ( COLON expr { /* FIXME: bit types not handled yet */ } ) ? + ( attributeDecl )* + ) + ; + +// FIXME: this will not correctly set the name of the enumeration when +// encountering a declaration like this: +// +// typedef enum { } enumName; +// +// In this case calling getName() on the EnumType return value will +// incorrectly return HeaderParser.ANONYMOUS_ENUM_NAME instead of +// "enumName" +// +// I haven't implemented it yet because I'm not sure how to get the +// "enumName" *before* executing the enumList rule. +enumSpecifier [int cvAttrs] returns [Type t] { + t = null; +} + : #( "enum" + ( ( ID LCURLY )=> i:ID LCURLY enumList[(EnumType)(t = getEnumType(i.getText()))] RCURLY + | LCURLY enumList[(EnumType)(t = getEnumType(ANONYMOUS_ENUM_NAME))] RCURLY + | ID { t = getEnumType(i.getText()); } + ) + ) + ; + +enumList[EnumType enumeration] { + long defaultEnumerantValue = 0; +} + : ( defaultEnumerantValue = enumerator[enumeration, defaultEnumerantValue] )+ + ; + +enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValue] { + newDefaultValue = defaultValue; +} + : eName:ID ( ASSIGN eVal:expr )? { + long value = 0; + if (eVal != null) { + String vTxt = eVal.getAllChildrenText(); + if (enumHash.containsKey(vTxt)) { + EnumType oldEnumType = (EnumType) enumHash.get(vTxt); + value = oldEnumType.getEnumValue(vTxt); + } else { + try { + value = Long.decode(vTxt).longValue(); + } catch (NumberFormatException e) { + System.err.println("NumberFormatException: ID[" + eName.getText() + "], VALUE=[" + vTxt + "]"); + throw e; + } + } + } else { + value = defaultValue; + } + + newDefaultValue = value+1; + String eTxt = eName.getText(); + if (enumHash.containsKey(eTxt)) { + EnumType oldEnumType = (EnumType) enumHash.get(eTxt); + long oldValue = oldEnumType.getEnumValue(eTxt); + System.err.println("WARNING: redefinition of enumerated value '" + eTxt + "';" + + " existing definition is in enumeration '" + oldEnumType.getName() + + "' with value " + oldValue + " and new definition is in enumeration '" + + enumeration.getName() + "' with value " + value); + // remove old definition + oldEnumType.removeEnumerate(eTxt); + } + // insert new definition + enumeration.addEnum(eTxt, value); + enumHash.put(eTxt, enumeration); + debugPrintln("ENUM [" + enumeration.getName() + "]: " + eTxt + " = " + enumeration.getEnumValue(eTxt) + + " (new default = " + newDefaultValue + ")"); + } + ; + +initDeclList[TypeBox tb] + : ( initDecl[tb] )+ + ; + +initDecl[TypeBox tb] { + String declName = null; +} + : #( NInitDecl + declName = declarator[tb] { + debugPrintln("GOT declName: " + declName + " TB=" + tb); + } + ( attributeDecl )* + ( ASSIGN initializer + | COLON expr + )? + ) +{ + if ((declName != null) && (tb != null) && tb.isTypedef()) { + Type t = tb.type(); + debugPrint("Adding typedef mapping: [" + declName + "] -> "+getTypeString(t)); + if (!t.hasTypedefName()) { + t.setName(declName); + debugPrint(" - declName -> "+getTypeString(t)); + } else { + // copy type to preserve declName ! + t = (Type) t.clone(); + t.setName(declName); + debugPrint(" - copy -> "+getTypeString(t)); + } + t = canonicalize(t); + debugPrintln(" - canon -> "+getTypeString(t)); + typedefDictionary.put(declName, t); + // Clear out PointerGroup effects in case another typedef variant follows + tb.reset(); + } +} + ; + +pointerGroup[TypeBox tb] { int x = 0; int y = 0; } + : #( NPointerGroup ( STAR { x = 0; y = 0; } ( y = typeQualifier { x |= y; } )* + { + debugPrintln("IN PTR GROUP: TB=" + tb); + if (tb != null) { + tb.setType(canonicalize(new PointerType(SizeThunk.POINTER, + tb.type(), + attrs2CVAttrs(x)))); + } + } + )+ ) + ; + + +functionDeclSpecifiers + : + ( functionStorageClassSpecifier + | typeQualifier + | typeSpecifier[0] + )+ + ; + +typeName { + TypeBox tb = null; +} + : specifierQualifierList (nonemptyAbstractDeclarator[tb])? + ; + + +/* FIXME: the handling of types in this rule has not been well thought + out and is known to be incomplete. Currently it is only used to handle + pointerGroups for unnamed parameters. */ +nonemptyAbstractDeclarator[TypeBox tb] + : #( NNonemptyAbstractDeclarator + ( pointerGroup[tb] + ( (LPAREN + ( nonemptyAbstractDeclarator[tb] + | parameterTypeList + )? + RPAREN) + | (LBRACKET (e1:expr)? RBRACKET) { handleArrayExpr(tb, e1); } + )* + + | ( (LPAREN + ( nonemptyAbstractDeclarator[tb] + | parameterTypeList + )? + RPAREN) + | (LBRACKET (e2:expr)? RBRACKET) { handleArrayExpr(tb, e2); } + )+ + ) + ) + ; + +/* Helper routine for parsing expressions which evaluate to integer + constants. Can be made more complicated as necessary. */ +intConstExpr returns [int i] { i = -1; } + : n:Number { return Integer.parseInt(n.getText()); } + ; diff --git a/src/main/antlr/com/jogamp/gluegen/cgram/StdCParser.g b/src/main/antlr/com/jogamp/gluegen/cgram/StdCParser.g new file mode 100644 index 0000000..7b34656 --- /dev/null +++ b/src/main/antlr/com/jogamp/gluegen/cgram/StdCParser.g @@ -0,0 +1,1401 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Copyright (c) Non, Inc. 1997 -- All Rights Reserved + +PROJECT: C Compiler +MODULE: Parser +FILE: stdc.g + +AUTHOR: John D. Mitchell (john@non.net), Jul 12, 1997 + +REVISION HISTORY: + + Name Date Description + ---- ---- ----------- + JDM 97.07.12 Initial version. + JTC 97.11.18 Declaration vs declarator & misc. hacking. + JDM 97.11.20 Fixed: declaration vs funcDef, + parenthesized expressions, + declarator iteration, + varargs recognition, + empty source file recognition, + and some typos. + + +DESCRIPTION: + + This grammar supports the Standard C language. + + Note clearly that this grammar does *NOT* deal with + preprocessor functionality (including things like trigraphs) + Nor does this grammar deal with multi-byte characters nor strings + containing multi-byte characters [these constructs are "exercises + for the reader" as it were :-)]. + + Please refer to the ISO/ANSI C Language Standard if you believe + this grammar to be in error. Please cite chapter and verse in any + correspondence to the author to back up your claim. + +TODO: + + - typedefName is commented out, needs a symbol table to resolve + ambiguity. + + - trees + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + + +header { + package com.jogamp.gluegen.cgram; + + import java.io.*; + + import antlr.CommonAST; + import antlr.DumpASTVisitor; +} + + +class StdCParser extends Parser; + +options + { + k = 2; + exportVocab = STDC; + buildAST = true; + ASTLabelType = "TNode"; + + // Copied following options from java grammar. + codeGenMakeSwitchThreshold = 2; + codeGenBitsetTestThreshold = 3; + } + + +{ + // 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; x0)?" [inputState.guessing "+ inputState.guessing + "]":"")); + + } + + } + try { + if ( LA(1)!=t ) { + if ( debugging ){ + for (int x=0; x "+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 declaration + | functionDef + | asm_expr + ; + + +asm_expr + : "asm"^ + ("volatile")? LCURLY! expr RCURLY! SEMI! + ; + + +declaration + { AST ds1 = null; } + : ds:declSpecifiers { ds1 = astFactory.dupList(#ds); } + ( + initDeclList[ds1] + )? + SEMI! + { ## = #( #[NDeclaration], ##); } + + ; + + +declSpecifiers + { int specCount=0; } + : ( options { // this loop properly aborts when + // it finds a non-typedefName ID MBZ + warnWhenFollowAmbig = false; + } : + s:storageClassSpecifier + | typeQualifier + | ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=> + specCount = typeSpecifier[specCount] + )+ + ; + +storageClassSpecifier + : "auto" + | "register" + | "typedef" + | functionStorageClassSpecifier + ; + + +functionStorageClassSpecifier + : "extern" + | "static" + ; + + +typeQualifier + : "const" + | "volatile" + ; + +typeSpecifier [int specCount] returns [int retSpecCount] + { retSpecCount = specCount + 1; } + : + ( "void" + | "char" + | "short" + | "int" + | "long" + | "float" + | "double" + | "signed" + | "unsigned" + | "int8_t" + | "uint8_t" + | "int16_t" + | "uint16_t" + | "__int32" + | "int32_t" + | "wchar_t" + | "uint32_t" + | "__int64" + | "int64_t" + | "uint64_t" + | "ptrdiff_t" + | "intptr_t" + | "size_t" + | "uintptr_t" + | structOrUnionSpecifier + | enumSpecifier + | { specCount == 0 }? typedefName + ) + ; + + +typedefName + : { isTypedefName ( LT(1).getText() ) }? + i:ID { ## = #(#[NTypedefName], #i); } + ; + +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, ## ); + } + ; + + +structOrUnion + : "struct" + | "union" + ; + + +structDeclarationList + : ( structDeclaration )+ + ; + + +structDeclaration + : specifierQualifierList structDeclaratorList ( SEMI! )+ + ; + + +specifierQualifierList + { int specCount = 0; } + : ( options { // this loop properly aborts when + // it finds a non-typedefName ID MBZ + warnWhenFollowAmbig = false; + } : + ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=> + specCount = typeSpecifier[specCount] + | typeQualifier + )+ + ; + + +structDeclaratorList + : structDeclarator ( COMMA! structDeclarator )* + ; + + +structDeclarator + : + ( COLON constExpr + | declarator[false] ( COLON constExpr )? + ) + { ## = #( #[NStructDeclarator], ##); } + ; + + +enumSpecifier + : "enum"^ + ( ( ID LCURLY )=> i:ID LCURLY enumList[i.getText()] RCURLY! + | LCURLY enumList["anonymous"] RCURLY! + | ID + ) + ; + + +enumList[String enumName] + : enumerator[enumName] ( COMMA! enumerator[enumName] )* + ; + +enumerator[String enumName] + : i:ID { symbolTable.add( i.getText(), + #( null, + #[LITERAL_enum, "enum"], + #[ ID, enumName] + ) + ); + } + (ASSIGN constExpr)? + ; + + +initDeclList[AST declarationSpecifiers] + : initDecl[declarationSpecifiers] + ( COMMA! initDecl[declarationSpecifiers] )* + ; + + +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) ); + } + ( ASSIGN initializer + | COLON expr + )? + { ## = #( #[NInitDecl], ## ); } + + ; + +pointerGroup + : ( STAR ( typeQualifier )* )+ { ## = #( #[NPointerGroup], ##); } + ; + + + +idList + : ID ( COMMA! ID )* + ; + + +initializer + : ( assignExpr + | LCURLY initializerList ( COMMA! )? RCURLY! + ) + { ## = #( #[NInitializer], ## ); } + ; + + +initializerList + : initializer ( COMMA! initializer )* + ; + + +declarator[boolean isFunctionDefinition] returns [String declName] + { declName = ""; } + : + ( pointerGroup )? + + ( id:ID { declName = id.getText(); } + | LPAREN declName = declarator[false] RPAREN + ) + + ( ! LPAREN + { + if (isFunctionDefinition) { + pushScope(declName); + } + else { + pushScope("!"+declName); + } + } + ( + (declSpecifiers)=> p:parameterTypeList + { + ## = #( null, ##, #( #[NParameterTypeList], #p ) ); + } + + | (i:idList)? + { + ## = #( null, ##, #( #[NParameterTypeList], #i ) ); + } + ) + { + 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 = (TNode) #[ NEmptyExpression ]; } + if ( #e2 == null) { #e2 = (TNode) #[ NEmptyExpression ]; } + if ( #e3 == null) { #e3 = (TNode) #[ 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 + ; + + + + + + +{ + import java.io.*; + import antlr.*; +} + +class StdCLexer extends Lexer; + +options + { + k = 3; + exportVocab = STDC; + testLiterals = false; + } + +{ + 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) ); + } + + public void addDefine(String name, String value) + { + } + + 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() { + lineObject.newline(); + } + + + + + + +} + +protected +Vocabulary + : '\3'..'\377' + ; + + +/* Operators: */ + +ASSIGN : '=' ; +COLON : ':' ; +COMMA : ',' ; +QUESTION : '?' ; +SEMI : ';' ; +PTR : "->" ; + + +// DOT & VARARGS are commented out since they are generated as part of +// the Number rule below due to some bizarre lexical ambiguity shme. + +// DOT : '.' ; +protected +DOT:; + +// VARARGS : "..." ; +protected +VARARGS:; + + +LPAREN : '(' ; +RPAREN : ')' ; +LBRACKET : '[' ; +RBRACKET : ']' ; +LCURLY : '{' ; +RCURLY : '}' ; + +EQUAL : "==" ; +NOT_EQUAL : "!=" ; +LTE : "<=" ; +LT : "<" ; +GTE : ">=" ; +GT : ">" ; + +DIV : '/' ; +DIV_ASSIGN : "/=" ; +PLUS : '+' ; +PLUS_ASSIGN : "+=" ; +INC : "++" ; +MINUS : '-' ; +MINUS_ASSIGN : "-=" ; +DEC : "--" ; +STAR : '*' ; +STAR_ASSIGN : "*=" ; +MOD : '%' ; +MOD_ASSIGN : "%=" ; +RSHIFT : ">>" ; +RSHIFT_ASSIGN : ">>=" ; +LSHIFT : "<<" ; +LSHIFT_ASSIGN : "<<=" ; + +LAND : "&&" ; +LNOT : '!' ; +LOR : "||" ; + +BAND : '&' ; +BAND_ASSIGN : "&=" ; +BNOT : '~' ; +BOR : '|' ; +BOR_ASSIGN : "|=" ; +BXOR : '^' ; +BXOR_ASSIGN : "^=" ; + + +Whitespace + : ( ( '\003'..'\010' | '\t' | '\013' | '\f' | '\016'.. '\037' | '\177'..'\377' | ' ' ) + | "\r\n" { newline(); } + | ( '\n' | '\r' ) { newline(); } + ) { _ttype = Token.SKIP; } + ; + + +Comment + : "/*" + ( { LA(2) != '/' }? '*' + | "\r\n" { deferredNewline(); } + | ( '\r' | '\n' ) { deferredNewline(); } + | ~( '*'| '\r' | '\n' ) + )* + "*/" { _ttype = Token.SKIP; + } + ; + + +CPPComment + : + "//" ( ~('\n') )* + { + _ttype = Token.SKIP; + } + ; + +protected NonWhitespace + : (~('\r' | '\n'))* + ; + + +PREPROC_DIRECTIVE +options { + paraphrase = "a line directive"; +} + + : + '#' + ( ( "line" || (( ' ' | '\t' | '\014')+ '0'..'9')) => LineDirective + | ( (Space)* "define" (Space)* i:ID (Space)* (n:DefineExpr)? + nw:NonWhitespace + ("\r\n" | "\r" | "\n") ) { + if (n != null) { + //System.out.println("addDefine: #define " + i.getText() + " " + n.getText()); + addDefine(i.getText(), n.getText()); + } else { + setPreprocessingDirective("#define " + i.getText() + " " + nw.getText()); + } + } + | (~'\n')* { setPreprocessingDirective(getText()); } + ) + { + _ttype = Token.SKIP; + } + ; + +DefineExpr: + ((LPAREN) (Space)* (DefineExpr2) (Space)* (RPAREN)) | (DefineExpr2) +; + +DefineExpr2: + (Number) + ((Space)* (LSHIFT | RSHIFT | PLUS | MINUS | STAR | DIV | MOD) (Space)* (DefineExpr))? +; + + +protected Space: + ( ' ' | '\t' | '\014') + ; + +protected LineDirective +{ + boolean oldCountingTokens = countingTokens; + countingTokens = false; +} +: + { + lineObject = new LineObject(); + deferredLineCount = 0; + } + ("line")? //this would be for if the directive started "#line", but not there for GNU directives + (Space)+ + n:Number { lineObject.setLine(Integer.parseInt(n.getText())); } + (Space)+ + ( fn:StringLiteral { try { + lineObject.setSource(fn.getText().substring(1,fn.getText().length()-1)); + } + catch (StringIndexOutOfBoundsException e) { /*not possible*/ } + } + | fi:ID { lineObject.setSource(fi.getText()); } + )? + (Space)* + ("1" { lineObject.setEnteringFile(true); } )? + (Space)* + ("2" { lineObject.setReturningToFile(true); } )? + (Space)* + ("3" { lineObject.setSystemHeader(true); } )? + (Space)* + ("4" { lineObject.setTreatAsC(true); } )? + (~('\r' | '\n'))* + ("\r\n" | "\r" | "\n") + { + preprocessorInfoChannel.addLineForTokenNumber(new LineObject(lineObject), new Integer(tokenNumber)); + countingTokens = oldCountingTokens; + } + ; + + + +/* Literals: */ + +/* + * Note that we do NOT handle tri-graphs nor multi-byte sequences. + */ + + +/* + * Note that we can't have empty character constants (even though we + * can have empty strings :-). + */ +CharLiteral + : '\'' ( Escape | ~( '\'' ) ) '\'' + ; + + +/* + * Can't have raw imbedded newlines in string constants. Strict reading of + * the standard gives odd dichotomy between newlines & carriage returns. + * Go figure. + */ +StringLiteral + : '"' + ( Escape + | ( + '\r' { deferredNewline(); } + | '\n' { + deferredNewline(); + _ttype = BadStringLiteral; + } + | '\\' '\n' { + deferredNewline(); + } + ) + | ~( '"' | '\r' | '\n' | '\\' ) + )* + '"' + ; + + +protected BadStringLiteral + : // Imaginary token. + ; + + +/* + * Handle the various escape sequences. + * + * Note carefully that these numeric escape *sequences* are *not* of the + * same form as the C language numeric *constants*. + * + * There is no such thing as a binary numeric escape sequence. + * + * Octal escape sequences are either 1, 2, or 3 octal digits exactly. + * + * There is no such thing as a decimal escape sequence. + * + * Hexadecimal escape sequences are begun with a leading \x and continue + * until a non-hexadecimal character is found. + * + * No real handling of tri-graph sequences, yet. + */ + +protected +Escape + : '\\' + ( options{warnWhenFollowAmbig=false;}: + 'a' + | 'b' + | 'f' + | 'n' + | 'r' + | 't' + | 'v' + | '"' + | '\'' + | '\\' + | '?' + | ('0'..'3') ( options{warnWhenFollowAmbig=false;}: Digit ( options{warnWhenFollowAmbig=false;}: Digit )? )? + | ('4'..'7') ( options{warnWhenFollowAmbig=false;}: Digit )? + | 'x' ( options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F' )+ + ) + ; + + +/* Numeric Constants: */ + +protected +Digit + : '0'..'9' + ; + +protected +LongSuffix + : 'l' + | 'L' + ; + +protected +UnsignedSuffix + : 'u' + | 'U' + ; + +protected +FloatSuffix + : 'f' + | 'F' + ; + +protected +Exponent + : ( 'e' | 'E' ) ( '+' | '-' )? ( Digit )+ + ; + + +protected +DoubleDoubleConst:; + +protected +FloatDoubleConst:; + +protected +LongDoubleConst:; + +protected +IntOctalConst:; + +protected +LongOctalConst:; + +protected +UnsignedOctalConst:; + +protected +IntIntConst:; + +protected +LongIntConst:; + +protected +UnsignedIntConst:; + +protected +IntHexConst:; + +protected +LongHexConst:; + +protected +UnsignedHexConst:; + + + + +Number + : ( ( Digit )+ ( '.' | 'e' | 'E' ) )=> ( Digit )+ + ( '.' ( Digit )* ( Exponent )? + | Exponent + ) { _ttype = DoubleDoubleConst; } + ( FloatSuffix { _ttype = FloatDoubleConst; } + | LongSuffix { _ttype = LongDoubleConst; } + )? + + | ( "..." )=> "..." { _ttype = VARARGS; } + + | '.' { _ttype = DOT; } + ( ( Digit )+ ( Exponent )? + { _ttype = DoubleDoubleConst; } + ( FloatSuffix { _ttype = FloatDoubleConst; } + | LongSuffix { _ttype = LongDoubleConst; } + )? + )? + + | '0' ( '0'..'7' )* { _ttype = IntOctalConst; } + ( LongSuffix { _ttype = LongOctalConst; } + | UnsignedSuffix { _ttype = UnsignedOctalConst; } + )? + + | '1'..'9' ( Digit )* { _ttype = IntIntConst; } + ( LongSuffix { _ttype = LongIntConst; } + | UnsignedSuffix { _ttype = UnsignedIntConst; } + )? + + | '0' ( 'x' | 'X' ) ( 'a'..'f' | 'A'..'F' | Digit )+ + { _ttype = IntHexConst; } + ( LongSuffix { _ttype = LongHexConst; } + | UnsignedSuffix { _ttype = UnsignedHexConst; } + )? + ; + + +ID + options + { + testLiterals = true; + } + : ( 'a'..'z' | 'A'..'Z' | '_' ) + ( 'a'..'z' | 'A'..'Z' | '_' | '0'..'9' )* + ; + + diff --git a/src/main/antlr/com/jogamp/gluegen/jgram/JavaParser.g b/src/main/antlr/com/jogamp/gluegen/jgram/JavaParser.g new file mode 100644 index 0000000..f67579e --- /dev/null +++ b/src/main/antlr/com/jogamp/gluegen/jgram/JavaParser.g @@ -0,0 +1,1315 @@ +/* Java 1.3 Recognizer + * + * Run 'java Main [-showtree] directory-full-of-java-files' + * + * [The -showtree option pops up a Swing frame that shows + * the AST constructed from the parser.] + * + * Run 'java Main ' + * + * Contributing authors: + * John Mitchell johnm@non.net + * Terence Parr parrt@magelang.com + * John Lilley jlilley@empathy.com + * Scott Stanchfield thetick@magelang.com + * Markus Mohnen mohnen@informatik.rwth-aachen.de + * Peter Williams pete.williams@sun.com + * Allan Jacobs Allan.Jacobs@eng.sun.com + * Steve Messick messick@redhills.com + * John Pybus john@pybus.org + * + * Version 1.00 December 9, 1997 -- initial release + * Version 1.01 December 10, 1997 + * fixed bug in octal def (0..7 not 0..8) + * Version 1.10 August 1998 (parrt) + * added tree construction + * fixed definition of WS,comments for mac,pc,unix newlines + * added unary plus + * Version 1.11 (Nov 20, 1998) + * Added "shutup" option to turn off last ambig warning. + * Fixed inner class def to allow named class defs as statements + * synchronized requires compound not simple statement + * add [] after builtInType DOT class in primaryExpression + * "const" is reserved but not valid..removed from modifiers + * Version 1.12 (Feb 2, 1999) + * Changed LITERAL_xxx to xxx in tree grammar. + * Updated java.g to use tokens {...} now for 2.6.0 (new feature). + * + * Version 1.13 (Apr 23, 1999) + * Didn't have (stat)? for else clause in tree parser. + * Didn't gen ASTs for interface extends. Updated tree parser too. + * Updated to 2.6.0. + * Version 1.14 (Jun 20, 1999) + * Allowed final/abstract on local classes. + * Removed local interfaces from methods + * Put instanceof precedence where it belongs...in relationalExpr + * It also had expr not type as arg; fixed it. + * Missing ! on SEMI in classBlock + * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus). + * fixed: didn't like Object[].class in parser or tree parser + * Version 1.15 (Jun 26, 1999) + * Screwed up rule with instanceof in it. :( Fixed. + * Tree parser didn't like (expr).something; fixed. + * Allowed multiple inheritance in tree grammar. oops. + * Version 1.16 (August 22, 1999) + * Extending an interface built a wacky tree: had extra EXTENDS. + * Tree grammar didn't allow multiple superinterfaces. + * Tree grammar didn't allow empty var initializer: {} + * Version 1.17 (October 12, 1999) + * ESC lexer rule allowed 399 max not 377 max. + * java.tree.g didn't handle the expression of synchronized + * statements. + * Version 1.18 (August 12, 2001) + * Terence updated to Java 2 Version 1.3 by + * observing/combining work of Allan Jacobs and Steve + * Messick. Handles 1.3 src. Summary: + * o primary didn't include boolean.class kind of thing + * o constructor calls parsed explicitly now: + * see explicitConstructorInvocation + * o add strictfp modifier + * o missing objBlock after new expression in tree grammar + * o merged local class definition alternatives, moved after declaration + * o fixed problem with ClassName.super.field + * o reordered some alternatives to make things more efficient + * o long and double constants were not differentiated from int/float + * o whitespace rule was inefficient: matched only one char + * o add an examples directory with some nasty 1.3 cases + * o made Main.java use buffered IO and a Reader for Unicode support + * o supports UNICODE? + * Using Unicode charVocabulay makes code file big, but only + * in the bitsets at the end. I need to make ANTLR generate + * unicode bitsets more efficiently. + * Version 1.19 (April 25, 2002) + * Terence added in nice fixes by John Pybus concerning floating + * constants and problems with super() calls. John did a nice + * reorg of the primary/postfix expression stuff to read better + * and makes f.g.super() parse properly (it was METHOD_CALL not + * a SUPER_CTOR_CALL). Also: + * + * o "finally" clause was a root...made it a child of "try" + * o Added stuff for asserts too for Java 1.4, but *commented out* + * as it is not backward compatible. + * + * Version 1.20 (October 27, 2002) + * + * Terence ended up reorging John Pybus' stuff to + * remove some nondeterminisms and some syntactic predicates. + * Note that the grammar is stricter now; e.g., this(...) must + * be the first statement. + * + * Trinary ?: operator wasn't working as array name: + * (isBig ? bigDigits : digits)[i]; + * + * Checked parser/tree parser on source for + * Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4, + * and the 110k-line jGuru server source. + * + * Version 1.21 (October 17, 2003) + * Fixed lots of problems including: + * Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g + * He found a problem/fix with floating point that start with 0 + * Ray also fixed problem that (int.class) was not recognized. + * Thorsten van Ellen noticed that \n are allowed incorrectly in strings. + * TJP fixed CHAR_LITERAL analogously. + * + * Version 1.22 (April 14, 2004) + * Changed vocab to be ..\uFFFE to avoid -1 char. removed dummy VOCAB rule. + * + * This grammar is in the PUBLIC DOMAIN + */ + +header { + package com.jogamp.gluegen.jgram; + + import java.util.*; + + import antlr.CommonAST; +} + +class JavaParser extends Parser; + +options { + k = 2; // two token lookahead + exportVocab=Java; // Call its vocabulary "Java" + codeGenMakeSwitchThreshold = 2; // Some optimizations + codeGenBitsetTestThreshold = 3; + defaultErrorHandler = false; // Don't generate parser error handlers + buildAST = true; + //buildAST = false; +} + +tokens { + BLOCK; MODIFIERS; OBJBLOCK; SLIST; CTOR_DEF; METHOD_DEF; VARIABLE_DEF; + INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF; + PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE; + PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP; + POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT; + IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION; + FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract"; + STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; +} + +{ + public void clearParsedEnumNames() { + enumNames.clear(); + } + + /** Returns the EnumTypes this HeaderParser processed. */ + public Set getParsedEnumNames() { + return enumNames; + } + + /** Clears the list of functions this HeaderParser has parsed. + Useful when reusing the same HeaderParser for more than one + header file. */ + public void clearParsedFunctionNames() { + functionNames.clear(); + } + + /** Returns the list of FunctionSymbols this HeaderParser has parsed. */ + public Set getParsedFunctionNames() { + return functionNames; + } + + private Set functionNames = new HashSet(); + // hash from name of an enumerated value to the EnumType to which it belongs + private Set enumNames = new HashSet(); + + private int blockDepth = 0; +} + +// Compilation Unit: In Java, this is a single file. This is the start +// rule for this parser +compilationUnit + : // A compilation unit starts with an optional package definition + ( packageDefinition + | /* nothing */ + ) + + // Next we have a series of zero or more import statements + ( importDefinition )* + + // Wrapping things up with any number of class or interface + // definitions + ( typeDefinition )* + + EOF! + ; + + +// Package statement: "package" followed by an identifier. +packageDefinition + options {defaultErrorHandler = true;} // let ANTLR handle errors + : p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI! + ; + + +// Import statement: import followed by a package or class name +importDefinition + options {defaultErrorHandler = true;} + : i:"import"^ {#i.setType(IMPORT);} identifierStar SEMI! + ; + +// A type definition in a file is either a class or interface definition. +typeDefinition + options {defaultErrorHandler = true;} + : m:modifiers! + ( classDefinition[#m] + | interfaceDefinition[#m] + ) + | SEMI! + ; + +/** A declaration is the creation of a reference or primitive-type variable + * Create a separate Type/Var tree for each var in the var list. + */ +declaration! + : m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t] + {#declaration = #v;} + ; + +// A type specification is a type name with possible brackets afterwards +// (which would make it an array type). +typeSpec[boolean addImagNode] + : classTypeSpec[addImagNode] + | builtInTypeSpec[addImagNode] + ; + +// A class type specification is a class type with possible brackets afterwards +// (which would make it an array type). +classTypeSpec[boolean addImagNode] + : identifier (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* + { + if ( addImagNode ) { + #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec); + } + } + ; + +// A builtin type specification is a builtin type with possible brackets +// afterwards (which would make it an array type). +builtInTypeSpec[boolean addImagNode] + : builtInType (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* + { + if ( addImagNode ) { + #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec); + } + } + ; + +// A type name. which is either a (possibly qualified) class name or +// a primitive (builtin) type +type + : identifier + | builtInType + ; + +// The primitive types. +builtInType + : "void" + | "boolean" + | "byte" + | "char" + | "short" + | "int" + | "float" + | "long" + | "double" + ; + +// A (possibly-qualified) java identifier. We start with the first IDENT +// and expand its name by adding dots and following IDENTS +identifier + : IDENT ( DOT^ IDENT )* + ; + +identifierStar + : IDENT + ( DOT^ IDENT )* + ( DOT^ STAR )? + ; + +// A list of zero or more modifiers. We could have used (modifier)* in +// place of a call to modifiers, but I thought it was a good idea to keep +// this rule separate so they can easily be collected in a Vector if +// someone so desires +modifiers + : ( modifier )* + {#modifiers = #([MODIFIERS, "MODIFIERS"], #modifiers);} + ; + +// modifiers for Java classes, interfaces, class/instance vars and methods +modifier + : "private" + | "public" + | "protected" + | "static" + | "transient" + | "final" + | "abstract" + | "native" + | "threadsafe" + | "synchronized" +// | "const" // reserved word, but not valid + | "volatile" + | "strictfp" + ; + +// Definition of a Java class +classDefinition![AST modifiers] + : "class" IDENT + // it _might_ have a superclass... + sc:superClassClause + // it might implement some interfaces... + ic:implementsClause + // now parse the body of the class + cb:classBlock + {#classDefinition = #(#[CLASS_DEF,"CLASS_DEF"], + modifiers,IDENT,sc,ic,cb);} + ; + +superClassClause! + : ( "extends" id:identifier )? + {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],id);} + ; + +// Definition of a Java Interface +interfaceDefinition![AST modifiers] + : "interface" IDENT + // it might extend some other interfaces + ie:interfaceExtends + // now parse the body of the interface (looks like a class...) + cb:classBlock + {#interfaceDefinition = #(#[INTERFACE_DEF,"INTERFACE_DEF"], + modifiers,IDENT,ie,cb);} + ; + + +// This is the body of a class. You can have fields and extra semicolons, +// That's about it (until you see what a field is...) +classBlock + : LCURLY! { blockDepth++; } + ( field | SEMI! )* + RCURLY! { blockDepth--; } + {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);} + ; + +// An interface can extend several other interfaces... +interfaceExtends + : ( + e:"extends"! + identifier ( COMMA! identifier )* + )? + {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"], + #interfaceExtends);} + ; + +// A class can implement several interfaces... +implementsClause + : ( + i:"implements"! identifier ( COMMA! identifier )* + )? + {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"], + #implementsClause);} + ; + +// Now the various things that can be defined inside a class or interface... +// Note that not all of these are really valid in an interface (constructors, +// for example), and if this grammar were used for a compiler there would +// need to be some semantic checks to make sure we're doing the right thing... +field! + : // method, constructor, or variable declaration + mods:modifiers + ( h:ctorHead s:constructorBody // constructor + {#field = #(#[CTOR_DEF,"CTOR_DEF"], mods, h, s);} + + | cd:classDefinition[#mods] // inner class + {#field = #cd;} + + | id:interfaceDefinition[#mods] // inner interface + {#field = #id;} + + | t:typeSpec[false] // method or variable declaration(s) + ( fn:IDENT // the name of the method + + // parse the formal parameter declarations. + LPAREN! param:parameterDeclarationList RPAREN! + + rt:declaratorBrackets[#t] + + // get the list of exceptions that this method is + // declared to throw + (tc:throwsClause)? + + ( s2:compoundStatement | SEMI ) + {#field = #(#[METHOD_DEF,"METHOD_DEF"], + mods, + #(#[TYPE,"TYPE"],rt), + fn, + param, + tc, + s2); + if(blockDepth==1) { + functionNames.add(fn.getText()); } } + | v:variableDefinitions[#mods,#t] SEMI +// {#field = #(#[VARIABLE_DEF,"VARIABLE_DEF"], v);} + {#field = #v;} + ) + ) + + // "static { ... }" class initializer + | "static" s3:compoundStatement + {#field = #(#[STATIC_INIT,"STATIC_INIT"], s3);} + + // "{ ... }" instance initializer + | s4:compoundStatement + {#field = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} + ; + +constructorBody + : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; } + ( options { greedy=true; } : explicitConstructorInvocation)? + (statement)* + RCURLY! { blockDepth--; } + ; + +/** Catch obvious constructor calls, but not the expr.super(...) calls */ +explicitConstructorInvocation + : "this"! lp1:LPAREN^ argList RPAREN! SEMI! + {#lp1.setType(CTOR_CALL);} + | "super"! lp2:LPAREN^ argList RPAREN! SEMI! + {#lp2.setType(SUPER_CTOR_CALL);} + ; + +variableDefinitions[AST mods, AST t] + : variableDeclarator[getASTFactory().dupTree(mods), + getASTFactory().dupTree(t)] + ( COMMA! + variableDeclarator[getASTFactory().dupTree(mods), + getASTFactory().dupTree(t)] + )* + ; + +/** Declaration of a variable. This can be a class/instance variable, + * or a local variable in a method + * It can also include possible initialization. + */ +variableDeclarator![AST mods, AST t] + : id:IDENT d:declaratorBrackets[t] v:varInitializer + {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],d), id, v); + if(blockDepth==1) { + enumNames.add(id.getText()); + } + } + ; + +declaratorBrackets[AST typ] + : {#declaratorBrackets=typ;} + (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* + ; + +varInitializer + : ( ASSIGN^ initializer )? + ; + +// This is an initializer used to set up an array. +arrayInitializer + : lc:LCURLY^ {#lc.setType(ARRAY_INIT); blockDepth++; } + ( initializer + ( + // CONFLICT: does a COMMA after an initializer start a new + // initializer or start the option ',' at end? + // ANTLR generates proper code by matching + // the comma as soon as possible. + options { + warnWhenFollowAmbig = false; + } + : + COMMA! initializer + )* + (COMMA!)? + )? + RCURLY! { blockDepth--; } + ; + + +// The two "things" that can initialize an array element are an expression +// and another (nested) array initializer. +initializer + : expression + | arrayInitializer + ; + +// This is the header of a method. It includes the name and parameters +// for the method. +// This also watches for a list of exception classes in a "throws" clause. +ctorHead + : IDENT // the name of the method + + // parse the formal parameter declarations. + LPAREN! parameterDeclarationList RPAREN! + + // get the list of exceptions that this method is declared to throw + (throwsClause)? + ; + +// This is a list of exception classes that the method is declared to throw +throwsClause + : "throws"^ identifier ( COMMA! identifier )* + ; + + +// A list of formal parameters +parameterDeclarationList + : ( parameterDeclaration ( COMMA! parameterDeclaration )* )? + {#parameterDeclarationList = #(#[PARAMETERS,"PARAMETERS"], + #parameterDeclarationList);} + ; + +// A formal parameter. +parameterDeclaration! + : pm:parameterModifier t:typeSpec[false] id:IDENT + pd:declaratorBrackets[#t] + {#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"], + pm, #([TYPE,"TYPE"],pd), id);} + ; + +parameterModifier + : (f:"final")? + {#parameterModifier = #(#[MODIFIERS,"MODIFIERS"], f);} + ; + +// Compound statement. This is used in many contexts: +// Inside a class definition prefixed with "static": +// it is a class initializer +// Inside a class definition without "static": +// it is an instance initializer +// As the body of a method +// As a completely indepdent braced block of code inside a method +// it starts a new scope for variable definitions + +compoundStatement + : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; } + // include the (possibly-empty) list of statements + (statement)* + RCURLY! { blockDepth--; } + ; + + +statement + // A list of statements in curly braces -- start a new scope! + : compoundStatement + + // declarations are ambiguous with "ID DOT" relative to expression + // statements. Must backtrack to be sure. Could use a semantic + // predicate to test symbol table to see what the type was coming + // up, but that's pretty hard without a symbol table ;) + | (declaration)=> declaration SEMI! + + // An expression statement. This could be a method call, + // assignment statement, or any other expression evaluated for + // side-effects. + | expression SEMI! + + // class definition + | m:modifiers! classDefinition[#m] + + // Attach a label to the front of a statement + | IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement + + // If-else statement + | "if"^ LPAREN! expression RPAREN! statement + ( + // CONFLICT: the old "dangling-else" problem... + // ANTLR generates proper code matching + // as soon as possible. Hush warning. + options { + warnWhenFollowAmbig = false; + } + : + "else"! statement + )? + + // For statement + | "for"^ + LPAREN! + forInit SEMI! // initializer + forCond SEMI! // condition test + forIter // updater + RPAREN! + statement // statement to loop over + + // While statement + | "while"^ LPAREN! expression RPAREN! statement + + // do-while statement + | "do"^ statement "while"! LPAREN! expression RPAREN! SEMI! + + // get out of a loop (or switch) + | "break"^ (IDENT)? SEMI! + + // do next iteration of a loop + | "continue"^ (IDENT)? SEMI! + + // Return an expression + | "return"^ (expression)? SEMI! + + // switch/case statement + | "switch"^ LPAREN! expression RPAREN! LCURLY! { blockDepth++; } + ( casesGroup )* + RCURLY! { blockDepth--; } + + // exception try-catch block + | tryBlock + + // throw an exception + | "throw"^ expression SEMI! + + // synchronize a statement + | "synchronized"^ LPAREN! expression RPAREN! compoundStatement + + // asserts (uncomment if you want 1.4 compatibility) + // | "assert"^ expression ( COLON! expression )? SEMI! + + // empty statement + | s:SEMI {#s.setType(EMPTY_STAT);} + ; + +casesGroup + : ( // CONFLICT: to which case group do the statements bind? + // ANTLR generates proper code: it groups the + // many "case"/"default" labels together then + // follows them with the statements + options { + greedy = true; + } + : + aCase + )+ + caseSList + {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);} + ; + +aCase + : ("case"^ expression | "default") COLON! + ; + +caseSList + : (statement)* + {#caseSList = #(#[SLIST,"SLIST"],#caseSList);} + ; + +// The initializer for a for loop +forInit + // if it looks like a declaration, it is + : ( (declaration)=> declaration + // otherwise it could be an expression list... + | expressionList + )? + {#forInit = #(#[FOR_INIT,"FOR_INIT"],#forInit);} + ; + +forCond + : (expression)? + {#forCond = #(#[FOR_CONDITION,"FOR_CONDITION"],#forCond);} + ; + +forIter + : (expressionList)? + {#forIter = #(#[FOR_ITERATOR,"FOR_ITERATOR"],#forIter);} + ; + +// an exception handler try/catch block +tryBlock + : "try"^ compoundStatement + (handler)* + ( finallyClause )? + ; + +finallyClause + : "finally"^ compoundStatement + ; + +// an exception handler +handler + : "catch"^ LPAREN! parameterDeclaration RPAREN! compoundStatement + ; + + +// expressions +// Note that most of these expressions follow the pattern +// thisLevelExpression : +// nextHigherPrecedenceExpression +// (OPERATOR nextHigherPrecedenceExpression)* +// which is a standard recursive definition for a parsing an expression. +// The operators in java have the following precedences: +// lowest (13) = *= /= %= += -= <<= >>= >>>= &= ^= |= +// (12) ?: +// (11) || +// (10) && +// ( 9) | +// ( 8) ^ +// ( 7) & +// ( 6) == != +// ( 5) < <= > >= +// ( 4) << >> +// ( 3) +(binary) -(binary) +// ( 2) * / % +// ( 1) ++ -- +(unary) -(unary) ~ ! (type) +// [] () (method call) . (dot -- identifier qualification) +// new () (explicit parenthesis) +// +// the last two are not usually on a precedence chart; I put them in +// to point out that new has a higher precedence than '.', so you +// can validy use +// new Frame().show() +// +// Note that the above precedence levels map to the rules below... +// Once you have a precedence chart, writing the appropriate rules as below +// is usually very straightfoward + + + +// the mother of all expressions +expression + : assignmentExpression + {#expression = #(#[EXPR,"EXPR"],#expression);} + ; + + +// This is a list of expressions. +expressionList + : expression (COMMA! expression)* + {#expressionList = #(#[ELIST,"ELIST"], expressionList);} + ; + + +// assignment expression (level 13) +assignmentExpression + : conditionalExpression + ( ( ASSIGN^ + | PLUS_ASSIGN^ + | MINUS_ASSIGN^ + | STAR_ASSIGN^ + | DIV_ASSIGN^ + | MOD_ASSIGN^ + | SR_ASSIGN^ + | BSR_ASSIGN^ + | SL_ASSIGN^ + | BAND_ASSIGN^ + | BXOR_ASSIGN^ + | BOR_ASSIGN^ + ) + assignmentExpression + )? + ; + + +// conditional test (level 12) +conditionalExpression + : logicalOrExpression + ( QUESTION^ assignmentExpression COLON! conditionalExpression )? + ; + + +// logical or (||) (level 11) +logicalOrExpression + : logicalAndExpression (LOR^ logicalAndExpression)* + ; + + +// logical and (&&) (level 10) +logicalAndExpression + : inclusiveOrExpression (LAND^ inclusiveOrExpression)* + ; + + +// bitwise or non-short-circuiting or (|) (level 9) +inclusiveOrExpression + : exclusiveOrExpression (BOR^ exclusiveOrExpression)* + ; + + +// exclusive or (^) (level 8) +exclusiveOrExpression + : andExpression (BXOR^ andExpression)* + ; + + +// bitwise or non-short-circuiting and (&) (level 7) +andExpression + : equalityExpression (BAND^ equalityExpression)* + ; + + +// equality/inequality (==/!=) (level 6) +equalityExpression + : relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)* + ; + + +// boolean relational expressions (level 5) +relationalExpression + : shiftExpression + ( ( ( LT^ + | GT^ + | LE^ + | GE^ + ) + shiftExpression + )* + | "instanceof"^ typeSpec[true] + ) + ; + + +// bit shift expressions (level 4) +shiftExpression + : additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)* + ; + + +// binary addition/subtraction (level 3) +additiveExpression + : multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)* + ; + + +// multiplication/division/modulo (level 2) +multiplicativeExpression + : unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)* + ; + +unaryExpression + : INC^ unaryExpression + | DEC^ unaryExpression + | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression + | PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression + | unaryExpressionNotPlusMinus + ; + +unaryExpressionNotPlusMinus + : BNOT^ unaryExpression + | LNOT^ unaryExpression + + // use predicate to skip cases like: (int.class) + | (LPAREN builtInTypeSpec[true] RPAREN) => + lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN! + unaryExpression + + // Have to backtrack to see if operator follows. If no operator + // follows, it's a typecast. No semantic checking needed to parse. + // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)" + | (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=> + lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN! + unaryExpressionNotPlusMinus + + | postfixExpression + ; + +// qualified names, array expressions, method invocation, post inc/dec +postfixExpression + : + /* + "this"! lp1:LPAREN^ argList RPAREN! + {#lp1.setType(CTOR_CALL);} + + | "super"! lp2:LPAREN^ argList RPAREN! + {#lp2.setType(SUPER_CTOR_CALL);} + | + */ + primaryExpression + + ( + /* + options { + // the use of postfixExpression in SUPER_CTOR_CALL adds DOT + // to the lookahead set, and gives loads of false non-det + // warnings. + // shut them off. + generateAmbigWarnings=false; + } + : */ + DOT^ IDENT + ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} + argList + RPAREN! + )? + | DOT^ "this" + + | DOT^ "super" + ( // (new Outer()).super() (create enclosing instance) + lp3:LPAREN^ argList RPAREN! + {#lp3.setType(SUPER_CTOR_CALL);} + | DOT^ IDENT + ( lps:LPAREN^ {#lps.setType(METHOD_CALL);} + argList + RPAREN! + )? + ) + | DOT^ newExpression + | lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK! + )* + + ( // possibly add on a post-increment or post-decrement. + // allows INC/DEC on too much, but semantics can check + in:INC^ {#in.setType(POST_INC);} + | de:DEC^ {#de.setType(POST_DEC);} + )? + ; + +// the basic element of an expression +primaryExpression + : identPrimary ( options {greedy=true;} : DOT^ "class" )? + | constant + | "true" + | "false" + | "null" + | newExpression + | "this" + | "super" + | LPAREN! assignmentExpression RPAREN! + // look for int.class and int[].class + | builtInType + ( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )* + DOT^ "class" + ; + +/** Match a, a.b.c refs, a.b.c(...) refs, a.b.c[], a.b.c[].class, + * and a.b.c.class refs. Also this(...) and super(...). Match + * this or super. + */ +identPrimary + : IDENT + ( + options { + // .ident could match here or in postfixExpression. + // We do want to match here. Turn off warning. + greedy=true; + } + : DOT^ IDENT + )* + ( + options { + // ARRAY_DECLARATOR here conflicts with INDEX_OP in + // postfixExpression on LBRACK RBRACK. + // We want to match [] here, so greedy. This overcomes + // limitation of linear approximate lookahead. + greedy=true; + } + : ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} argList RPAREN! ) + | ( options {greedy=true;} : + lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! + )+ + )? + ; + +/** object instantiation. + * Trees are built as illustrated by the following input/tree pairs: + * + * new T() + * + * new + * | + * T -- ELIST + * | + * arg1 -- arg2 -- .. -- argn + * + * new int[] + * + * new + * | + * int -- ARRAY_DECLARATOR + * + * new int[] {1,2} + * + * new + * | + * int -- ARRAY_DECLARATOR -- ARRAY_INIT + * | + * EXPR -- EXPR + * | | + * 1 2 + * + * new int[3] + * new + * | + * int -- ARRAY_DECLARATOR + * | + * EXPR + * | + * 3 + * + * new int[1][2] + * + * new + * | + * int -- ARRAY_DECLARATOR + * | + * ARRAY_DECLARATOR -- EXPR + * | | + * EXPR 1 + * | + * 2 + * + */ +newExpression + : "new"^ type + ( LPAREN! argList RPAREN! (classBlock)? + + //java 1.1 + // Note: This will allow bad constructs like + // new int[4][][3] {exp,exp}. + // There needs to be a semantic check here... + // to make sure: + // a) [ expr ] and [ ] are not mixed + // b) [ expr ] and an init are not used together + + | newArrayDeclarator (arrayInitializer)? + ) + ; + +argList + : ( expressionList + | /*nothing*/ + {#argList = #[ELIST,"ELIST"];} + ) + ; + +newArrayDeclarator + : ( + // CONFLICT: + // newExpression is a primaryExpression which can be + // followed by an array index reference. This is ok, + // as the generated code will stay in this loop as + // long as it sees an LBRACK (proper behavior) + options { + warnWhenFollowAmbig = false; + } + : + lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} + (expression)? + RBRACK! + )+ + ; + +constant + : NUM_INT + | CHAR_LITERAL + | STRING_LITERAL + | NUM_FLOAT + | NUM_LONG + | NUM_DOUBLE + ; + +//---------------------------------------------------------------------------- +// The Java scanner +//---------------------------------------------------------------------------- +class JavaLexer extends Lexer; + +options { + exportVocab=Java; // call the vocabulary "Java" + testLiterals=false; // don't automatically test for literals + k=4; // four characters of lookahead + charVocabulary='\u0003'..'\u7FFE'; + // without inlining some bitset tests, couldn't do unicode; + // I need to make ANTLR generate smaller bitsets; see + // bottom of JavaLexer.java + codeGenBitsetTestThreshold=20; +} + +// OPERATORS +QUESTION : '?' ; +LPAREN : '(' ; +RPAREN : ')' ; +LBRACK : '[' ; +RBRACK : ']' ; +LCURLY : '{' ; +RCURLY : '}' ; +COLON : ':' ; +COMMA : ',' ; +//DOT : '.' ; +ASSIGN : '=' ; +EQUAL : "==" ; +LNOT : '!' ; +BNOT : '~' ; +NOT_EQUAL : "!=" ; +DIV : '/' ; +DIV_ASSIGN : "/=" ; +PLUS : '+' ; +PLUS_ASSIGN : "+=" ; +INC : "++" ; +MINUS : '-' ; +MINUS_ASSIGN : "-=" ; +DEC : "--" ; +STAR : '*' ; +STAR_ASSIGN : "*=" ; +MOD : '%' ; +MOD_ASSIGN : "%=" ; +SR : ">>" ; +SR_ASSIGN : ">>=" ; +BSR : ">>>" ; +BSR_ASSIGN : ">>>=" ; +GE : ">=" ; +GT : ">" ; +SL : "<<" ; +SL_ASSIGN : "<<=" ; +LE : "<=" ; +LT : '<' ; +BXOR : '^' ; +BXOR_ASSIGN : "^=" ; +BOR : '|' ; +BOR_ASSIGN : "|=" ; +LOR : "||" ; +BAND : '&' ; +BAND_ASSIGN : "&=" ; +LAND : "&&" ; +SEMI : ';' ; + + +// Whitespace -- ignored +WS : ( ' ' + | '\t' + | '\f' + // handle newlines + | ( options {generateAmbigWarnings=false;} + : "\r\n" // Evil DOS + | '\r' // Macintosh + | '\n' // Unix (the right way) + ) + { newline(); } + )+ + { _ttype = Token.SKIP; } + ; + +// Single-line comments +SL_COMMENT + : "//" + (~('\n'|'\r'))* ('\n'|'\r'('\n')?)? + {$setType(Token.SKIP); newline();} + ; + +// multiple-line comments +ML_COMMENT + : "/*" + ( /* '\r' '\n' can be matched in one alternative or by matching + '\r' in one iteration and '\n' in another. I am trying to + handle any flavor of newline that comes in, but the language + that allows both "\r\n" and "\r" and "\n" to all be valid + newline is ambiguous. Consequently, the resulting grammar + must be ambiguous. I'm shutting this warning off. + */ + options { + generateAmbigWarnings=false; + } + : + { LA(2)!='/' }? '*' + | '\r' '\n' {newline();} + | '\r' {newline();} + | '\n' {newline();} + | ~('*'|'\n'|'\r') + )* + "*/" + {$setType(Token.SKIP);} + ; + + +// character literals +CHAR_LITERAL + : '\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\'' + ; + +// string literals +STRING_LITERAL + : '"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"' + ; + + +// escape sequence -- note that this is protected; it can only be called +// from another lexer rule -- it will not ever directly return a token to +// the parser +// There are various ambiguities hushed in this rule. The optional +// '0'...'9' digit matches should be matched here rather than letting +// them go back to STRING_LITERAL to be matched. ANTLR does the +// right thing by matching immediately; hence, it's ok to shut off +// the FOLLOW ambig warnings. +protected +ESC + : '\\' + ( 'n' + | 'r' + | 't' + | 'b' + | 'f' + | '"' + | '\'' + | '\\' + | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT + | '0'..'3' + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + )? + )? + | '4'..'7' + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + )? + ) + ; + + +// hexadecimal digit (again, note it's protected!) +protected +HEX_DIGIT + : ('0'..'9'|'A'..'F'|'a'..'f') + ; + + +// an identifier. Note that testLiterals is set to true! This means +// that after we match the rule, we look in the literals table to see +// if it's a literal or really an identifer +IDENT + options {testLiterals=true;} + : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* + ; + + +// a numeric literal +NUM_INT + {boolean isDecimal=false; Token t=null;} + : '.' {_ttype = DOT;} + ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})? + { + if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { + _ttype = NUM_FLOAT; + } + else { + _ttype = NUM_DOUBLE; // assume double + } + } + )? + + | ( '0' {isDecimal = true;} // special case for just '0' + ( ('x'|'X') + ( // hex + // the 'e'|'E' and float suffix stuff look + // like hex digits, hence the (...)+ doesn't + // know when to stop: ambig. ANTLR resolves + // it correctly by matching immediately. It + // is therefor ok to hush warning. + options { + warnWhenFollowAmbig=false; + } + : HEX_DIGIT + )+ + + | //float or double with leading zero + (('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+ + + | ('0'..'7')+ // octal + )? + | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal + ) + ( ('l'|'L') { _ttype = NUM_LONG; } + + // only check to see if it's a float if looks like decimal so far + | {isDecimal}? + ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})? + | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})? + | f4:FLOAT_SUFFIX {t=f4;} + ) + { + if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { + _ttype = NUM_FLOAT; + } + else { + _ttype = NUM_DOUBLE; // assume double + } + } + )? + ; + + +// a couple protected methods to assist in matching floating point numbers +protected +EXPONENT + : ('e'|'E') ('+'|'-')? ('0'..'9')+ + ; + + +protected +FLOAT_SUFFIX + : 'f'|'F'|'d'|'D' + ; + -- cgit v1.2.3 From d6a5fa9169cc3f7abdb7a23068ddd76f632eec26 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 31 May 2014 15:08:25 -0700 Subject: gluegen: remove some unused imports Signed-off-by: Harvey Harrison --- src/java/com/jogamp/gluegen/DebugEmitter.java | 1 - src/java/com/jogamp/gluegen/GlueEmitter.java | 1 - src/java/com/jogamp/gluegen/cgram/CToken.java | 2 -- src/java/com/jogamp/gluegen/cgram/TNodeFactory.java | 1 - .../jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java | 1 - 5 files changed, 6 deletions(-) (limited to 'src/java') diff --git a/src/java/com/jogamp/gluegen/DebugEmitter.java b/src/java/com/jogamp/gluegen/DebugEmitter.java index 781188e..8773f1b 100644 --- a/src/java/com/jogamp/gluegen/DebugEmitter.java +++ b/src/java/com/jogamp/gluegen/DebugEmitter.java @@ -41,7 +41,6 @@ package com.jogamp.gluegen; import java.util.*; -import com.jogamp.common.os.MachineDescription; import com.jogamp.gluegen.cgram.types.*; /** Debug emitter which prints the parsing results to standard output. */ diff --git a/src/java/com/jogamp/gluegen/GlueEmitter.java b/src/java/com/jogamp/gluegen/GlueEmitter.java index bd5a7f3..bb46cf5 100644 --- a/src/java/com/jogamp/gluegen/GlueEmitter.java +++ b/src/java/com/jogamp/gluegen/GlueEmitter.java @@ -41,7 +41,6 @@ package com.jogamp.gluegen; import java.util.*; -import com.jogamp.common.os.MachineDescription; import com.jogamp.gluegen.cgram.types.*; /** Specifies the interface by which GlueGen requests glue code to be diff --git a/src/java/com/jogamp/gluegen/cgram/CToken.java b/src/java/com/jogamp/gluegen/cgram/CToken.java index cfa88fc..78fc7f7 100644 --- a/src/java/com/jogamp/gluegen/cgram/CToken.java +++ b/src/java/com/jogamp/gluegen/cgram/CToken.java @@ -1,7 +1,5 @@ package com.jogamp.gluegen.cgram; -import antlr.CommonToken; - public class CToken extends antlr.CommonToken { String source = ""; int tokenNumber; diff --git a/src/java/com/jogamp/gluegen/cgram/TNodeFactory.java b/src/java/com/jogamp/gluegen/cgram/TNodeFactory.java index ccbd233..ff2f1b0 100644 --- a/src/java/com/jogamp/gluegen/cgram/TNodeFactory.java +++ b/src/java/com/jogamp/gluegen/cgram/TNodeFactory.java @@ -1,6 +1,5 @@ package com.jogamp.gluegen.cgram; -import antlr.Token; import antlr.ASTFactory; import antlr.collections.AST; diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java index 236627c..f28c50d 100644 --- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java @@ -42,7 +42,6 @@ import com.jogamp.gluegen.MethodBinding; import com.jogamp.gluegen.FunctionEmitter; import com.jogamp.gluegen.JavaMethodBindingEmitter; import java.io.*; -import com.jogamp.gluegen.*; /** A specialization of JavaMethodBindingEmitter with knowledge of how to call through a function pointer. */ -- cgit v1.2.3 From 5d802fb8dd4004039d4597253712d24fffb90a36 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 31 May 2014 15:08:41 -0700 Subject: gluegen: update HeaderParser grammar to annotation EnumType map and functions list Signed-off-by: Harvey Harrison --- src/java/com/jogamp/gluegen/GlueGen.java | 3 +-- .../antlr/com/jogamp/gluegen/cgram/HeaderParser.g | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src/java') diff --git a/src/java/com/jogamp/gluegen/GlueGen.java b/src/java/com/jogamp/gluegen/GlueGen.java index 54e510d..891878b 100644 --- a/src/java/com/jogamp/gluegen/GlueGen.java +++ b/src/java/com/jogamp/gluegen/GlueGen.java @@ -190,8 +190,7 @@ public class GlueGen implements GlueEmitterControls { // Repackage the enum and #define statements from the parser into a common format // so that SymbolFilters can operate upon both identically constants = new ArrayList(); - for (Object elem : headerParser.getEnums()) { - EnumType enumeration = (EnumType) elem; + for (EnumType enumeration : headerParser.getEnums()) { String enumName = enumeration.getName(); if (enumName.equals("")) { enumName = null; diff --git a/src/main/antlr/com/jogamp/gluegen/cgram/HeaderParser.g b/src/main/antlr/com/jogamp/gluegen/cgram/HeaderParser.g index 0b4d5ec..75cf413 100644 --- a/src/main/antlr/com/jogamp/gluegen/cgram/HeaderParser.g +++ b/src/main/antlr/com/jogamp/gluegen/cgram/HeaderParser.g @@ -100,7 +100,7 @@ options { /** Pre-define the list of EnumTypes for this HeaderParser. Must be done before parsing. */ - public void setEnums(List/**/ enumTypes) { + public void setEnums(List enumTypes) { // FIXME: Need to take the input set of EnumTypes, extract all // the enumerates from each EnumType, and fill in the enumHash // so that each enumerate maps to the enumType to which it @@ -109,8 +109,8 @@ options { } /** Returns the EnumTypes this HeaderParser processed. */ - public List/**/ getEnums() { - return new ArrayList(enumHash.values()); + public List getEnums() { + return new ArrayList(enumHash.values()); } /** Clears the list of functions this HeaderParser has parsed. @@ -121,7 +121,7 @@ options { } /** Returns the list of FunctionSymbols this HeaderParser has parsed. */ - public List getParsedFunctions() { + public List getParsedFunctions() { return functions; } @@ -241,9 +241,9 @@ options { private List parameters; private TypeDictionary typedefDictionary; private TypeDictionary structDictionary; - private List/**/ functions = new ArrayList(); + private List functions = new ArrayList(); // hash from name of an enumerated value to the EnumType to which it belongs - private HashMap/**/ enumHash = new HashMap(); + private HashMap enumHash = new HashMap(); // Storage class specifiers private static final int AUTO = 1 << 0; @@ -317,9 +317,9 @@ options { returns an existing one if it has already been created. */ private EnumType getEnumType(String enumTypeName) { EnumType enumType = null; - Iterator it = enumHash.values().iterator(); + Iterator it = enumHash.values().iterator(); while (it.hasNext()) { - EnumType potentialMatch = (EnumType)it.next(); + EnumType potentialMatch = it.next(); if (potentialMatch.getName().equals(enumTypeName)) { enumType = potentialMatch; break; @@ -652,7 +652,7 @@ enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValu if (eVal != null) { String vTxt = eVal.getAllChildrenText(); if (enumHash.containsKey(vTxt)) { - EnumType oldEnumType = (EnumType) enumHash.get(vTxt); + EnumType oldEnumType = enumHash.get(vTxt); value = oldEnumType.getEnumValue(vTxt); } else { try { @@ -669,7 +669,7 @@ enumerator[EnumType enumeration, long defaultValue] returns [long newDefaultValu newDefaultValue = value+1; String eTxt = eName.getText(); if (enumHash.containsKey(eTxt)) { - EnumType oldEnumType = (EnumType) enumHash.get(eTxt); + EnumType oldEnumType = enumHash.get(eTxt); long oldValue = oldEnumType.getEnumValue(eTxt); System.err.println("WARNING: redefinition of enumerated value '" + eTxt + "';" + " existing definition is in enumeration '" + oldEnumType.getName() + -- cgit v1.2.3