1

I'm new to ANTLR and currently I'm trying to use ANTLR 3.1.3 with Python. I've already installed successfully ANTLR runtime for Python. But I don't know how to print out the parse tree of a particular input.

Grammar

grammar Expr;

options {
    language=Python;
    output=AST;
}

expr    :   atom (op atom)* NEWLINE ;
op  :   '+' | '-';
atom    :   ID | INT;
ID  :   ('a'..'z'|'A'..'Z')+ ;  
INT     :   ('0'..'9')+ ;
NEWLINE :   '\r'? '\n' ;
WS  :   (' '|'\t'|'\n'|'\r')+ {self.skip()} ;

Python code

import sys
import antlr3
from antlr3 import *
from ExprLexer import ExprLexer
from ExprParser import ExprParser

# test the parser with an input
char_stream = antlr3.ANTLRStringStream('3+5\n')
lexer = ExprLexer(char_stream)
tokens = antlr3.CommonTokenStream(lexer)
parser = ExprParser(tokens)

# print the parse tree
t = parser.expr().tree
print t.toStringTree()

Although what I want when the code's executed is the parse tree. The code will print out '3+5' only.

Would you please tell me how to modify the code to get the parse tree printed?

2 Answers 2

1

Some weeks ago, I wanted to print out the ANTLR AST (not the parse tree, but it depends on how you implemented your grammar..) for debugging purposes.

You can do something very easy like:

def print_tree(tree, lev):
    print (" " * lev) + "` " + str(tree)
    for c in tree.getChildren():
        print_tree(c, lev + 1)

print_tree(parser.expr().tree, 0)

NB: I've written the code directly in SO, so it is untested

Sign up to request clarification or add additional context in comments.

Comments

0

Here is another version...

from antlr4 import *
from antlr4.tree.Tree import TerminalNodeImpl
from antlr4.tree.Trees import Trees

def dump(node, depth=0, ruleNames=None):
    depthStr = '. ' * depth
    if isinstance(node, TerminalNodeImpl):
        print(f'{depthStr}{node.symbol}')
    else:
        print(f'{depthStr}{Trees.getNodeText(node, ruleNames)}')
        for child in node.children:
            dump(child, depth + 1, ruleNames)


def test_parse_tree():
    istream = FileStream(INFILE, encoding='utf-8')
    lexer = MyLexer(istream)
    stream = CommonTokenStream(lexer)
    parser = MyParser(stream)
    tree = parser.MAINRULE()
    print(tree.toStringTree(recog=parser))  # lisp repr of tree
    dump(tree, ruleNames=parser.ruleNames)  # pretty printed version

It yields output like so...

prog
. line
. . text
. . . [@0,0:0='@',<5>,1:0]
. . cmnt
. . . [@1,1:2='\n@',<1>,1:1]
. . . [@2,3:3=' ',<4>,2:1]
. . . text
. . . . [@3,4:4=' ',<4>,2:2]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.