Search in sources :

Example 71 with GrammarAST

use of org.antlr.v4.tool.ast.GrammarAST in project antlr4 by antlr.

the class GrammarTransformPipeline method integrateImportedGrammars.

/** Merge all the rules, token definitions, and named actions from
		imported grammars into the root grammar tree.  Perform:

	 	(tokens { X (= Y 'y')) + (tokens { Z )	->	(tokens { X (= Y 'y') Z)

	 	(@ members {foo}) + (@ members {bar})	->	(@ members {foobar})

	 	(RULES (RULE x y)) + (RULES (RULE z))	->	(RULES (RULE x y z))

	 	Rules in root prevent same rule from being appended to RULES node.

	 	The goal is a complete combined grammar so we can ignore subordinate
	 	grammars.
	 */
public void integrateImportedGrammars(Grammar rootGrammar) {
    List<Grammar> imports = rootGrammar.getAllImportedGrammars();
    if (imports == null)
        return;
    GrammarAST root = rootGrammar.ast;
    GrammarAST id = (GrammarAST) root.getChild(0);
    GrammarASTAdaptor adaptor = new GrammarASTAdaptor(id.token.getInputStream());
    GrammarAST tokensRoot = (GrammarAST) root.getFirstChildWithType(ANTLRParser.TOKENS_SPEC);
    List<GrammarAST> actionRoots = root.getNodesWithType(ANTLRParser.AT);
    // Compute list of rules in root grammar and ensure we have a RULES node
    GrammarAST RULES = (GrammarAST) root.getFirstChildWithType(ANTLRParser.RULES);
    Set<String> rootRuleNames = new HashSet<String>();
    // make list of rules we have in root grammar
    List<GrammarAST> rootRules = RULES.getNodesWithType(ANTLRParser.RULE);
    for (GrammarAST r : rootRules) rootRuleNames.add(r.getChild(0).getText());
    for (Grammar imp : imports) {
        // COPY TOKENS
        GrammarAST imp_tokensRoot = (GrammarAST) imp.ast.getFirstChildWithType(ANTLRParser.TOKENS_SPEC);
        if (imp_tokensRoot != null) {
            rootGrammar.tool.log("grammar", "imported tokens: " + imp_tokensRoot.getChildren());
            if (tokensRoot == null) {
                tokensRoot = (GrammarAST) adaptor.create(ANTLRParser.TOKENS_SPEC, "TOKENS");
                tokensRoot.g = rootGrammar;
                // ^(GRAMMAR ID TOKENS...)
                root.insertChild(1, tokensRoot);
            }
            tokensRoot.addChildren(Arrays.asList(imp_tokensRoot.getChildren().toArray(new Tree[0])));
        }
        List<GrammarAST> all_actionRoots = new ArrayList<GrammarAST>();
        List<GrammarAST> imp_actionRoots = imp.ast.getAllChildrenWithType(ANTLRParser.AT);
        if (actionRoots != null)
            all_actionRoots.addAll(actionRoots);
        all_actionRoots.addAll(imp_actionRoots);
        // COPY ACTIONS
        if (imp_actionRoots != null) {
            DoubleKeyMap<String, String, GrammarAST> namedActions = new DoubleKeyMap<String, String, GrammarAST>();
            rootGrammar.tool.log("grammar", "imported actions: " + imp_actionRoots);
            for (GrammarAST at : all_actionRoots) {
                String scopeName = rootGrammar.getDefaultActionScope();
                GrammarAST scope, name, action;
                if (at.getChildCount() > 2) {
                    // must have a scope
                    scope = (GrammarAST) at.getChild(0);
                    scopeName = scope.getText();
                    name = (GrammarAST) at.getChild(1);
                    action = (GrammarAST) at.getChild(2);
                } else {
                    name = (GrammarAST) at.getChild(0);
                    action = (GrammarAST) at.getChild(1);
                }
                GrammarAST prevAction = namedActions.get(scopeName, name.getText());
                if (prevAction == null) {
                    namedActions.put(scopeName, name.getText(), action);
                } else {
                    if (prevAction.g == at.g) {
                        rootGrammar.tool.errMgr.grammarError(ErrorType.ACTION_REDEFINITION, at.g.fileName, name.token, name.getText());
                    } else {
                        String s1 = prevAction.getText();
                        s1 = s1.substring(1, s1.length() - 1);
                        String s2 = action.getText();
                        s2 = s2.substring(1, s2.length() - 1);
                        String combinedAction = "{" + s1 + '\n' + s2 + "}";
                        prevAction.token.setText(combinedAction);
                    }
                }
            }
            // Merge in any actions not in root grammar into root's tree.
            for (String scopeName : namedActions.keySet()) {
                for (String name : namedActions.keySet(scopeName)) {
                    GrammarAST action = namedActions.get(scopeName, name);
                    rootGrammar.tool.log("grammar", action.g.name + " " + scopeName + ":" + name + "=" + action.getText());
                    if (action.g != rootGrammar) {
                        root.insertChild(1, action.getParent());
                    }
                }
            }
        }
        // COPY RULES
        List<GrammarAST> rules = imp.ast.getNodesWithType(ANTLRParser.RULE);
        if (rules != null) {
            for (GrammarAST r : rules) {
                rootGrammar.tool.log("grammar", "imported rule: " + r.toStringTree());
                String name = r.getChild(0).getText();
                boolean rootAlreadyHasRule = rootRuleNames.contains(name);
                if (!rootAlreadyHasRule) {
                    // merge in if not overridden
                    RULES.addChild(r);
                    rootRuleNames.add(name);
                }
            }
        }
        GrammarAST optionsRoot = (GrammarAST) imp.ast.getFirstChildWithType(ANTLRParser.OPTIONS);
        if (optionsRoot != null) {
            // suppress the warning if the options match the options specified
            // in the root grammar
            // https://github.com/antlr/antlr4/issues/707
            boolean hasNewOption = false;
            for (Map.Entry<String, GrammarAST> option : imp.ast.getOptions().entrySet()) {
                String importOption = imp.ast.getOptionString(option.getKey());
                if (importOption == null) {
                    continue;
                }
                String rootOption = rootGrammar.ast.getOptionString(option.getKey());
                if (!importOption.equals(rootOption)) {
                    hasNewOption = true;
                    break;
                }
            }
            if (hasNewOption) {
                rootGrammar.tool.errMgr.grammarError(ErrorType.OPTIONS_IN_DELEGATE, optionsRoot.g.fileName, optionsRoot.token, imp.name);
            }
        }
    }
    rootGrammar.tool.log("grammar", "Grammar: " + rootGrammar.ast.toStringTree());
}
Also used : GrammarAST(org.antlr.v4.tool.ast.GrammarAST) ArrayList(java.util.ArrayList) GrammarASTAdaptor(org.antlr.v4.parse.GrammarASTAdaptor) DoubleKeyMap(org.antlr.v4.runtime.misc.DoubleKeyMap) Map(java.util.Map) DoubleKeyMap(org.antlr.v4.runtime.misc.DoubleKeyMap) HashSet(java.util.HashSet)

