Search in sources :

Example 51 with Tree

use of org.antlr.v4.runtime.tree.Tree in project antlr4 by antlr.

the class LeftRecursiveRuleAnalyzer method text.

public String text(GrammarAST t) {
    if (t == null)
        return "";
    int tokenStartIndex = t.getTokenStartIndex();
    int tokenStopIndex = t.getTokenStopIndex();
    // ignore tokens from existing option subtrees like:
    //    (ELEMENT_OPTIONS (= assoc right))
    //
    // element options are added back according to the values in the map
    // returned by getOptions().
    IntervalSet ignore = new IntervalSet();
    List<GrammarAST> optionsSubTrees = t.getNodesWithType(ELEMENT_OPTIONS);
    for (GrammarAST sub : optionsSubTrees) {
        ignore.add(sub.getTokenStartIndex(), sub.getTokenStopIndex());
    }
    // Individual labels appear as RULE_REF or TOKEN_REF tokens in the tree,
    // but do not support the ELEMENT_OPTIONS syntax. Make sure to not try
    // and add the tokenIndex option when writing these tokens.
    IntervalSet noOptions = new IntervalSet();
    List<GrammarAST> labeledSubTrees = t.getNodesWithType(new IntervalSet(ASSIGN, PLUS_ASSIGN));
    for (GrammarAST sub : labeledSubTrees) {
        noOptions.add(sub.getChild(0).getTokenStartIndex());
    }
    StringBuilder buf = new StringBuilder();
    int i = tokenStartIndex;
    while (i <= tokenStopIndex) {
        if (ignore.contains(i)) {
            i++;
            continue;
        }
        Token tok = tokenStream.get(i);
        // Compute/hold any element options
        StringBuilder elementOptions = new StringBuilder();
        if (!noOptions.contains(i)) {
            GrammarAST node = t.getNodeWithTokenIndex(tok.getTokenIndex());
            if (node != null && (tok.getType() == TOKEN_REF || tok.getType() == STRING_LITERAL || tok.getType() == RULE_REF)) {
                elementOptions.append("tokenIndex=").append(tok.getTokenIndex());
            }
            if (node instanceof GrammarASTWithOptions) {
                GrammarASTWithOptions o = (GrammarASTWithOptions) node;
                for (Map.Entry<String, GrammarAST> entry : o.getOptions().entrySet()) {
                    if (elementOptions.length() > 0) {
                        elementOptions.append(',');
                    }
                    elementOptions.append(entry.getKey());
                    elementOptions.append('=');
                    elementOptions.append(entry.getValue().getText());
                }
            }
        }
        // add actual text of the current token to the rewritten alternative
        buf.append(tok.getText());
        // move to the next token
        i++;
        // Are there args on a rule?
        if (tok.getType() == RULE_REF && i <= tokenStopIndex && tokenStream.get(i).getType() == ARG_ACTION) {
            buf.append('[' + tokenStream.get(i).getText() + ']');
            i++;
        }
        // now that we have the actual element, we can add the options.
        if (elementOptions.length() > 0) {
            buf.append('<').append(elementOptions).append('>');
        }
    }
    return buf.toString();
}
Also used : IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) GrammarAST(org.antlr.v4.tool.ast.GrammarAST) Token(org.antlr.runtime.Token) CommonToken(org.antlr.runtime.CommonToken) GrammarASTWithOptions(org.antlr.v4.tool.ast.GrammarASTWithOptions) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 52 with Tree

use of org.antlr.v4.runtime.tree.Tree in project antlr4 by antlr.

the class LeftRecursiveRuleTransformer method translateLeftRecursiveRule.

/** 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) {
        // didn't match; oh well
        isLeftRec = false;
    }
    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;
        // todo: isn't this Rule or something?
        arg.resolver = r.alt[1];
    }
    // 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;
}
Also used : RuleAST(org.antlr.v4.tool.ast.RuleAST) RuleCollector(org.antlr.v4.semantics.RuleCollector) GrammarAST(org.antlr.v4.tool.ast.GrammarAST) LabelElementPair(org.antlr.v4.tool.LabelElementPair) ActionAST(org.antlr.v4.tool.ast.ActionAST) GrammarTransformPipeline(org.antlr.v4.tool.GrammarTransformPipeline) BasicSemanticChecks(org.antlr.v4.semantics.BasicSemanticChecks) RecognitionException(org.antlr.runtime.RecognitionException)

Example 53 with Tree

use of org.antlr.v4.runtime.tree.Tree in project antlr4 by antlr.

the class TestVisitors method testShouldNotVisitTerminal.

/**
	 * This test verifies that {@link AbstractParseTreeVisitor#shouldVisitNextChild} is called before visiting the first
	 * child. It also verifies that {@link AbstractParseTreeVisitor#defaultResult} provides the default return value for
	 * visiting a tree.
	 */
