Java Code Examples for org.antlr.v4.tool.ast.GrammarAST#getChild()

The following examples show how to use org.antlr.v4.tool.ast.GrammarAST#getChild() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: LeftRecursiveRuleAnalyzer.java    From codebuff with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Match (RULE RULE_REF (BLOCK (ALT .*) (ALT RULE_REF[self] .*) (ALT .*)))
 * Match (RULE RULE_REF (BLOCK (ALT .*) (ALT (ASSIGN ID RULE_REF[self]) .*) (ALT .*)))
 */
public static boolean hasImmediateRecursiveRuleRefs(GrammarAST t, String ruleName) {
	if ( t==null ) return false;
	GrammarAST blk = (GrammarAST)t.getFirstChildWithType(BLOCK);
	if ( blk==null ) return false;
	int n = blk.getChildren().size();
	for (int i = 0; i < n; i++) {
		GrammarAST alt = (GrammarAST)blk.getChildren().get(i);
		Tree first = alt.getChild(0);
		if ( first==null ) continue;
		if (first.getType() == ELEMENT_OPTIONS) {
			first = alt.getChild(1);
			if (first == null) {
				continue;
			}
		}
		if ( first.getType()==RULE_REF && first.getText().equals(ruleName) ) return true;
		Tree rref = first.getChild(1);
		if ( rref!=null && rref.getType()==RULE_REF && rref.getText().equals(ruleName) ) return true;
	}
	return false;
}
 
Example 2
Source File: SymbolChecks.java    From codebuff with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public void checkForQualifiedRuleIssues(Grammar g, List<GrammarAST> qualifiedRuleRefs) {
	for (GrammarAST dot : qualifiedRuleRefs) {
		GrammarAST grammar = (GrammarAST)dot.getChild(0);
		GrammarAST rule = (GrammarAST)dot.getChild(1);
           g.tool.log("semantics", grammar.getText()+"."+rule.getText());
		Grammar delegate = g.getImportedGrammar(grammar.getText());
		if ( delegate==null ) {
			errMgr.grammarError(ErrorType.NO_SUCH_GRAMMAR_SCOPE,
									  g.fileName, grammar.token, grammar.getText(),
									  rule.getText());
		}
		else {
			if ( g.getRule(grammar.getText(), rule.getText())==null ) {
				errMgr.grammarError(ErrorType.NO_SUCH_RULE_IN_SCOPE,
										  g.fileName, rule.token, grammar.getText(),
										  rule.getText());
			}
		}
	}
}
 
Example 3
Source File: Tool.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/** Manually get option node from tree; return null if no defined. */
public static GrammarAST findOptionValueAST(GrammarRootAST root, String option) {
	GrammarAST options = (GrammarAST)root.getFirstChildWithType(ANTLRParser.OPTIONS);
	if ( options!=null && options.getChildCount() > 0 ) {
		for (Object o : options.getChildren()) {
			GrammarAST c = (GrammarAST)o;
			if ( c.getType() == ANTLRParser.ASSIGN &&
				 c.getChild(0).getText().equals(option) )
			{
				return (GrammarAST)c.getChild(1);
			}
		}
	}
	return null;
}
 
Example 4
Source File: Grammar.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/** 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 . .) .)))",
			// TODO: allow doc comment in there
		};
		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;
	}
 
Example 5
Source File: ParserATNFactory.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * From {@code (blk)+} build
 *
 * <pre>
 *   |---------|
 *   v         |
 *  [o-blk-o]-&gt;o-&gt;o
 * </pre>
 *
 * We add a decision for loop back node to the existing one at {@code blk}
 * start.
 */

