[antlr-interest] More on TokenWithIndex
Paul J. Lucas
pauljlucas at mac.com
Sun Oct 31 15:33:36 PST 2004
I've been playing with this stuff for several days now and have
something that works well.
I modified Terence's ASTMinMax class and added a Visitor
interface.
To solve the left-factored problem, I do:
declareThing
: d:DECLARE! { markTokenIndex( d ); }
( functionDecl
| varDecl
| // ...
)
;
where markTokenIndex() simply sets a parser class variable that
can be obtained later; then:
varDecl
: v:VARIABLE^ varRefTypeDecl ASSIGN! expr semi:SEMICOLON!
{
#v.setType( VAR_DECL );
#v.setText( "VAR_DECL" );
setMinMaxIndex( #v, semi );
}
;
where the two-argument form of setMinMaxIndex() sets the min/max
indicies of #v to the previously-marked token and the semicolon.
There are many overloaded variations of setMinMaxIndex(): some
taken tokens as arguments, some take AST nodes, and combinations
of both.
Most rules don't need any call to setMinMaxIndex() at all. The
only ones that do are for left-factored rules as shown and also
for those where the max index is a non-included terminal, e.g.,:
parenthesizedExpr
: lp:LPAREN! expr rp:RPAREN!
{
setMinMaxIndex( ##, lp, rp );
}
;
or:
functionCall
: f:FUNCTION_NAME LPAREN! (exprList)? rp:RPAREN!
{
#f.setType( FUNCTION_CALL );
#f.setText( "FUNCTION_CALL" );
setMinMaxIndex( #f, f, rp );
}
;
Note that "#f" refers to the AST node and 'f' refers to the
token.
To set all the min/max indicies for the entire tree once it's
completely built, I have a visitor that post-order traverses
it. As part of the initialize() method on my derived AST
class, I do:
m_maxTokenIndex = 0;
m_minTokenIndex = Integer.MAX_VALUE;
then the visitor does:
public void visit( XQueryAST node, int visitType, int depth ) {
if ( visitType == PREVISIT )
return;
int mostMin = node.getMinIndex(),
mostMax = node.getMaxIndex();
for ( XQueryAST child = (XQueryAST)node.getFirstChild();
child != null;
child = (XQueryAST)child.getNextSibling()
) {
final int min = child.getMinIndex();
final int max = child.getMaxIndex();
if ( min < mostMin )
mostMin = min;
if ( max > mostMax )
mostMax = max;
}
node.setMinMaxIndex( mostMin, mostMax );
}
Hence, the token index information propagates bottup-up from
the terminals to the root of the AST.
By doing the setting of min/max once during a single-pass
traversal, I can avoid the inefficient way it was done in
TrackerASTFactory.
- Paul
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/antlr-interest/
<*> To unsubscribe from this group, send an email to:
antlr-interest-unsubscribe at yahoogroups.com
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
More information about the antlr-interest
mailing list