antlrparserplugin.java
来自「大名鼎鼎的java动态脚本语言。已经通过了sun的认证」· Java 代码 · 共 1,799 行 · 第 1/5 页
JAVA
1,799 行
/** * * 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: 1.70 $ */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 catched 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); break; case METHOD_DEF: methodDef(node); break; case CTOR_IDENT: constructorDef(node); break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?