groovyrecognizer.java
来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 2,284 行 · 第 1/5 页
JAVA
2,284 行
// $ANTLR 2.7.2: "groovy.g" -> "GroovyRecognizer.java"$
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;
import antlr.TokenBuffer;import antlr.TokenStreamException;import antlr.TokenStreamIOException;import antlr.ANTLRException;import antlr.LLkParser;import antlr.Token;import antlr.TokenStream;import antlr.RecognitionException;import antlr.NoViableAltException;import antlr.MismatchedTokenException;import antlr.SemanticException;import antlr.ParserSharedInputState;import antlr.collections.impl.BitSet;import antlr.collections.AST;import java.util.Hashtable;import antlr.ASTFactory;import antlr.ASTPair;import antlr.collections.impl.ASTArray;/** 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
*/public class GroovyRecognizer extends antlr.LLkParser implements GroovyTokenTypes {
/** 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)
// Query a name token to see if it is identical with the current class name.
// This is used to distinguish constructors from other methods.
private boolean isConstructorIdent(Token x) {
if (currentClass == null) return false;
if (currentClass.getType() != IDENT) return false; // cannot happen?
String cname = currentClass.getText();
if (x == null || x.getType() != IDENT) return false; // cannot happen?
return cname.equals(x.getText());
}
// Scratch variable for last 'sep' token.
// Written by the 'sep' rule, read only by immediate callers of 'sep'.
// (Not entirely clean, but better than a million xx=sep occurrences.)
private int sepToken = EOF;
// Scratch variable for last argument list; tells whether there was a label.
// Written by 'argList' rule, read only by immediate callers of 'argList'.
private boolean argListHasLabels = false;
// Scratch variable, holds most recently completed pathExpression.
// Read only by immediate callers of 'pathExpression' and 'expression'.
private AST lastPathExpression = null;
// Inherited attribute pushed into most expression rules.
// If not zero, it means that the left context of the expression
// being parsed is a statement boundary or an initializer sign '='.
// Only such expressions are allowed to reach across newlines
// to pull in an LCURLY and appended block.
private final int LC_STMT = 1, LC_INIT = 2;
/**
* Counts the number of LT seen in the typeArguments production.
* It is used in semantic predicates to ensure we have seen
* enough closing '>' characters; which actually may have been
* either GT, SR or BSR tokens.
*/
private int ltCounter = 0;
/* This symbol is used to work around a known ANTLR limitation.
* In a loop with syntactic predicate, ANTLR needs help knowing
* that the loop exit is a second alternative.
* Example usage: ( (LCURLY)=> block | {ANTLR_LOOP_EXIT}? )*
* Probably should be an ANTLR RFE.
*/
////// Original comment in Java grammar:
// Unfortunately a syntactic predicate can only select one of
// multiple alternatives on the same level, not break out of
// an enclosing loop, which is why this ugly hack (a fake
// empty alternative with always-false semantic predicate)
// is necessary.
private static final boolean ANTLR_LOOP_EXIT = false;
protected GroovyRecognizer(TokenBuffer tokenBuf, int k) { super(tokenBuf,k); tokenNames = _tokenNames; buildTokenTypeASTClassMap(); astFactory = new ASTFactory(getTokenTypeToASTClassMap());}public GroovyRecognizer(TokenBuffer tokenBuf) { this(tokenBuf,3);}protected GroovyRecognizer(TokenStream lexer, int k) { super(lexer,k); tokenNames = _tokenNames; buildTokenTypeASTClassMap(); astFactory = new ASTFactory(getTokenTypeToASTClassMap());}public GroovyRecognizer(TokenStream lexer) { this(lexer,3);}public GroovyRecognizer(ParserSharedInputState state) { super(state,3); tokenNames = _tokenNames; buildTokenTypeASTClassMap(); astFactory = new ASTFactory(getTokenTypeToASTClassMap());} public final void compilationUnit() throws RecognitionException, TokenStreamException { returnAST = null; ASTPair currentAST = new ASTPair(); AST compilationUnit_AST = null; { switch ( LA(1)) { case SH_COMMENT: { match(SH_COMMENT); break; } case EOF: case FINAL: case ABSTRACT: case STRICTFP: case LITERAL_package: case LITERAL_import: case LITERAL_static: case LITERAL_def: case AT: case IDENT: case LBRACK: case LPAREN: case LITERAL_class: case LITERAL_interface: case LITERAL_enum: case LITERAL_super: case LITERAL_void: case LITERAL_boolean: case LITERAL_byte: case LITERAL_char: case LITERAL_short: case LITERAL_int: case LITERAL_float: case LITERAL_long: case LITERAL_double: case LITERAL_any: case STAR: case LITERAL_private: case LITERAL_public: case LITERAL_protected: case LITERAL_transient: case LITERAL_native: case LITERAL_threadsafe: case LITERAL_synchronized: case LITERAL_volatile: case LCURLY: case SEMI: case NLS: case LITERAL_this: case STRING_LITERAL: case LITERAL_if: case LITERAL_while: case LITERAL_with: case LITERAL_switch: case LITERAL_for:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?