Package com.dci.intellij.dbn.language.common

Source Code of com.dci.intellij.dbn.language.common.DBLanguageParser

package com.dci.intellij.dbn.language.common;

import com.dci.intellij.dbn.common.options.setting.SettingsUtil;
import com.dci.intellij.dbn.common.util.CommonUtil;
import com.dci.intellij.dbn.language.common.element.ElementTypeBundle;
import com.dci.intellij.dbn.language.common.element.NamedElementType;
import com.dci.intellij.dbn.language.common.element.parser.ParserBuilder;
import com.dci.intellij.dbn.language.common.element.parser.ParserContext;
import com.dci.intellij.dbn.language.common.element.path.ParsePathNode;
import com.intellij.lang.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.psi.tree.IElementType;
import org.jdom.Document;
import org.jetbrains.annotations.NotNull;

public abstract class DBLanguageParser implements PsiParser {
    private DBLanguageDialect languageDialect;
    private ElementTypeBundle elementTypes;
    private TokenTypeBundle tokenTypes;
    private String defaultParseRootId;

    public DBLanguageParser(DBLanguageDialect languageDialect, String tokenTypesFile, String elementTypesFile, String defaultParseRootId) {
        this.languageDialect = languageDialect;
        this.tokenTypes = new TokenTypeBundle(languageDialect, CommonUtil.loadXmlFile(getClass(), tokenTypesFile));
        Document document = CommonUtil.loadXmlFile(getClass(), elementTypesFile);
        this.elementTypes = new ElementTypeBundle(languageDialect, tokenTypes, document);
        this.defaultParseRootId = defaultParseRootId;
    }

    public DBLanguageDialect getLanguageDialect() {
        return languageDialect;
    }

    @NotNull
    public ASTNode parse(IElementType rootElementType, PsiBuilder builder) {
        return parse(rootElementType, builder, defaultParseRootId);
    }

    @NotNull
    public ASTNode parse(IElementType rootElementType, PsiBuilder psiBuilder, String parseRootId) {
        ParserContext context = new ParserContext(psiBuilder, languageDialect);
        ParserBuilder builder = context.getBuilder();
        if (parseRootId == null ) parseRootId = defaultParseRootId;
        builder.setDebugMode(SettingsUtil.isDebugEnabled);
        PsiBuilder.Marker marker = builder.mark(null);
        NamedElementType root =  elementTypes.getNamedElementType(parseRootId);
        if (root == null) {
            root = elementTypes.getRootElementType();
        }

        boolean advancedLexer = false;
        ParsePathNode rootParseNode = new ParsePathNode(root, null, 0, 0);

        try {
            while (!builder.eof()) {
                int currentOffset =  builder.getCurrentOffset();
                root.getParser().parse(rootParseNode, true, 0, context);
                if (currentOffset == builder.getCurrentOffset()) {
                    TokenType tokenType = (TokenType) builder.getTokenType();
                    /*if (tokenType.isChameleon()) {
                        PsiBuilder.Marker injectedLanguageMarker = builder.mark();
                        builder.advanceLexer();
                        injectedLanguageMarker.done((IElementType) tokenType);
                    }
                    else*/ if (tokenType instanceof ChameleonTokenType) {
                        PsiBuilder.Marker injectedLanguageMarker = builder.mark(null);
                        builder.advanceLexer(rootParseNode);
                        injectedLanguageMarker.done((IElementType) tokenType);
                    } else {
                        builder.advanceLexer(rootParseNode);
                    }
                    advancedLexer = true;
                }
            }
        } catch (ParseException e) {
            while (!builder.eof()) {
                builder.advanceLexer(rootParseNode);
                advancedLexer = true;
            }
        } catch (StackOverflowError e) {
            marker.rollbackTo();
            marker = builder.mark(null);
            while (!builder.eof()) {
                builder.advanceLexer(rootParseNode);
                advancedLexer = true;
            }

        }

        if (!advancedLexer) builder.advanceLexer(rootParseNode);
        marker.done(rootElementType);
        return builder.getTreeBuilt();
    }

    public TokenTypeBundle getTokenTypes() {
        return tokenTypes;
    }

    public ElementTypeBundle getElementTypes() {
        return elementTypes;
    }
}
TOP

Related Classes of com.dci.intellij.dbn.language.common.DBLanguageParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.