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 + -
显示快捷键?