use of org.antlr.v4.tool.Rule in project antlr4 by tunnelvisionlabs.
the class BasicSemanticChecks method finishRule.
@Override
public void finishRule(RuleAST rule, GrammarAST ID, GrammarAST block) {
if (rule.isLexerRule())
return;
BlockAST blk = (BlockAST) rule.getFirstChildWithType(BLOCK);
int nalts = blk.getChildCount();
GrammarAST idAST = (GrammarAST) rule.getChild(0);
for (int i = 0; i < nalts; i++) {
AltAST altAST = (AltAST) blk.getChild(i);
if (altAST.altLabel != null) {
String altLabel = altAST.altLabel.getText();
// first check that label doesn't conflict with a rule
// label X or x can't be rule x.
Rule r = ruleCollector.rules.get(Utils.decapitalize(altLabel));
if (r != null) {
g.tool.errMgr.grammarError(ErrorType.ALT_LABEL_CONFLICTS_WITH_RULE, g.fileName, altAST.altLabel.token, altLabel, r.name);
}
// Now verify that label X or x doesn't conflict with label
// in another rule. altLabelToRuleName has both X and x mapped.
String prevRuleForLabel = ruleCollector.altLabelToRuleName.get(altLabel);
if (prevRuleForLabel != null && !prevRuleForLabel.equals(rule.getRuleName())) {
g.tool.errMgr.grammarError(ErrorType.ALT_LABEL_REDEF, g.fileName, altAST.altLabel.token, altLabel, rule.getRuleName(), prevRuleForLabel);
}
}
}
List<GrammarAST> altLabels = ruleCollector.ruleToAltLabels.get(rule.getRuleName());
int numAltLabels = 0;
if (altLabels != null)
numAltLabels = altLabels.size();
if (numAltLabels > 0 && nalts != numAltLabels) {
g.tool.errMgr.grammarError(ErrorType.RULE_WITH_TOO_FEW_ALT_LABELS, g.fileName, idAST.token, rule.getRuleName());
}
}
use of org.antlr.v4.tool.Rule in project antlr4 by tunnelvisionlabs.
the class BasicSemanticChecks method checkElementIsOuterMostInSingleAlt.
/**
* Make sure that action is last element in outer alt; here action,
* a2, z, and zz are bad, but a3 is ok:
* (RULE A (BLOCK (ALT {action} 'a')))
* (RULE B (BLOCK (ALT (BLOCK (ALT {a2} 'x') (ALT 'y')) {a3})))
* (RULE C (BLOCK (ALT 'd' {z}) (ALT 'e' {zz})))
*/
protected void checkElementIsOuterMostInSingleAlt(GrammarAST tree) {
CommonTree alt = tree.parent;
CommonTree blk = alt.parent;
boolean outerMostAlt = blk.parent.getType() == RULE;
Tree rule = tree.getAncestor(RULE);
String fileName = tree.getToken().getInputStream().getSourceName();
if (!outerMostAlt || blk.getChildCount() > 1) {
ErrorType e = ErrorType.LEXER_COMMAND_PLACEMENT_ISSUE;
g.tool.errMgr.grammarError(e, fileName, tree.getToken(), rule.getChild(0).getText());
}
}
use of org.antlr.v4.tool.Rule in project antlr4 by tunnelvisionlabs.
the class RuleCollector method discoverLexerRule.
@Override
public void discoverLexerRule(RuleAST rule, GrammarAST ID, List<GrammarAST> modifiers, GrammarAST block) {
int numAlts = block.getChildCount();
Rule r = new Rule(g, ID.getText(), rule, numAlts);
r.mode = currentModeName;
if (!modifiers.isEmpty())
r.modifiers = modifiers;
rules.put(r.name, r);
}
use of org.antlr.v4.tool.Rule in project antlr4 by tunnelvisionlabs.
the class SemanticPipeline method process.
public void process() {
if (g.ast == null)
return;
// COLLECT RULE OBJECTS
RuleCollector ruleCollector = new RuleCollector(g);
ruleCollector.process(g.ast);
// CLONE RULE ASTs FOR CONTEXT REFERENCE
for (Rule rule : ruleCollector.rules.values()) {
List<RuleAST> list = g.contextASTs.get(rule.getBaseContext());
if (list == null) {
list = new ArrayList<RuleAST>();
g.contextASTs.put(rule.getBaseContext(), list);
}
list.add((RuleAST) rule.ast.dupTree());
}
// DO BASIC / EASY SEMANTIC CHECKS
int prevErrors = g.tool.errMgr.getNumErrors();
BasicSemanticChecks basics = new BasicSemanticChecks(g, ruleCollector);
basics.process();
if (g.tool.errMgr.getNumErrors() > prevErrors)
return;
// TRANSFORM LEFT-RECURSIVE RULES
prevErrors = g.tool.errMgr.getNumErrors();
LeftRecursiveRuleTransformer lrtrans = new LeftRecursiveRuleTransformer(g.ast, ruleCollector.rules.values(), g);
lrtrans.translateLeftRecursiveRules();
// don't continue if we got errors during left-recursion elimination
if (g.tool.errMgr.getNumErrors() > prevErrors) {
return;
}
// AUTO LEFT FACTORING
LeftFactoringRuleTransformer lftrans = new LeftFactoringRuleTransformer(g.ast, ruleCollector.rules, g);
lftrans.translateLeftFactoredRules();
// STORE RULES IN GRAMMAR
for (Rule r : ruleCollector.rules.values()) {
g.defineRule(r);
}
// COLLECT SYMBOLS: RULES, ACTIONS, TERMINALS, ...
SymbolCollector collector = new SymbolCollector(g);
collector.process(g.ast);
// CHECK FOR SYMBOL COLLISIONS
SymbolChecks symcheck = new SymbolChecks(g, collector);
// side-effect: strip away redef'd rules.
symcheck.process();
for (GrammarAST a : collector.namedActions) {
g.defineAction(a);
}
// LINK (outermost) ALT NODES WITH Alternatives
for (Rule r : g.rules.values()) {
for (int i = 1; i <= r.numberOfAlts; i++) {
r.alt[i].ast.alt = r.alt[i];
}
}
// ASSIGN TOKEN TYPES
g.importTokensFromTokensFile();
if (g.isLexer()) {
assignLexerTokenTypes(g, collector.tokensDefs);
} else {
assignTokenTypes(g, collector.tokensDefs, collector.tokenIDRefs, collector.terminals);
}
symcheck.checkForModeConflicts(g);
symcheck.checkForUnreachableTokens(g);
assignChannelTypes(g, collector.channelDefs);
// CHECK RULE REFS NOW (that we've defined rules in grammar)
symcheck.checkRuleArgs(g, collector.rulerefs);
identifyStartRules(collector);
symcheck.checkForQualifiedRuleIssues(g, collector.qualifiedRulerefs);
// don't continue if we got symbol errors
if (g.tool.getNumErrors() > 0)
return;
// CHECK ATTRIBUTE EXPRESSIONS FOR SEMANTIC VALIDITY
AttributeChecks.checkAllAttributeExpressions(g);
UseDefAnalyzer.trackTokenRuleRefsInActions(g);
}
use of org.antlr.v4.tool.Rule in project antlr4 by tunnelvisionlabs.
the class SemanticPipeline method identifyStartRules.
void identifyStartRules(SymbolCollector collector) {
for (GrammarAST ref : collector.rulerefs) {
String ruleName = ref.getText();
Rule r = g.getRule(ruleName);
if (r != null)
r.isStartRule = false;
}
}
Aggregations