@Override
public Handle plus(GrammarAST plusAST, Handle blk) {
	PlusBlockStartState blkStart = (PlusBlockStartState)blk.left;
	BlockEndState blkEnd = (BlockEndState)blk.right;
	preventEpsilonClosureBlocks.add(new Triple<Rule, ATNState, ATNState>(currentRule, blkStart, blkEnd));

	PlusLoopbackState loop = newState(PlusLoopbackState.class, plusAST);
	loop.nonGreedy = !((QuantifierAST)plusAST).isGreedy();
	atn.defineDecisionState(loop);
	LoopEndState end = newState(LoopEndState.class, plusAST);
	blkStart.loopBackState = loop;
	end.loopBackState = loop;

	plusAST.atnState = loop;
	epsilon(blkEnd, loop);		// blk can see loop back

	BlockAST blkAST = (BlockAST)plusAST.getChild(0);
	if ( ((QuantifierAST)plusAST).isGreedy() ) {
		if (expectNonGreedy(blkAST)) {
			g.tool.errMgr.grammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, plusAST.getToken(), plusAST.getToken().getText());
		}

		epsilon(loop, blkStart);	// loop back to start
		epsilon(loop, end);			// or exit
	}
	else {
		// if not greedy, priority to exit branch; make it first
		epsilon(loop, end);			// exit
		epsilon(loop, blkStart);	// loop back to start
	}

	return new Handle(blkStart, end);
}
 
Example 6
Source File: ParserATNFactory.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * From {@code (blk)*} build {@code ( blk+ )?} with *two* decisions, one for
 * entry and one for choosing alts of {@code blk}.
 *
 * <pre>
 *   |-------------|
 *   v             |
 *   o--[o-blk-o]-&gt;o  o
 *   |                ^
 *   -----------------|
 * </pre>
 *
 * Note that the optional bypass must jump outside the loop as
 * {@code (A|B)*} is not the same thing as {@code (A|B|)+}.
 */

@Override
public Handle star(GrammarAST starAST, Handle elem) {
	StarBlockStartState blkStart = (StarBlockStartState)elem.left;
	BlockEndState blkEnd = (BlockEndState)elem.right;
	preventEpsilonClosureBlocks.add(new Triple<Rule, ATNState, ATNState>(currentRule, blkStart, blkEnd));

	StarLoopEntryState entry = newState(StarLoopEntryState.class, starAST);
	entry.nonGreedy = !((QuantifierAST)starAST).isGreedy();
	atn.defineDecisionState(entry);
	LoopEndState end = newState(LoopEndState.class, starAST);
	StarLoopbackState loop = newState(StarLoopbackState.class, starAST);
	entry.loopBackState = loop;
	end.loopBackState = loop;

	BlockAST blkAST = (BlockAST)starAST.getChild(0);
	if ( ((QuantifierAST)starAST).isGreedy() ) {
		if (expectNonGreedy(blkAST)) {
			g.tool.errMgr.grammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, starAST.getToken(), starAST.getToken().getText());
		}

		epsilon(entry, blkStart);	// loop enter edge (alt 1)
		epsilon(entry, end);		// bypass loop edge (alt 2)
	}
	else {
		// if not greedy, priority to exit branch; make it first
		epsilon(entry, end);		// bypass loop edge (alt 1)
		epsilon(entry, blkStart);	// loop enter edge (alt 2)
	}
	epsilon(blkEnd, loop);		// block end hits loop back
	epsilon(loop, entry);		// loop back to entry/exit decision

	starAST.atnState = entry;	// decision is to enter/exit; blk is its own decision
	return new Handle(entry, end);
}
 
Example 7
Source File: LL1PlusBlockSingleAlt.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public LL1PlusBlockSingleAlt(OutputModelFactory factory, GrammarAST plusRoot, List<CodeBlockForAlt> alts) {
	super(factory, plusRoot, alts);

	BlockAST blkAST = (BlockAST)plusRoot.getChild(0);
	PlusBlockStartState blkStart = (PlusBlockStartState)blkAST.atnState;

	stateNumber = blkStart.loopBackState.stateNumber;
	blockStartStateNumber = blkStart.stateNumber;
	PlusBlockStartState plus = (PlusBlockStartState)blkAST.atnState;
	this.decision = plus.loopBackState.decision;
	IntervalSet[] altLookSets = factory.getGrammar().decisionLOOK.get(decision);

	IntervalSet loopBackLook = altLookSets[0];
	loopExpr = addCodeForLoopLookaheadTempVar(loopBackLook);
}
 