@Test
public void testShouldNotVisitTerminal() {
    String input = "A";
    VisitorBasicLexer lexer = new VisitorBasicLexer(new ANTLRInputStream(input));
    VisitorBasicParser parser = new VisitorBasicParser(new CommonTokenStream(lexer));
    VisitorBasicParser.SContext context = parser.s();
    Assert.assertEquals("(s A <EOF>)", context.toStringTree(parser));
    VisitorBasicVisitor<String> listener = new VisitorBasicBaseVisitor<String>() {

        @Override
        public String visitTerminal(TerminalNode node) {
            throw new RuntimeException("Should not be reachable");
        }

        @Override
        protected String defaultResult() {
            return "default result";
        }

        @Override
        protected boolean shouldVisitNextChild(RuleNode node, String currentResult) {
            return false;
        }
    };
    String result = listener.visit(context);
    String expected = "default result";
    Assert.assertEquals(expected, result);
}
Also used : CommonTokenStream(org.antlr.v4.runtime.CommonTokenStream) RuleNode(org.antlr.v4.runtime.tree.RuleNode) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) ANTLRInputStream(org.antlr.v4.runtime.ANTLRInputStream) Test(org.junit.Test)

Example 54 with Tree

use of org.antlr.v4.runtime.tree.Tree in project antlr4 by antlr.

the class BaseBrowserTest method writeParserTestFile.

protected void writeParserTestFile(String parserName, String lexerName, String listenerName, String visitorName, String parserStartRuleName, boolean debug) {
    String html = "<!DOCTYPE html>\r\n" + "<html>\r\n" + "	<head>\r\n" + "		<script src='lib/require.js'></script>\r\n" + "		<script>\r\n" + "			antlr4 = null;\r\n" + "			listener = null;\r\n" + "			TreeShapeListener = null;\r\n" + "			" + lexerName + " = null;\r\n" + "			" + parserName + " = null;\r\n" + "			" + listenerName + " = null;\r\n" + "			" + visitorName + " = null;\r\n" + "			printer = function() {\r\n" + "				this.println = function(s) { document.getElementById('output').value += s + '\\n'; }\r\n" + "				this.print = function(s) { document.getElementById('output').value += s; }\r\n" + "				return this;\r\n" + "			};\r\n" + "\r\n" + "			loadParser = function() {\r\n" + "				try {\r\n" + "					antlr4 = require('antlr4/index');\r\n" + "					" + lexerName + " = require('./parser/" + lexerName + "');\n" + "					" + parserName + " = require('./parser/" + parserName + "');\n" + "					" + listenerName + " = require('./parser/" + listenerName + "');\n" + "					" + visitorName + " = require('./parser/" + visitorName + "');\n" + "				} catch (ex) {\r\n" + "					document.getElementById('errors').value = ex.toString();\r\n" + "				}\r\n" + "\r\n" + "				listener = function() {\r\n" + "					antlr4.error.ErrorListener.call(this);\r\n" + "					return this;\r\n" + "				}\r\n" + "				listener.prototype = Object.create(antlr4.error.ErrorListener.prototype);\r\n" + "				listener.prototype.constructor = listener;\r\n" + "				listener.prototype.syntaxError = function(recognizer, offendingSymbol, line, column, msg, e) {\r\n" + "    				document.getElementById('errors').value += 'line ' + line + ':' + column + ' ' + msg + '\\r\\n';\r\n" + "				};\r\n" + "\r\n" + "				TreeShapeListener = function() {\r\n" + "					antlr4.tree.ParseTreeListener.call(this);\r\n" + "					return this;\r\n" + "				};\r\n" + "\r\n" + "				TreeShapeListener.prototype = Object.create(antlr4.tree.ParseTreeListener.prototype);\r\n" + "				TreeShapeListener.prototype.constructor = TreeShapeListener;\r\n" + "\r\n" + "				TreeShapeListener.prototype.enterEveryRule = function(ctx) {\r\n" + "					for(var i=0;i<ctx.getChildCount; i++) {\r\n" + "						var child = ctx.getChild(i);\r\n" + "						var parent = child.parentCtx;\r\n" + "						if(parent.getRuleContext() !== ctx || !(parent instanceof antlr4.tree.RuleNode)) {\r\n" + "							throw 'Invalid parse tree shape detected.';\r\n" + "						}\r\n" + "					}\r\n" + "				};\r\n" + "			}\r\n" + "\r\n" + "			test = function() {\r\n" + "				document.getElementById('output').value = ''\r\n" + "				var input = document.getElementById('input').value;\r\n" + "			var stream = new antlr4.InputStream(input, true);\n" + "    			var lexer = new " + lexerName + "." + lexerName + "(stream);\n" + "				lexer._listeners = [new listener()];\r\n" + "    			var tokens = new antlr4.CommonTokenStream(lexer);\n" + "				var parser = new " + parserName + "." + parserName + "(tokens);\n" + "				parser._listeners.push(new listener());\n" + (debug ? "				parser._listeners.push(new antlr4.error.DiagnosticErrorListener());\n" : "") + "    			parser.buildParseTrees = true;\n" + "    			parser.printer = new printer();\n" + "    			var tree = parser." + parserStartRuleName + "();\n" + "    			antlr4.tree.ParseTreeWalker.DEFAULT.walk(new TreeShapeListener(), tree);\n" + "			};\r\n" + "\r\n" + "		</script>\r\n" + "	</head>\r\n" + "	<body>\r\n" + "		<textarea id='input'></textarea><br>\r\n" + "		<button id='load' type='button' onclick='loadParser()'>Load</button><br>\r\n" + "		<button id='submit' type='button' onclick='test()'>Test</button><br>\r\n" + "		<textarea id='output'></textarea><br>\r\n" + "		<textarea id='errors'></textarea><br>\r\n" + "	</body>\r\n" + "</html>\r\n";
    writeFile(httpdir, "Test.html", html);
}
Also used : STGroupString(org.stringtemplate.v4.STGroupString) BaseRuntimeTest.antlrOnString(org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString)

