[antlr-interest] array list action attributes

Aaron Leiby aleiby.antlr at gmail.com
Sat Jan 8 14:43:07 PST 2011


The args will only be in a vector when using the += operator to gather them
rather than processing things as they are matched, right?  (Which had been
suggested not to use the += but handle them as they are matched instead -
which I agree would be preferable.)

A concrete example may help clear things up.  Here's my tree parser for
functionLiteral.

functionLiteral returns [LLVMValueRef value]
scope Symbols, Function;
@init
{
$Symbols::table = antlr3HashTableNew(11);
SCOPE_TOP(Symbols)->free = freeTable;
const char* function_name = "";
}
@after
{
BuildReturn($Function::ref);
}
: ^( FUNC ( name=NameLiteral { function_name = (const char
*)$name.text->chars; } )?
^( PARAMS args+=NameLiteral* )
{
ANTLR3_UINT32 count = $args ? $args->count : 0;
$Function::ref = CreateFunction(function_name, count);
 for (int i = 0; i < count; i++)
{
pANTLR3_BASE_TREE arg = (pANTLR3_BASE_TREE)$args->get($args, i);
const char* name = (const char *)arg->getText(arg)->chars;
LLVMValueRef value = NameParam($Function::ref, i, name);
addSymbol(ctx, value, name);
}
 addSymbol(ctx, $Function::ref, function_name);
$value = $Function::ref;
}
block[function_name] )
;

The arguments are gathered, to create a function object with the appropriate
number of parameters.  The way I would prefer this to work would be to
create the function object first, and then update the parameters as they are
matched.

functionLiteral returns [LLVMValueRef value]
scope Symbols, Function;
@init
{
$Symbols::table = antlr3HashTableNew(11);
SCOPE_TOP(Symbols)->free = freeTable;
const char* function_name = "";
int i = 0;
}
@after
{
BuildReturn($Function::ref);
}
: ^( FUNC name=NameLiteral?
{
function_name = $name ? (const char *)$name.text->chars : "";
$Function::ref = CreateFunction(function_name, count); //!! need count
addSymbol(ctx, $Function::ref, function_name);
$value = $Function::ref;
}
^( PARAMS ( arg=NameLiteral
{
const char* name = (const char *)$arg.text->chars;
LLVMValueRef value = NameParam($Function::ref, i++, name);
addSymbol(ctx, value, name);
} )* )
block[function_name] )
;

Does that make more sense?  I need the count (ideally) before I parse the
parameters.

On Sat, Jan 8, 2011 at 12:51 PM, Jim Idle <jimi at temporal-wave.com> wrote:

> Don’t do that. The count will be available to you in the tree parser as the
> args will be in a vector and you can reference the count of the list. You
> are trying to do too much in the parser basically.
>
>
>
> Jim
>
>
>
> *From:* Aaron Leiby [mailto:aleiby.antlr at gmail.com]
> *Sent:* Saturday, January 08, 2011 12:37 PM
> *To:* Jim Idle
> *Cc:* antlr-interest
> *Subject:* Re: [antlr-interest] array list action attributes
>
>
>
> I would prefer to handle the actions as suggested above, but in most cases
> I
> need to know how many elements exist first.  So what I've been doing is
> collecting them, getting the count, then processing them.
>
>
>
> This is all in a tree walker grammar.  Is there an easy way to write out
> the
> count in the lexer/parser grammar rewrite rules so it's available to the
> tree walker without having to gather them first as I've been doing?
>
>
>
> For example, I'd like to be able to do something like this (in the
> lexer/parser grammar):
>
>
>
> functionLiteral
>
>          :           'function' name=NameLiteral? args=parameters
> body=block
>
>          ->         ^( FUNC $name? $args->count $args $body )
>
>          ;
>
>
>
> But the $args->count obviously won't work since the output tree is
> homogenous.  I imagine there might be a way to create a dummy node with the
> value as a payload, but I haven't tracked down the syntax for that yet.
>
>
>
> Perhaps I'm still going about this the wrong way?
>
>
>
> > the vector access functions are all documented in the API and there
>
> > a copious examples if you read through the runtime source code.
>
>
>
> Yep.  I was more hoping that there was higher level syntax in the ANTLR
> language itself that could be used to autogenerate the API calls when
> working with those vectors (making the grammar a bit more portable in the
> process).  I was aware of the single element support (e.g. $arg.text), and
> hoped I had simply missed the multi-value support.  Failing that, I was
> familiar with the SCOPE macros that the C target provides for hiding some
> of
> the data structure API details, and imagined similar macros had been
> created
> for working with the += output that I had maybe missed.  It sounds like
> neither of those are the case, so working directly with the API calls is
> the
> correct/only path currently.
>
>
>
> Thanks!
>
>
>
> On Mon, Jan 3, 2011 at 10:27 AM, Jim Idle <jimi at temporal-wave.com> wrote:
>
> The += syntax is really only used for tree rewriting, but the vector
> access functions are all documented in the API and there a copious
> examples if you read through the runtime source code.
>
> Unless you don't care too much about memory (memory for the STRINGs is not
> released until you free the parser), then I would just get the pointers
> from the token directly and copy whatever text you want from there.
>
> However, I think that your confusion here is that you are gathering a list
> then trying to process it afterwards, where I think you will find it more
> useful to do this (and note that you use + as otherwise if there are no
> IDs then it is just a TYPE alt):
>
> : TYPE // No IDs
> | ^(TYPE
>
>     (
>       i=ID { some code that does $i.whatever }
>     )+
>  )
>  { action code to finish up }
> ;
>
>
> Jim
>
>
> > -----Original Message-----
> > From: antlr-interest-bounces at antlr.org [mailto:antlr-interest-
> > bounces at antlr.org] On Behalf Of Aaron Leiby
> > Sent: Sunday, January 02, 2011 7:30 PM
> > To: antlr-interest
> > Subject: [antlr-interest] array list action attributes
> >
> > ANTLR3 allows labeling attributes for referencing in actions.
> >
> > Example:
> >
> > decl: type id=ID ';' { print "var" + $id.text; }
> >
> > With the C language target, the $id.text gets converted nicely into:
> >
> > (id->getText(id))
> >
> > However, if you have more than one attribute:
> >
> > decl: ^( TYPE ids+=ID* )
> >
> > ...$ids becomes a pANTLR3_VECTOR, and it appears those helpful
> > attributes no longer work?
> >
> > I was hoping something like $ids[i].text would get automatically
> > converted.
> >  Instead, I had to dig into the implementation a bit and hand-expand it
> > to:
> >
> > pANTLR_BASE_TREE id = (pANTLR_BASE_TREE)$ids->get($ids, i); const char*
> > name = (const char*)id->getText(id)->chars;
> >
> > So, I guess a couple questions:
> >
> > 1) Does the java language option suffer the same fate?  (i.e. ANTLR3
> > simply does not provide syntax for working with attributes on multi-
> > value labels?)
> > 2) Does the C API provide some nice macros I may have missed for making
> > this less gross?  (e.g. its set of SCOPE accessors)
> >
> > Thanks,
> > Aaron
> >
>
> > List: http://www.antlr.org/mailman/listinfo/antlr-interest
> > Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-
> > email-address
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe:
> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe:
> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>


More information about the antlr-interest mailing list