[antlr-interest] Python How To Convert from Java
Bob Adolf
rdadolf at gmail.com
Fri Feb 26 12:04:18 PST 2010
Hi Remy,
I think you'll be surprised at how similar the python and java
versions actually are. You made things a little more difficult for
yourself than you needed. I've put some comments in-line with your
original python code and finished off the end.
> import antlr3
> import antlr3.tree
> from sqltestLexer import sqltestLexer
> from sqltestParser import sqltestParser
> #import sqltest ? won't import
The grammar sqltest.g actually doesn't produce an sqltest file or
class, so you just need the first two.
> import sys
> #from sqltest import sqltest
> #sys.argv[1]
> char_stream = antlr3.ANTLRStringStream("SELECT * FROM BOOKS;")
Your grammar actually doesn't parse this phrase, but I assume you just
forgot to replace the place-holder string with something else. I used
this instead:
char_stream = antlr3.ANTLRStringStream("CREATE TABLE foo ( bar int ) ;")
which (not knowing SQL) seems to fit your grammar at least.
It seems like you tried using an input file first. I'm assuming that
you want something like your original java file that selects between a
file or a string. Well, it looks very much like the java version:
if( len(sys.argv)>1 ):
char_stream = antlr3.ANTLRFileStream(sys.argv[1])
else:
char_stream = antlr3.ANTLRStringStream(raw_input("SQL>"))
> lexer = sqltestLexer(char_stream)
> tokens = antlr3.CommonTokenStream(lexer)
> parser = sqltestParser(tokens)
>
> r = parser.createtablestmt_return()
You'll actually want to call the function itself. The types are
handled automatically, so you can focus on the work that's actually
being done. The function parser.createtablestmt (which you can look at
directly in sqltestParser.py) is ANTLR's translation of your root-
level grammar rule. You can walk through the logic in the python
source as it tries to match against input tokens and recursively
invokes the other rules.
r = parser.createtablestmt()
Interestingly enough, this is where your java version stops. You just
print out the tree element.
# System.out.println("tablename ="+
((Tree)r.tree).getChild(2).toString());
# System.out.println("tree="+((Tree)r.tree).toStringTree());
You can do the same thing in python!
print "tablename = " + r.tree.children[2].toString()
print "tree = " + r.tree.toStringTree()
>
> # this is the root of the AST
> root = r.tree
>
> nodes = antlr3.tree.CommonTreeNodeStream(root)
> nodes.setTokenStream(tokens)
>
> #walker = sqltest(nodes)
> # STUCK!
As for the rest of this, it looks like you started trying to implement
a tree walker. If you're serious about munging the AST, you'll
probably want to do this later, but for simple things like just
dumping the tree, you don't need to. Likewise, if you're just doing a
simple extraction of SQL snippets or some easy translation, you can do
it directly by inserting actions into your parser at the appropriate
place.
If you do decide that a tree walker is what you need, then you'll need
to create a separate grammar for that (and this is why you got stuck,
there was nothing you could invoke because you hadn't written a tree
parser). You should probably run through the python examples (http://www.antlr.org/download/examples-v3.tar.gz
) or the ANTLR book if you're going to do that.
Hope this helps.
-Bob
For clarity, here's the whole file I used (driver.py):
import antlr3
from sqltestLexer import sqltestLexer
from sqltestParser import sqltestParser
import sys
if( len(sys.argv)>1 ):
char_stream = antlr3.ANTLRFileStream(sys.argv[1])
else:
char_stream = antlr3.ANTLRStringStream(raw_input("SQL>"))
lexer = sqltestLexer(char_stream)
tokens = antlr3.CommonTokenStream(lexer)
parser = sqltestParser(tokens)
r = parser.createtablestmt()
# System.out.println("tablename ="+
((Tree)r.tree).getChild(2).toString());
# System.out.println("tree="+((Tree)r.tree).toStringTree());
print "tablename = " + r.tree.children[2].toString()
print "tree = " + r.tree.toStringTree()
And the output:
tablename = foo
tree = CREATE TABLE foo ( bar int )
More information about the antlr-interest
mailing list