?? antlrparserplugin.java
字號(hào):
/**
*
* Copyright 2004 James Strachan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
package org.codehaus.groovy.antlr;
import antlr.RecognitionException;
import antlr.TokenStreamException;
import antlr.TokenStreamRecognitionException;
import antlr.collections.AST;
import com.thoughtworks.xstream.XStream;
import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.antlr.parser.GroovyLexer;
import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
import org.codehaus.groovy.antlr.parser.GroovyTokenTypes;
import org.codehaus.groovy.antlr.treewalker.*;
import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.ParserPlugin;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.syntax.*;
import org.objectweb.asm.Opcodes;
import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* A parser plugin which adapts the JSR Antlr Parser to the Groovy runtime
*
* @author <a href="mailto:jstrachan@protique.com">James Strachan</a>
* @version $Revision: 4526 $
*/
public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, GroovyTokenTypes {
private AST ast;
private ClassNode classNode;
private String[] tokenNames;
public Reduction parseCST(final SourceUnit sourceUnit, Reader reader) throws CompilationFailedException {
ast = null;
setController(sourceUnit);
SourceBuffer sourceBuffer = new SourceBuffer();
UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(reader,sourceBuffer);
GroovyLexer lexer = new GroovyLexer(unicodeReader);
unicodeReader.setLexer(lexer);
GroovyRecognizer parser = GroovyRecognizer.make(lexer);
parser.setSourceBuffer(sourceBuffer);
tokenNames = parser.getTokenNames();
parser.setFilename(sourceUnit.getName());
// start parsing at the compilationUnit rule
try {
parser.compilationUnit();
}
catch (TokenStreamRecognitionException tsre) {
RecognitionException e = tsre.recog;
SyntaxException se = new SyntaxException(e.getMessage(),e,e.getLine(),e.getColumn());
se.setFatal(true);
sourceUnit.addError(se);
}
catch (RecognitionException e) {
SyntaxException se = new SyntaxException(e.getMessage(),e,e.getLine(),e.getColumn());
se.setFatal(true);
sourceUnit.addError(se);
}
catch (TokenStreamException e) {
sourceUnit.addException(e);
}
ast = parser.getAST();
AntlrASTProcessor snippets = new AntlrASTProcessSnippets(sourceBuffer);
ast = snippets.process(ast);
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
outputASTInVariousFormsIfNeeded(sourceUnit);
return null;
}
});
return null; //new Reduction(Tpken.EOF);
}
public SourceSummary getSummary() {
SummaryCollector summaryCollector = new SummaryCollector();
AntlrASTProcessor treewalker = new PreOrderTraversal(summaryCollector);
treewalker.process(ast);
return summaryCollector.getSourceSummary();
}
private void outputASTInVariousFormsIfNeeded(SourceUnit sourceUnit) {
// straight xstream output of AST
if ("xml".equals(System.getProperty("antlr.ast"))) {
saveAsXML(sourceUnit.getName(), ast);
}
// 'pretty printer' output of AST
if ("groovy".equals(System.getProperty("antlr.ast"))) {
try {
PrintStream out = new PrintStream(new FileOutputStream(sourceUnit.getName() + ".pretty.groovy"));
Visitor visitor = new SourcePrinter(out,tokenNames);
AntlrASTProcessor treewalker = new SourceCodeTraversal(visitor);
treewalker.process(ast);
} catch (FileNotFoundException e) {
System.out.println("Cannot create " + sourceUnit.getName() + ".pretty.groovy");
}
}
// output AST in format suitable for opening in http://freemind.sourceforge.net
// which is a really nice way of seeing the AST, folding nodes etc
if ("mindmap".equals(System.getProperty("antlr.ast"))) {
try {
PrintStream out = new PrintStream(new FileOutputStream(sourceUnit.getName() + ".mm"));
Visitor visitor = new MindMapPrinter(out,tokenNames);
AntlrASTProcessor treewalker = new PreOrderTraversal(visitor);
treewalker.process(ast);
} catch (FileNotFoundException e) {
System.out.println("Cannot create " + sourceUnit.getName() + ".mm");
}
}
// html output of AST
if ("html".equals(System.getProperty("antlr.ast"))) {
try {
PrintStream out = new PrintStream(new FileOutputStream(sourceUnit.getName() + ".html"));
List v = new ArrayList();
v.add(new NodeAsHTMLPrinter(out,tokenNames));
v.add(new SourcePrinter(out,tokenNames));
Visitor visitors = new CompositeVisitor(v);
AntlrASTProcessor treewalker = new SourceCodeTraversal(visitors);
treewalker.process(ast);
} catch (FileNotFoundException e) {
System.out.println("Cannot create " + sourceUnit.getName() + ".html");
}
}
}
private void saveAsXML(String name, AST ast) {
XStream xstream = new XStream();
try {
xstream.toXML(ast, new FileWriter(name + ".antlr.xml"));
System.out.println("Written AST to " + name + ".antlr.xml");
}
catch (Exception e) {
System.out.println("Couldn't write to " + name + ".antlr.xml");
e.printStackTrace();
}
}
public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduction cst) throws ParserException {
setClassLoader(classLoader);
makeModule();
try {
convertGroovy(ast);
}
catch (ASTRuntimeException e) {
throw new ASTParserException(e.getMessage() + ". File: " + sourceUnit.getName(), e);
}
return output;
}
/**
* Converts the Antlr AST to the Groovy AST
*/
protected void convertGroovy(AST node) {
while (node != null) {
int type = node.getType();
switch (type) {
case PACKAGE_DEF:
packageDef(node);
break;
case IMPORT:
importDef(node);
break;
case CLASS_DEF:
classDef(node);
break;
case INTERFACE_DEF:
interfaceDef(node);
break;
case METHOD_DEF:
methodDef(node);
break;
default:
{
Statement statement = statement(node);
output.addStatement(statement);
}
}
node = node.getNextSibling();
}
}
// Top level control structures
//-------------------------------------------------------------------------
protected void packageDef(AST packageDef) {
AST node = packageDef.getFirstChild();
if (isType(ANNOTATIONS, node)) {
node = node.getNextSibling();
}
String name = qualifiedName(node);
setPackageName(name);
}
protected void importDef(AST importNode) {
// TODO handle static imports
AST node = importNode.getFirstChild();
String alias = null;
if (isType(LITERAL_as, node)) {
//import is like "import Foo as Bar"
node = node.getFirstChild();
AST aliasNode = node.getNextSibling();
alias = identifier(aliasNode);
}
if (node.getNumberOfChildren()==0) {
// import is like "import Foo"
String name = identifier(node);
ClassNode type = ClassHelper.make(name);
configureAST(type,importNode);
importClass(type,name,alias);
return;
}
AST packageNode = node.getFirstChild();
String packageName = qualifiedName(packageNode);
AST nameNode = packageNode.getNextSibling();
if (isType(STAR, nameNode)) {
// import is like "import foo.*"
importPackageWithStar(packageName);
if (alias!=null) throw new GroovyBugError(
"imports like 'import foo.* as Bar' are not "+
"supported and should be caught by the grammar");
} else {
// import is like "import foo.Bar"
String name = identifier(nameNode);
ClassNode type = ClassHelper.make(packageName+"."+name);
configureAST(type,importNode);
importClass(type,name,alias);
}
}
protected void interfaceDef(AST classDef) {
List annotations = new ArrayList();
AST node = classDef.getFirstChild();
int modifiers = Opcodes.ACC_PUBLIC;
if (isType(MODIFIERS, node)) {
modifiers = modifiers(node, annotations, modifiers);
node = node.getNextSibling();
}
modifiers |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE;
String name = identifier(node);
node = node.getNextSibling();
ClassNode superClass = ClassHelper.OBJECT_TYPE;
ClassNode[] interfaces = {};
if (isType(EXTENDS_CLAUSE, node)) {
interfaces = interfaces(node);
node = node.getNextSibling();
}
addNewClassName(name);
classNode = new ClassNode(dot(getPackageName(), name), modifiers, superClass, interfaces, null);
classNode.addAnnotations(annotations);
configureAST(classNode, classDef);
assertNodeType(OBJBLOCK, node);
objectBlock(node);
output.addClass(classNode);
classNode = null;
}
protected void classDef(AST classDef) {
List annotations = new ArrayList();
AST node = classDef.getFirstChild();
int modifiers = Opcodes.ACC_PUBLIC;
if (isType(MODIFIERS, node)) {
modifiers = modifiers(node, annotations, modifiers);
node = node.getNextSibling();
}
String name = identifier(node);
node = node.getNextSibling();
ClassNode superClass = null;
if (isType(EXTENDS_CLAUSE, node)) {
superClass = makeType(node);
node = node.getNextSibling();
}
ClassNode[] interfaces = {};
if (isType(IMPLEMENTS_CLAUSE, node)) {
interfaces = interfaces(node);
node = node.getNextSibling();
}
// TODO read mixins
MixinNode[] mixins = {};
addNewClassName(name);
classNode = new ClassNode(dot(getPackageName(), name), modifiers, superClass, interfaces, mixins);
classNode.addAnnotations(annotations);
configureAST(classNode, classDef);
assertNodeType(OBJBLOCK, node);
objectBlock(node);
output.addClass(classNode);
classNode = null;
}
protected void objectBlock(AST objectBlock) {
for (AST node = objectBlock.getFirstChild(); node != null; node = node.getNextSibling()) {
int type = node.getType();
switch (type) {
case OBJBLOCK:
objectBlock(node);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -