i am using jjtree to try to parse a string such as (pseudo-code):
f( [ expression() ( "," expression() )* ] )
it will correctly parse arguments to functions such as: f(1, 2, 4)
i'd like it to be able to parse functions of them form: f(1,,3) or
f(,,,)
where the null arguments are parsed as 'null tokens'. how can i do
that?
something with the effect of this
t = <NOTHING>
{
if ("".equals(t.image)) {
jjtThis.setLiteral(t.image, NULL_LITERAL);
} else {...}
}
thanks.
Note that your syntax cannot distinguish passing a single null argument
and passing no arguments.
It looks like you are trying to force tokens where there none. In stead,
you should use the parser BNF part.
void Arguments():
{
Node n;
}
{
"("
( {n = null; }
( n=Expression() )?
","
{
if (n == null)
// do your NULL thing
}
)*
")"
}
> i am having trouble specifying a grammar which can parse negative
> integers as negative integer tokens rather than a unary minus
> operation in front of a positive integer. i've tried a couple of
> things but i end up creating a parser that either doesnt compile or
> confuses the subtraction operator with the unary minus operation and
> so forth.
>
> for example,
>
> i'd like to have
>
> 1. f(-1) parse as f acting on the token -1
> 2. -1+1 parse as addition of the token -1 and 1
> 3. -1^1 parse as unary negation times 1^1 (where ^ is exponentiation)
> 4. 1^-1 to give a parser error
> 5. 1-1 to parse as the token 1, the operation 'subtraction', and the
> token 1
> 6(optional or parser error). 1--1 to parse as the token 1, the
> operation 'subtraction', and the token -1.
I also saw the above message from you about the unary minus and negative
int literals. You have the same issue of trying to do things in the
regular expression (Token) part whereas you should be doing this in the
parrser. You need to parse unary minus as an operator if you want to
satisfy all your constraints. There is no way to do it using tokens.
Sreeni.
thanks sreeni.
its a little intimidating to veer too far off from the examples given with
the javacc distribution. i followed your advice and this is what i came up
with:
void function() #TreeNode :
{ Token t; }
{
t = <NAME> ( "()" |
("(" function_argument() ("," function_argument() )* ")" ) )
{ jjtThis.setOperator(t.image); }
}
void function_argument() :
{ int n; }
{
{ n = 0; }
( n = relational() )?
{
/**
* If its a null argument, we manually create a null
* literal node and add it to the tree. */
if (n == 0 ) {
ASTTreeNode t = new ASTTreeNode(0);
t.setLiteral("", ASTTreeNode.NULL_LIT);
jjtree.pushNode(t);
}
}
}
relational() returns 1 always. ASTTreeNode is my jjtree node type with a
member function 'setLiteral'. if i could improve on this more or make it
more concise, please let me know, so i can improve my understanding.
i wasnt sure what to do with the SimpleNode 'id' constructor argument so i
just set it to zero.
void function_argument() #void :
{}
{
relational() #FUNCTIONARG
|
{} #NOFUNCTIONARG
}
--------
void function() #TreeNode :
{ Token t; }
{
t = <NAME> ( "()" |
("(" function_argument() ("," function_argument() )* ")" ) )
{ jjtThis.setOperator(t.image); }
}
The weird thing here is that you are parsing "()" as one
token. Thus "f()" will be result in one tree, while "f( )"
will result in another. Is that really what you want?
Cheers,
Theodore Norvell