[antlr-interest] [C Target] How to skip a whole sub-tree (not just a token)

Mohamed Yousef harrrrpo at gmail.com
Sun Nov 15 07:07:38 PST 2009


well , sorry jim if i sound offensive , i didn't mean it :)
anyway , did you check the indices problem , was i right or was i reading it
from a wrong place
the indices of tokens in parser are the same of them tree parser they are
indices of lexical tokens not tree nodes in stream
take this example

if (c) then 10 else 20

EIF D EIF_COND D OPERAND c U U  EIF_THEN D 10 U  EIF_ELSE D 20 U U
(D => DOWN , U => UP)

EIF.start =0 , EIF.end=11 ( there are 10 lexems , in tree parser it should
be 0,16)
EIF_THEN.start = 8 , EIF_THEN.end=  8 (it's only the "10" lexeme there)

the problem is i'm in the middle of my senior project so i can't go back and
i can't wait wait for 3.2.1
so i had to find a solution myself , it may be useless by 3.2.1 but i can't
wait

@Claude
my approach is a bit different , it's better depicted by the C code (assume
all indices are recorded in savedIndex field) , i don't think Terence would
be counting UP's and DOWN's for jumping this would be really ineffecient
compared to jumping using saved indices

Parser grammar :

if_expr
    :KW_IF cond=expr_g  ( KW_THEN | KW_DO )  then=expr_g  (KW_ELSE
relse=expr_g)?

    -> ^(EIF ^(EIF_COND $cond) ^(EIF_THEN $then) ^(EIF_ELSE ($relse)?)
EIF_END )

    ;

tree Parser :

if_expr
    :
      ^( j= EIF ^(EIF_COND c =expr_g)
{TInterp::IfExpr::Exec($j,$c.start,ctx);}  )

the code for that method

pANTLR3_BASE_TREE r;
//cond is our condition imaginary node
if(*((Tvarp)(cond->u))).bool== BTrue )
{
    r=(pANTLR3_BASE_TREE)(ifnode->getChild(ifnode,1)); //first child is
'then' node
    SEEK(r->savedIndex);
    MATCHT(EIF_THEN,NULL);
    MATCHT(ANTLR3_TOKEN_DOWN,NULL);
    xyz->expr_g(xyz); //xyz is our ctx , generally this parses/interprets
the 'then' statments
    r=(pANTLR3_BASE_TREE)(ifnode->getChild(ifnode,3));//3 is our END_IF node
    SEEK(r->savedIndex);
    MATCHT(EIF_END,NULL);
}
else
{
    r=(pANTLR3_BASE_TREE)(ifnode->getChild(ifnode,2));
    SEEK(r->savedIndex);
    MATCHT(EIF_ELSE,NULL);
    if(LA(1)==ANTLR3_TOKEN_DOWN) //if we can go down , this means there is
'else' statement
    {
        MATCHT(ANTLR3_TOKEN_DOWN,NULL);
        xyz->expr_g(xyz);//go interpret it
    }
    MATCHT(ANTLR3_TOKEN_UP,NULL);
    MATCHT(EIF_END,NULL);
}

Regards,
Mohammed Yousef

2009/11/15 Claude Moulin <claude.moulin at hds.utc.fr>

>  Hello Mohamed,
>
> You are right. The parser consumes the nodes of the tree without doing
> nothing. I suppose it is based on DOWN and UP node matching. Terrence could
> explain better than me.
>
> For me the dot (.) metacharacter is only useful if it represents a tree,
> not a single node. The principle works well with a tree (I have if, for,
> while statements that which can be nested). If you may have a case with one
> single node, I advice to create a tree with a node based on an imaginary
> token.
>
> In my structure I have a IF tree with two or three child nodes which are
> trees.
>
> To be completely exact I mark before the then case and before the else case
> (not after the then case as you said). The else case may not be present in
> the tree and that’s why I test if the else_list node is not null.
>
> I wait the parser is ready to parse the instruction after the IF and then I
> push the index I have marked, because any method built on a rule begins with
> a pop action. I need to pop after the method I use (list_instructions to
> actually parse the tree) because this one pushes an index that I have to
> cancel in order to retrieve the expected situation.
>
> I am sorry but I have no experience with C. I don’t know the behavior and
> the methods to use.
>
> Regards,
>
> Claude
>
>
>
>
>
> *De :* Mohamed Yousef [mailto:harrrrpo at gmail.com]
> *Envoyé :* dimanche 15 novembre 2009 04:50
> *À :* Claude Moulin
> *Cc **:* antlr-interest at antlr.org
> *Objet :* Re: [antlr-interest] [C Target] How to skip a whole sub-tree
> (not just a token)
>
>
>
> Thanks Claude,
> if i understand your code correctly , it looks that the "." eats the whole
> "Then" tree ( tree executed when condition is true ) so u mark berfore it (
> then case) and after it (else cases) , is that true ?
>
> well , if this is true and this is the standard implementation , then this
> is a bug in the C Target
> in the C Target the macro MATCHANYT() represents the "." , unfortunetly it
> matches only a signle token , not a sub-tree , making it really usless
>
> however , it's really easy to modify this in the c target , just confirm me
> this is the standard behavior
> ( a note i thinked of now , can anybody check to see if the java terget
> saves the indexes of nodes , and i mean indexes of them as they appear in
> the flattened parse tree , coz this is another cause of problems in C Target
> )
>
> Thanks
> Regards,
> Mohammed Yousef
>
>  2009/11/14 Claude Moulin <claude.moulin at hds.utc.fr>
>
> Here is the solution I use in Java. The principle is also valid for loops.
>
> I suppose the CommonTreeNodeStream methods () I use have equivalent
> functions in C
>
> push, pop, and mark
>
>
>
> if_statement
>
> @init{
>
>   int mark_before_true = 0;
>
>   int mark_before_false = 0;
>
> }     :
>
>  ^(IF e = expbool {mark_before_true = input.mark();} . ({mark_before_false
> = input.mark();} else_list = .)? )
>
>         {
>
>          if ($e.b) {
>
>              push(mark_before_true);
>
>              list_instructions();
>
>              pop();
>
>          }
>
>          else
>
>          if (else_liste != null) {
>
>              push(mark_before_false);
>
>              list_instructions();
>
>              pop();
>
>          }
>
>         }
>
>       ;
>
> expbool is a rule returning a Boolean in its b field.
>
> list_instructions is a rule parsing a tree containing instructions in a
> list.
>
> input.mark()  gives the index of the following node and in this case it is
> the index I want to store.
>
> And in the @members section I add two methods in order to simplify the
> code:
>
>   public void push(int index) {
>
>      ((CommonTreeNodeStream)input).push(index);
>
>   }
>
>   public void pop() {
>
>      ((CommonTreeNodeStream)input).pop();
>
>   }
>
>
>
> I hope it is usefull.
>
> Claude
>
>
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe:
> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/antlr-interest/attachments/20091115/a23b1288/attachment.html 


More information about the antlr-interest mailing list