Example 55 with Tree

use of org.antlr.v4.runtime.tree.Tree in project antlr4 by antlr.

the class BaseJavaTest method execStartRule.

public ParseTree execStartRule(String startRuleName, Parser parser) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    Method startRule = null;
    Object[] args = null;
    try {
        startRule = parser.getClass().getMethod(startRuleName);
    } catch (NoSuchMethodException nsme) {
        // try with int _p arg for recursive func
        startRule = parser.getClass().getMethod(startRuleName, int.class);
        args = new Integer[] { 0 };
    }
    ParseTree result = (ParseTree) startRule.invoke(parser, args);
    //		System.out.println("parse tree = "+result.toStringTree(parser));
    return result;
}
Also used : JavaFileObject(javax.tools.JavaFileObject) Method(java.lang.reflect.Method) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Aggregations

ParseTree (org.antlr.v4.runtime.tree.ParseTree)30 CommonTokenStream (org.antlr.v4.runtime.CommonTokenStream)21 ANTLRInputStream (org.antlr.v4.runtime.ANTLRInputStream)15 GrammarAST (org.antlr.v4.tool.ast.GrammarAST)12 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)9 ParseCancellationException (org.antlr.v4.runtime.misc.ParseCancellationException)8 ByteArrayInputStream (java.io.ByteArrayInputStream)6 InputStream (java.io.InputStream)6 ArrayList (java.util.ArrayList)6 BailErrorStrategy (org.antlr.v4.runtime.BailErrorStrategy)6 Tree (org.antlr.v4.runtime.tree.Tree)6 IOException (java.io.IOException)5 Tree (org.antlr.runtime.tree.Tree)4 ParserInterpreter (org.antlr.v4.runtime.ParserInterpreter)4 RecognitionException (org.antlr.v4.runtime.RecognitionException)4 Rectangle2D (java.awt.geom.Rectangle2D)3 FileInputStream (java.io.FileInputStream)3 Method (java.lang.reflect.Method)3 Map (java.util.Map)3 GrammarASTAdaptor (org.antlr.v4.parse.GrammarASTAdaptor)3