Example

Skip to end of metadata
Go to start of metadata

Book Examples Modified for Python

The code snippets below are my adaptations of the tree walking example files from chapter 3 in The Book to make them work with Python.

Notes

  • Set language=Python option in both .g files
  • In Eval.g I had to change references to $INT.text and $ID.text to $INT.getText() and $ID.getText() respectively
  • In Eval.g I had to use @init{} instead of @members{} action to initialize memory variable
  • In Expr.g I had to use self.skip() instead of just skip()
  • Based Test.py on example from Antlr3PythonTarget

Expr.g 

grammar Expr;

options {
	language=Python;
	output=AST;
	ASTLabelType=CommonTree;
}

prog	: ( stat {print $stat.tree.toStringTree();} )+ ;

stat	:	expr NEWLINE        -> expr
	|	ID '=' expr NEWLINE -> ^('=' ID expr)
	|	NEWLINE             ->
	;

expr	:	multExpr (('+'^|'-'^) multExpr)*
	;

multExpr
	:	atom ('*'^ atom)*
	;

atom	:	INT
	|	ID
	|	'('! expr ')'!
	;

ID	:	('a'..'z'|'A'..'Z')+ ;

INT	:	'0'..'9'+ ;

NEWLINE	:	'\r'? '\n' ;

WS	:	(' '|'\t'|'\n'|'\r')+ {self.skip()} ;

Eval.g

tree grammar Eval;

options {
    language=Python;
    tokenVocab=Expr;
    ASTLabelType=CommonTree;
}

@init {self.memory = {}}

// START:stat
prog:   stat+ ;

stat:   expr
        {print $expr.value}
    |   ^('=' ID expr)
        {self.memory[$ID.getText()] = int($expr.value)}
    ;
// END:stat

// START:expr
expr returns [value]
    :   ^('+' a=expr b=expr) {$value = a+b;}
    |   ^('-' a=expr b=expr) {$value = a-b;}
    |   ^('*' a=expr b=expr) {$value = a*b;}
    |   ID
        {
k = $ID.getText()
if k in self.memory:
	$value = self.memory[k]
else:
	print >> sys.stderr, "undefined variable "+k
        }
    |   INT {$value = int($INT.getText())}
    ;
// END:expr

Test.py

import sys
import antlr3
import antlr3.tree
from ExprLexer import ExprLexer
from ExprParser import ExprParser
from Eval import Eval

char_stream = antlr3.ANTLRInputStream(sys.stdin)
lexer = ExprLexer(char_stream)
tokens = antlr3.CommonTokenStream(lexer)
parser = ExprParser(tokens)
r = parser.prog()

# this is the root of the AST
root = r.tree

nodes = antlr3.tree.CommonTreeNodeStream(root)
nodes.setTokenStream(tokens)
eval = Eval(nodes)
eval.prog()

Labels: