use of org.antlr.v4.tool.ast.TerminalAST in project antlr4 by tunnelvisionlabs.
the class BasicSemanticChecks method checkElementOptions.
/**
* Check option is appropriate for elem; parent of ID is ELEMENT_OPTIONS
*/
boolean checkElementOptions(GrammarASTWithOptions elem, GrammarAST ID, GrammarAST valueAST) {
if (checkAssocElementOption && ID != null && "assoc".equals(ID.getText())) {
if (elem.getType() != ANTLRParser.ALT) {
Token optionID = ID.token;
String fileName = optionID.getInputStream().getSourceName();
g.tool.errMgr.grammarError(ErrorType.UNRECOGNIZED_ASSOC_OPTION, fileName, optionID, currentRuleName);
}
}
if (elem instanceof RuleRefAST) {
return checkRuleRefOptions((RuleRefAST) elem, ID, valueAST);
}
if (elem instanceof TerminalAST) {
return checkTokenOptions((TerminalAST) elem, ID, valueAST);
}
if (elem.getType() == ANTLRParser.ACTION) {
return false;
}
if (elem.getType() == ANTLRParser.SEMPRED) {
Token optionID = ID.token;
String fileName = optionID.getInputStream().getSourceName();
if (valueAST != null && !Grammar.semPredOptions.contains(optionID.getText())) {
g.tool.errMgr.grammarError(ErrorType.ILLEGAL_OPTION, fileName, optionID, optionID.getText());
return false;
}
}
return false;
}
use of org.antlr.v4.tool.ast.TerminalAST in project antlr4 by tunnelvisionlabs.
the class SymbolChecks method getSingleTokenValues.
/**
* {@return} list of simple string literals for rule {@param rule}
*/
private List<String> getSingleTokenValues(Rule rule) {
List<String> values = new ArrayList<String>();
for (Alternative alt : rule.alt) {
if (alt != null) {
// select first alt if token has a command
Tree rootNode = alt.ast.getChildCount() == 2 && alt.ast.getChild(0) instanceof AltAST && alt.ast.getChild(1) instanceof GrammarAST ? alt.ast.getChild(0) : alt.ast;
if (rootNode.getTokenStartIndex() == -1) {
// ignore autogenerated tokens from combined grammars that start with T__
continue;
}
// Ignore alt if contains not only string literals (repetition, optional)
boolean ignore = false;
StringBuilder currentValue = new StringBuilder();
for (int i = 0; i < rootNode.getChildCount(); i++) {
Tree child = rootNode.getChild(i);
if (!(child instanceof TerminalAST)) {
ignore = true;
break;
}
TerminalAST terminalAST = (TerminalAST) child;
if (terminalAST.token.getType() != ANTLRLexer.STRING_LITERAL) {
ignore = true;
break;
} else {
String text = terminalAST.token.getText();
currentValue.append(text.substring(1, text.length() - 1));
}
}
if (!ignore) {
values.add(currentValue.toString());
}
}
}
return values;
}
use of org.antlr.v4.tool.ast.TerminalAST in project antlr4 by antlr.
the class SymbolChecks method getSingleTokenValues.
/**
* {@return} list of simple string literals for rule {@param rule}
*/
private List<String> getSingleTokenValues(Rule rule) {
List<String> values = new ArrayList<>();
for (Alternative alt : rule.alt) {
if (alt != null) {
// select first alt if token has a command
Tree rootNode = alt.ast.getChildCount() == 2 && alt.ast.getChild(0) instanceof AltAST && alt.ast.getChild(1) instanceof GrammarAST ? alt.ast.getChild(0) : alt.ast;
if (rootNode.getTokenStartIndex() == -1) {
// ignore autogenerated tokens from combined grammars that start with T__
continue;
}
// Ignore alt if contains not only string literals (repetition, optional)
boolean ignore = false;
StringBuilder currentValue = new StringBuilder();
for (int i = 0; i < rootNode.getChildCount(); i++) {
Tree child = rootNode.getChild(i);
if (!(child instanceof TerminalAST)) {
ignore = true;
break;
}
TerminalAST terminalAST = (TerminalAST) child;
if (terminalAST.token.getType() != ANTLRLexer.STRING_LITERAL) {
ignore = true;
break;
} else {
String text = terminalAST.token.getText();
currentValue.append(text.substring(1, text.length() - 1));
}
}
if (!ignore) {
values.add(currentValue.toString());
}
}
}
return values;
}
use of org.antlr.v4.tool.ast.TerminalAST in project antlr4 by antlr.
the class Tool method checkForRuleIssues.
/**
* Important enough to avoid multiple definitions that we do very early,
* right after AST construction. Also check for undefined rules in
* parser/lexer to avoid exceptions later. Return true if we find multiple
* definitions of the same rule or a reference to an undefined rule or
* parser rule ref in lexer rule.
*/
public boolean checkForRuleIssues(final Grammar g) {
// check for redefined rules
GrammarAST RULES = (GrammarAST) g.ast.getFirstChildWithType(ANTLRParser.RULES);
List<GrammarAST> rules = new ArrayList<GrammarAST>(RULES.getAllChildrenWithType(ANTLRParser.RULE));
for (GrammarAST mode : g.ast.getAllChildrenWithType(ANTLRParser.MODE)) {
rules.addAll(mode.getAllChildrenWithType(ANTLRParser.RULE));
}
boolean redefinition = false;
final Map<String, RuleAST> ruleToAST = new HashMap<String, RuleAST>();
for (GrammarAST r : rules) {
RuleAST ruleAST = (RuleAST) r;
GrammarAST ID = (GrammarAST) ruleAST.getChild(0);
String ruleName = ID.getText();
RuleAST prev = ruleToAST.get(ruleName);
if (prev != null) {
GrammarAST prevChild = (GrammarAST) prev.getChild(0);
g.tool.errMgr.grammarError(ErrorType.RULE_REDEFINITION, g.fileName, ID.getToken(), ruleName, prevChild.getToken().getLine());
redefinition = true;
continue;
}
ruleToAST.put(ruleName, ruleAST);
}
// check for undefined rules
class UndefChecker extends GrammarTreeVisitor {
public boolean badref = false;
@Override
public void tokenRef(TerminalAST ref) {
if ("EOF".equals(ref.getText())) {
// this is a special predefined reference
return;
}
if (g.isLexer())
ruleRef(ref, null);
}
@Override
public void ruleRef(GrammarAST ref, ActionAST arg) {
RuleAST ruleAST = ruleToAST.get(ref.getText());
String fileName = ref.getToken().getInputStream().getSourceName();
if (Character.isUpperCase(currentRuleName.charAt(0)) && Character.isLowerCase(ref.getText().charAt(0))) {
badref = true;
errMgr.grammarError(ErrorType.PARSER_RULE_REF_IN_LEXER_RULE, fileName, ref.getToken(), ref.getText(), currentRuleName);
} else if (ruleAST == null) {
badref = true;
errMgr.grammarError(ErrorType.UNDEFINED_RULE_REF, fileName, ref.token, ref.getText());
}
}
@Override
public ErrorManager getErrorManager() {
return errMgr;
}
}
UndefChecker chk = new UndefChecker();
chk.visitGrammar(g.ast);
return redefinition || chk.badref;
}
use of org.antlr.v4.tool.ast.TerminalAST in project antlr4 by antlr.
the class ParserATNFactory method tokenRef.
/**
* From label {@code A} build graph {@code o-A->o}.
*/
@Override
public Handle tokenRef(TerminalAST node) {
ATNState left = newState(node);
ATNState right = newState(node);
int ttype = g.getTokenType(node.getText());
left.addTransition(new AtomTransition(right, ttype));
node.atnState = left;
return new Handle(left, right);
}
Aggregations