Example 8
Source File: PlusBlock.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public PlusBlock(OutputModelFactory factory,
				 GrammarAST plusRoot,
				 List<CodeBlockForAlt> alts)
{
	super(factory, plusRoot, alts);
	BlockAST blkAST = (BlockAST)plusRoot.getChild(0);
	PlusBlockStartState blkStart = (PlusBlockStartState)blkAST.atnState;
	PlusLoopbackState loop = blkStart.loopBackState;
	stateNumber = blkStart.loopBackState.stateNumber;
	blockStartStateNumber = blkStart.stateNumber;
	loopBackStateNumber = loop.stateNumber;
	this.error = getThrowNoViableAlt(factory, plusRoot, null);
	decision = loop.decision;
}
 
Example 9
Source File: BasicSemanticChecks.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
void checkNumRules(GrammarAST rulesNode) {
	if ( rulesNode.getChildCount()==0 ) {
		GrammarAST root = (GrammarAST)rulesNode.getParent();
		GrammarAST IDNode = (GrammarAST)root.getChild(0);
		g.tool.errMgr.grammarError(ErrorType.NO_RULES, g.fileName,
				null, IDNode.getText(), g);
	}
}
 
Example 10
Source File: SemanticPipeline.java    From codebuff with BSD 2-Clause "Simplified" License 5 votes vote down vote up
boolean hasTypeOrMoreCommand(Rule r) {
	GrammarAST ast = r.ast;
	if (ast == null) {
		return false;
	}

	GrammarAST altActionAst = (GrammarAST)ast.getFirstDescendantWithType(ANTLRParser.LEXER_ALT_ACTION);
	if (altActionAst == null) {
		// the rule isn't followed by any commands
		return false;
	}

	// first child is the alt itself, subsequent are the actions
	for (int i = 1; i < altActionAst.getChildCount(); i++) {
		GrammarAST node = (GrammarAST)altActionAst.getChild(i);
		if (node.getType() == ANTLRParser.LEXER_ACTION_CALL) {
			if ("type".equals(node.getChild(0).getText())) {
				return true;
			}
		}
		else if ("more".equals(node.getText())) {
			return true;
		}
	}

	return false;
}
 
Example 11
Source File: LeftRecursiveRuleTransformer.java    From codebuff with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/** Return true if successful */
	public boolean translateLeftRecursiveRule(GrammarRootAST ast,
											  LeftRecursiveRule r,
											  String language)
	{
		//tool.log("grammar", ruleAST.toStringTree());
		GrammarAST prevRuleAST = r.ast;
		String ruleName = prevRuleAST.getChild(0).getText();
		LeftRecursiveRuleAnalyzer leftRecursiveRuleWalker =
			new LeftRecursiveRuleAnalyzer(prevRuleAST, tool, ruleName, language);
		boolean isLeftRec;
		try {
//			System.out.println("TESTING ---------------\n"+
//							   leftRecursiveRuleWalker.text(ruleAST));
			isLeftRec = leftRecursiveRuleWalker.rec_rule();
		}
		catch (RecognitionException re) {
			isLeftRec = false; // didn't match; oh well
		}
		if ( !isLeftRec ) return false;

		// replace old rule's AST; first create text of altered rule
		GrammarAST RULES = (GrammarAST)ast.getFirstChildWithType(ANTLRParser.RULES);
		String newRuleText = leftRecursiveRuleWalker.getArtificialOpPrecRule();
//		System.out.println("created: "+newRuleText);
		// now parse within the context of the grammar that originally created
		// the AST we are transforming. This could be an imported grammar so
		// we cannot just reference this.g because the role might come from
		// the imported grammar and not the root grammar (this.g)
		RuleAST t = parseArtificialRule(prevRuleAST.g, newRuleText);

		// reuse the name token from the original AST since it refers to the proper source location in the original grammar
		((GrammarAST)t.getChild(0)).token = ((GrammarAST)prevRuleAST.getChild(0)).getToken();

		// update grammar AST and set rule's AST.
		RULES.setChild(prevRuleAST.getChildIndex(), t);
		r.ast = t;

		// Reduce sets in newly created rule tree
		GrammarTransformPipeline transform = new GrammarTransformPipeline(g, g.tool);
		transform.reduceBlocksToSets(r.ast);
		transform.expandParameterizedLoops(r.ast);

		// Rerun semantic checks on the new rule
		RuleCollector ruleCollector = new RuleCollector(g);
		ruleCollector.visit(t, "rule");
		BasicSemanticChecks basics = new BasicSemanticChecks(g, ruleCollector);
		// disable the assoc element option checks because they are already
		// handled for the pre-transformed rule.
		basics.checkAssocElementOption = false;
		basics.visit(t, "rule");

		// track recursive alt info for codegen
		r.recPrimaryAlts = new ArrayList<LeftRecursiveRuleAltInfo>();
		r.recPrimaryAlts.addAll(leftRecursiveRuleWalker.prefixAndOtherAlts);
		if (r.recPrimaryAlts.isEmpty()) {
			tool.errMgr.grammarError(ErrorType.NO_NON_LR_ALTS, g.fileName, ((GrammarAST)r.ast.getChild(0)).getToken(), r.name);
		}

		r.recOpAlts = new OrderedHashMap<Integer, LeftRecursiveRuleAltInfo>();
		r.recOpAlts.putAll(leftRecursiveRuleWalker.binaryAlts);
		r.recOpAlts.putAll(leftRecursiveRuleWalker.ternaryAlts);
		r.recOpAlts.putAll(leftRecursiveRuleWalker.suffixAlts);

		// walk alt info records and set their altAST to point to appropriate ALT subtree
		// from freshly created AST
		setAltASTPointers(r, t);

		// update Rule to just one alt and add prec alt
		ActionAST arg = (ActionAST)r.ast.getFirstChildWithType(ANTLRParser.ARG_ACTION);
		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[1]; // todo: isn't this Rule or something?
		}

		// define labels on recursive rule refs we delete; they don't point to nodes of course
		// these are so $label in action translation works
		for (Pair<GrammarAST,String> pair : leftRecursiveRuleWalker.leftRecursiveRuleRefLabels) {
			GrammarAST labelNode = pair.a;
			GrammarAST labelOpNode = (GrammarAST)labelNode.getParent();
			GrammarAST elementNode = (GrammarAST)labelOpNode.getChild(1);
			LabelElementPair lp = new LabelElementPair(g, labelNode, elementNode, labelOpNode.getType());
			r.alt[1].labelDefs.map(labelNode.getText(), lp);
		}
		// copy to rule from walker
		r.leftRecursiveRuleRefLabels = leftRecursiveRuleWalker.leftRecursiveRuleRefLabels;

		tool.log("grammar", "added: "+t.toStringTree());
		return true;
	}
 