Example 72 with GrammarAST

use of org.antlr.v4.tool.ast.GrammarAST in project antlr4 by antlr.

the class GrammarAST method toTokenString.

public String toTokenString() {
    CharStream input = this.token.getInputStream();
    GrammarASTAdaptor adaptor = new GrammarASTAdaptor(input);
    CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor, this);
    StringBuilder buf = new StringBuilder();
    GrammarAST o = (GrammarAST) nodes.LT(1);
    int type = adaptor.getType(o);
    while (type != Token.EOF) {
        buf.append(" ");
        buf.append(o.getText());
        nodes.consume();
        o = (GrammarAST) nodes.LT(1);
        type = adaptor.getType(o);
    }
    return buf.toString();
}
Also used : GrammarASTAdaptor(org.antlr.v4.parse.GrammarASTAdaptor) CharStream(org.antlr.runtime.CharStream) CommonTreeNodeStream(org.antlr.runtime.tree.CommonTreeNodeStream)

Example 73 with GrammarAST

use of org.antlr.v4.tool.ast.GrammarAST in project antlr4 by antlr.

the class SemanticPipeline method assignChannelTypes.

/**
	 * Assign constant values to custom channels defined in a grammar.
	 *
	 * @param g The grammar.
	 * @param channelDefs A collection of AST nodes defining individual channels
	 * within a {@code channels{}} block in the grammar.
	 */
