📄 groovy.g
字号:
// Note: Please don't use physical tabs. Logical tabs for indent are width 4.
header {
package org.codehaus.groovy.antlr.parser;
import org.codehaus.groovy.antlr.*;
import java.util.*;
import java.io.InputStream;
import java.io.Reader;
import antlr.InputBuffer;
import antlr.LexerSharedInputState;
}
/** JSR-241 Groovy Recognizer
*
* Run 'java Main [-showtree] directory-full-of-groovy-files'
*
* [The -showtree option pops up a Swing frame that shows
* the AST constructed from the parser.]
*
* 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
* James Strachan jstrachan@protique.com
* John Pybus john@pybus.org
* John Rose rose00@mac.com
* Jeremy Rayner groovy@ross-rayner.com
*
* 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.21.2 (March, 2003)
* Changes by Matt Quail to support generics (as per JDK1.5/JSR14)
* Notes:
* o We only allow the "extends" keyword and not the "implements"
* keyword, since thats what JSR14 seems to imply.
* o Thanks to Monty Zukowski for his help on the antlr-interest
* mail list.
* o Thanks to Alan Eliasen for testing the grammar over his
* Fink source base
*
* Version 1.22 (July, 2004)
* Changes by Michael Studman to support Java 1.5 language extensions
* Notes:
* o Added support for annotations types
* o Finished off Matt Quail's generics enhancements to support bound type arguments
* o Added support for new for statement syntax
* o Added support for static import syntax
* o Added support for enum types
* o Tested against JDK 1.5 source base and source base of jdigraph project
* o Thanks to Matt Quail for doing the hard part by doing most of the generics work
*
* Version 1.22.1 (July 28, 2004)
* Bug/omission fixes for Java 1.5 language support
* o Fixed tree structure bug with classOrInterface - thanks to Pieter Vangorpto for
* spotting this
* o Fixed bug where incorrect handling of SR and BSR tokens would cause type
* parameters to be recognised as type arguments.
* o Enabled type parameters on constructors, annotations on enum constants
* and package definitions
* o Fixed problems when parsing if ((char.class.equals(c))) {} - solution by Matt Quail at Cenqua
*
* Version 1.22.2 (July 28, 2004)
* Slight refactoring of Java 1.5 language support
* o Refactored for/"foreach" productions so that original literal "for" literal
* is still used but the for sub-clauses vary by token type
* o Fixed bug where type parameter was not included in generic constructor's branch of AST
*
* Version 1.22.3 (August 26, 2004)
* Bug fixes as identified by Michael Stahl; clean up of tabs/spaces
* and other refactorings
* o Fixed typeParameters omission in identPrimary and newStatement
* o Replaced GT reconcilliation code with simple semantic predicate
* o Adapted enum/assert keyword checking support from Michael Stahl's java15 grammar
* o Refactored typeDefinition production and field productions to reduce duplication
*
* Version 1.22.4 (October 21, 2004)
* Small bux fixes
* o Added typeArguments to explicitConstructorInvocation, e.g. new <String>MyParameterised()
* o Added typeArguments to postfixExpression productions for anonymous inner class super
* constructor invocation, e.g. new Outer().<String>super()
* o Fixed bug in array declarations identified by Geoff Roy
*
* Version 1.22.4.g.1
* o I have taken java.g for Java1.5 from Michael Studman (1.22.4)
* and have applied the groovy.diff from java.g (1.22) by John Rose
* back onto the new root (1.22.4) - Jeremy Rayner (Jan 2005)
* o for a map of the task see...
* http://groovy.javanicus.com/java-g.png
*
* This grammar is in the PUBLIC DOMAIN
*/
class GroovyRecognizer extends Parser;
options {
k = 3; // three token lookahead
exportVocab=Groovy; // Call its vocabulary "Groovy"
codeGenMakeSwitchThreshold = 2; // Some optimizations
codeGenBitsetTestThreshold = 3;
defaultErrorHandler = false; // Don't generate parser error handlers
buildAST = true;
// ASTLabelType = "GroovyAST";
}
tokens {
BLOCK; MODIFIERS; OBJBLOCK; SLIST; 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;
IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION;
FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract";
UNUSED_GOTO="goto"; UNUSED_CONST="const"; UNUSED_DO="do";
STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; CTOR_IDENT; VARIABLE_PARAMETER_DEF;
STRING_CONSTRUCTOR; STRING_CTOR_MIDDLE;
CLOSABLE_BLOCK; IMPLICIT_PARAMETERS;
SELECT_SLOT; DYNAMIC_MEMBER;
LABELED_ARG; SPREAD_ARG; SPREAD_MAP_ARG; SCOPE_ESCAPE;
LIST_CONSTRUCTOR; MAP_CONSTRUCTOR;
FOR_IN_ITERABLE;
STATIC_IMPORT; ENUM_DEF; ENUM_CONSTANT_DEF; FOR_EACH_CLAUSE; ANNOTATION_DEF; ANNOTATIONS;
ANNOTATION; ANNOTATION_MEMBER_VALUE_PAIR; ANNOTATION_FIELD_DEF; ANNOTATION_ARRAY_INIT;
TYPE_ARGUMENTS; TYPE_ARGUMENT; TYPE_PARAMETERS; TYPE_PARAMETER; WILDCARD_TYPE;
TYPE_UPPER_BOUNDS; TYPE_LOWER_BOUNDS;
}
{
/** This factory is the correct way to wire together a Groovy parser and lexer. */
public static GroovyRecognizer make(GroovyLexer lexer) {
GroovyRecognizer parser = new GroovyRecognizer(lexer.plumb());
// TODO: set up a common error-handling control block, to avoid excessive tangle between these guys
parser.lexer = lexer;
lexer.parser = parser;
parser.setASTNodeClass("org.codehaus.groovy.antlr.GroovySourceAST");
parser.warningList = new ArrayList();
return parser;
}
// Create a scanner that reads from the input stream passed to us...
public static GroovyRecognizer make(InputStream in) { return make(new GroovyLexer(in)); }
public static GroovyRecognizer make(Reader in) { return make(new GroovyLexer(in)); }
public static GroovyRecognizer make(InputBuffer in) { return make(new GroovyLexer(in)); }
public static GroovyRecognizer make(LexerSharedInputState in) { return make(new GroovyLexer(in)); }
private static GroovySourceAST dummyVariableToforceClassLoaderToFindASTClass = new GroovySourceAST();
List warningList;
public List getWarningList() { return warningList; }
GroovyLexer lexer;
public GroovyLexer getLexer() { return lexer; }
public void setFilename(String f) { super.setFilename(f); lexer.setFilename(f); }
private SourceBuffer sourceBuffer;
public void setSourceBuffer(SourceBuffer sourceBuffer) {
this.sourceBuffer = sourceBuffer;
}
/** Create an AST node with the token type and text passed in, but
* with the same background information as another supplied Token (e.g. line numbers)
* to be used in place of antlr tree construction syntax,
* i.e. #[TOKEN,"text"] becomes create(TOKEN,"text",anotherToken)
*
* todo - change antlr.ASTFactory to do this instead...
*/
public AST create(int type, String txt, Token first, Token last) {
AST t = astFactory.create(type,txt);
if ( t != null && first != null) {
// first copy details from first token
t.initialize(first);
// then ensure that type and txt are specific to this new node
t.initialize(type,txt);
}
if ((t instanceof GroovySourceAST) && last != null) {
GroovySourceAST node = (GroovySourceAST)t;
node.setLast(last);
// This is a good point to call node.setSnippet(),
// but it bulks up the AST too much for production code.
}
return t;
}
// stuff to adjust ANTLR's tracing machinery
public static boolean tracing = false; // only effective if antlr.Tool is run with -traceParser
public void traceIn(String rname) throws TokenStreamException {
if (!GroovyRecognizer.tracing) return;
super.traceIn(rname);
}
public void traceOut(String rname) throws TokenStreamException {
if (!GroovyRecognizer.tracing) return;
if (returnAST != null) rname += returnAST.toStringList();
super.traceOut(rname);
}
// Error handling. This is a funnel through which parser errors go, when the parser can suggest a solution.
public void requireFailed(String problem, String solution) throws SemanticException {
// TODO: Needs more work.
Token lt = null;
try { lt = LT(1); }
catch (TokenStreamException ee) { }
if (lt == null) lt = Token.badToken;
throw new SemanticException(problem + ";\n solution: " + solution,
getFilename(), lt.getLine(), lt.getColumn());
}
public void addWarning(String warning, String solution) {
Token lt = null;
try { lt = LT(1); }
catch (TokenStreamException ee) { }
if (lt == null) lt = Token.badToken;
Map row = new HashMap();
row.put("warning" ,warning);
row.put("solution",solution);
row.put("filename",getFilename());
row.put("line" ,new Integer(lt.getLine()));
row.put("column" ,new Integer(lt.getColumn()));
// System.out.println(row);
warningList.add(row);
}
// Convenience method for checking of expected error syndromes.
private void require(boolean z, String problem, String solution) throws SemanticException {
if (!z) requireFailed(problem, solution);
}
// Query a name token to see if it begins with a capital letter.
// This is used to tell the difference (w/o symbol table access) between {String x} and {println x}.
private boolean isUpperCase(Token x) {
if (x == null || x.getType() != IDENT) return false; // cannot happen?
String xtext = x.getText();
return (xtext.length() > 0 && Character.isUpperCase(xtext.charAt(0)));
}
private AST currentClass = null; // current enclosing class (for constructor recognition)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -