use of org.antlr.v4.codegen.model.Action in project antlr4 by antlr.
the class LexerATNFactory method lexerCommand.
@Override
public Handle lexerCommand(GrammarAST ID) {
LexerAction lexerAction = createLexerAction(ID, null);
if (lexerAction != null) {
return action(ID, lexerAction);
}
// fall back to standard action generation for the command
ST cmdST = codegenTemplates.getInstanceOf("Lexer" + CharSupport.capitalize(ID.getText()) + "Command");
if (cmdST == null) {
g.tool.errMgr.grammarError(ErrorType.INVALID_LEXER_COMMAND, g.fileName, ID.token, ID.getText());
return epsilon(ID);
}
if (cmdST.impl.formalArguments != null && cmdST.impl.formalArguments.containsKey("arg")) {
g.tool.errMgr.grammarError(ErrorType.MISSING_LEXER_COMMAND_ARGUMENT, g.fileName, ID.token, ID.getText());
return epsilon(ID);
}
return action(cmdST.render());
}
use of org.antlr.v4.codegen.model.Action in project antlr4 by antlr.
the class Grammar method getStringLiteralAliasesFromLexerRules.
/** Return list of (TOKEN_NAME node, 'literal' node) pairs */
public static List<Pair<GrammarAST, GrammarAST>> getStringLiteralAliasesFromLexerRules(GrammarRootAST ast) {
String[] patterns = { "(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL)))", "(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL ACTION)))", "(RULE %name:TOKEN_REF (BLOCK (ALT %lit:STRING_LITERAL SEMPRED)))", "(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) .)))", "(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) . .)))", "(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) (LEXER_ACTION_CALL . .))))", "(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) . (LEXER_ACTION_CALL . .))))", "(RULE %name:TOKEN_REF (BLOCK (LEXER_ALT_ACTION (ALT %lit:STRING_LITERAL) (LEXER_ACTION_CALL . .) .)))" };
GrammarASTAdaptor adaptor = new GrammarASTAdaptor(ast.token.getInputStream());
org.antlr.runtime.tree.TreeWizard wiz = new org.antlr.runtime.tree.TreeWizard(adaptor, ANTLRParser.tokenNames);
List<Pair<GrammarAST, GrammarAST>> lexerRuleToStringLiteral = new ArrayList<Pair<GrammarAST, GrammarAST>>();
List<GrammarAST> ruleNodes = ast.getNodesWithType(ANTLRParser.RULE);
if (ruleNodes == null || ruleNodes.isEmpty())
return null;
for (GrammarAST r : ruleNodes) {
//tool.log("grammar", r.toStringTree());
// System.out.println("chk: "+r.toStringTree());
org.antlr.runtime.tree.Tree name = r.getChild(0);
if (name.getType() == ANTLRParser.TOKEN_REF) {
// check rule against patterns
boolean isLitRule;
for (String pattern : patterns) {
isLitRule = defAlias(r, pattern, wiz, lexerRuleToStringLiteral);
if (isLitRule)
break;
}
// if ( !isLitRule ) System.out.println("no pattern matched");
}
}
return lexerRuleToStringLiteral;
}
use of org.antlr.v4.codegen.model.Action in project antlr4 by antlr.
the class RuleCollector method discoverRule.
@Override
public void discoverRule(RuleAST rule, GrammarAST ID, List<GrammarAST> modifiers, ActionAST arg, ActionAST returns, GrammarAST thrws, GrammarAST options, ActionAST locals, List<GrammarAST> actions, GrammarAST block) {
int numAlts = block.getChildCount();
Rule r;
if (LeftRecursiveRuleAnalyzer.hasImmediateRecursiveRuleRefs(rule, ID.getText())) {
r = new LeftRecursiveRule(g, ID.getText(), rule);
} else {
r = new Rule(g, ID.getText(), rule, numAlts);
}
rules.put(r.name, r);
if (arg != null) {
r.args = ScopeParser.parseTypedArgList(arg, arg.getText(), g);
r.args.type = AttributeDict.DictType.ARG;
r.args.ast = arg;
arg.resolver = r.alt[currentOuterAltNumber];
}
if (returns != null) {
r.retvals = ScopeParser.parseTypedArgList(returns, returns.getText(), g);
r.retvals.type = AttributeDict.DictType.RET;
r.retvals.ast = returns;
}
if (locals != null) {
r.locals = ScopeParser.parseTypedArgList(locals, locals.getText(), g);
r.locals.type = AttributeDict.DictType.LOCAL;
r.locals.ast = locals;
}
for (GrammarAST a : actions) {
// a = ^(AT ID ACTION)
ActionAST action = (ActionAST) a.getChild(1);
r.namedActions.put(a.getChild(0).getText(), action);
action.resolver = r;
}
}
use of org.antlr.v4.codegen.model.Action 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());
}
use of org.antlr.v4.codegen.model.Action 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;
}
Aggregations