Example 12
Source File: RuleFunction.java    From codebuff with BSD 2-Clause "Simplified" License 4 votes vote down vote up
public RuleFunction(OutputModelFactory factory, Rule r) {
	super(factory);
	this.name = r.name;
	this.rule = r;
	if ( r.modifiers!=null && !r.modifiers.isEmpty() ) {
		this.modifiers = new ArrayList<String>();
		for (GrammarAST t : r.modifiers) modifiers.add(t.getText());
	}
	modifiers = Utils.nodesToStrings(r.modifiers);

	index = r.index;

	ruleCtx = new StructDecl(factory, r);
	altToContext = new AltLabelStructDecl[r.getOriginalNumberOfAlts()+1];
	addContextGetters(factory, r);

	if ( r.args!=null ) {
		Collection<Attribute> decls = r.args.attributes.values();
		if ( decls.size()>0 ) {
			args = new ArrayList<AttributeDecl>();
			ruleCtx.addDecls(decls);
			for (Attribute a : decls) {
				args.add(new AttributeDecl(factory, a));
			}
			ruleCtx.ctorAttrs = args;
		}
	}
	if ( r.retvals!=null ) {
		ruleCtx.addDecls(r.retvals.attributes.values());
	}
	if ( r.locals!=null ) {
		ruleCtx.addDecls(r.locals.attributes.values());
	}

	ruleLabels = r.getElementLabelNames();
	tokenLabels = r.getTokenRefs();
	if ( r.exceptions!=null ) {
		exceptions = new ArrayList<ExceptionClause>();
		for (GrammarAST e : r.exceptions) {
			ActionAST catchArg = (ActionAST)e.getChild(0);
			ActionAST catchAction = (ActionAST)e.getChild(1);
			exceptions.add(new ExceptionClause(factory, catchArg, catchAction));
		}
	}

	startState = factory.getGrammar().atn.ruleToStartState[r.index];
}
 
Example 13
Source File: RuleCollector.java    From codebuff with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@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;
	}
}