void assignChannelTypes(Grammar g, List<GrammarAST> channelDefs) {
    Grammar outermost = g.getOutermostGrammar();
    for (GrammarAST channel : channelDefs) {
        String channelName = channel.getText();
        if (g.getTokenType(channelName) != Token.INVALID_TYPE) {
            g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_TOKEN, g.fileName, channel.token, channelName);
        }
        if (LexerATNFactory.COMMON_CONSTANTS.containsKey(channelName)) {
            g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, channel.token, channelName);
        }
        if (outermost instanceof LexerGrammar) {
            LexerGrammar lexerGrammar = (LexerGrammar) outermost;
            if (lexerGrammar.modes.containsKey(channelName)) {
                g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_MODE, g.fileName, channel.token, channelName);
            }
        }
        outermost.defineChannelName(channel.getText());
    }
}
Also used : GrammarAST(org.antlr.v4.tool.ast.GrammarAST) Grammar(org.antlr.v4.tool.Grammar) LexerGrammar(org.antlr.v4.tool.LexerGrammar) LexerGrammar(org.antlr.v4.tool.LexerGrammar)

Example 74 with GrammarAST

use of org.antlr.v4.tool.ast.GrammarAST in project antlr4 by antlr.

the class SymbolChecks method checkActionRedefinitions.

public void checkActionRedefinitions(List<GrammarAST> actions) {
    if (actions == null)
        return;
    String scope = g.getDefaultActionScope();
    String name;
    GrammarAST nameNode;
    for (GrammarAST ampersandAST : actions) {
        nameNode = (GrammarAST) ampersandAST.getChild(0);
        if (ampersandAST.getChildCount() == 2) {
            name = nameNode.getText();
        } else {
            scope = nameNode.getText();
            name = ampersandAST.getChild(1).getText();
        }
        Set<String> scopeActions = actionScopeToActionNames.get(scope);
        if (scopeActions == null) {
            // init scope
            scopeActions = new HashSet<String>();
            actionScopeToActionNames.put(scope, scopeActions);
        }
        if (!scopeActions.contains(name)) {
            scopeActions.add(name);
        } else {
            errMgr.grammarError(ErrorType.ACTION_REDEFINITION, g.fileName, nameNode.token, name);
        }
    }
}
Also used : GrammarAST(org.antlr.v4.tool.ast.GrammarAST)

Example 75 with GrammarAST

use of org.antlr.v4.tool.ast.GrammarAST in project antlr4 by antlr.

the class SymbolCollector method ruleCatch.

@Override
public void ruleCatch(GrammarAST arg, ActionAST action) {
    GrammarAST catchme = (GrammarAST) action.getParent();
    currentRule.exceptions.add(catchme);
    action.resolver = currentRule;
}
Also used : GrammarAST(org.antlr.v4.tool.ast.GrammarAST)

Aggregations

GrammarAST (org.antlr.v4.tool.ast.GrammarAST)55 Rule (org.antlr.v4.tool.Rule)20 ATNState (org.antlr.v4.runtime.atn.ATNState)15 ArrayList (java.util.ArrayList)12 GrammarASTAdaptor (org.antlr.v4.parse.GrammarASTAdaptor)12 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)12 LeftRecursiveRule (org.antlr.v4.tool.LeftRecursiveRule)12 Grammar (org.antlr.v4.tool.Grammar)8 Decl (org.antlr.v4.codegen.model.decl.Decl)7 ActionAST (org.antlr.v4.tool.ast.ActionAST)7 AltAST (org.antlr.v4.tool.ast.AltAST)7 TerminalAST (org.antlr.v4.tool.ast.TerminalAST)7 LinkedHashMap (java.util.LinkedHashMap)6 Token (org.antlr.runtime.Token)6 RuleAST (org.antlr.v4.tool.ast.RuleAST)6 HashMap (java.util.HashMap)5 AddToLabelList (org.antlr.v4.codegen.model.AddToLabelList)5 Pair (org.antlr.v4.runtime.misc.Pair)5 LexerGrammar (org.antlr.v4.tool.LexerGrammar)5 GrammarASTWithOptions (org.antlr.v4.tool.ast.GrammarASTWithOptions)5