views:

107

answers:

1

Hello all!

I have some questions about antlr3 with tree grammar in C target.

I have almost done my interpretor (functions, variables, boolean and math expressions ok) and i have kept the most difficult statements for the end (like if, switch, etc.)

1) I would like interpreting a simple loop statement:

repeat: ^(REPEAT DIGIT stmt);

I've seen many examples but nothing about the tree walker (only a topic here with the macros MARK() / REWIND(m) + @init / @after but not working (i've antlr errors: "unexpected node at offset 0")). How can i interpret this statement in C?

2) Same question with a simple if statement:

if: ^(IF condition stmt elseifstmt* elsestmt?);

The problem is to skip the statement if the condition is false and test the other elseif/else statements.

3) I have some statements which can stop the script (like "break" or "exit"). How can i interrupt the tree walker and skip the following tokens?

4) When a lexer or parser error is detected, antlr returns an error. But i would like to make my homemade error messages. How can i have the line number where parser crashed?

Ask me if you want more details.

Thanks you very much (and i apologize for my poor english)

A: 

About the repeat statement, i think i've found a way to do it. In antlr.org, i've found a complete interpreter for C-- language but made in Java.

I put here the while statement (a bit different but the way is the same):

whileStmt
scope{
    Boolean breaked;
}
@after{
    CommonTree stmtNode=(CommonTree)$whileStmt.start.getChild(1);
    CommonTree exprNode=(CommonTree)$whileStmt.start.getChild(0);

    int test;

    $whileStmt::breaked=false;
    while($whileStmt::breaked==false){
            stream.push(stream.getNodeIndex(exprNode));
            test=expr().value;
            stream.pop();
            if (test==0) break;
            stream.push(stream.getNodeIndex(stmtNode));
            stmt();
            stream.pop();
        }

}
    : ^(WHILE . .)
    ;

I've tried to transform this code into C language:

repeat 
scope {
    int breaked;
    int tours;
}
@after
{
    int test;

    pANTLR3_BASE_TREE repeatstmt = (pANTLR3_BASE_TREE)$repeat.start->getChild($repeat.start,1);
    pANTLR3_BASE_TREE exprstmt = (pANTLR3_BASE_TREE)$repeat.start->getChild($repeat.start,0);

    $repeat::breaked = 0;
    test = 1;

    while($repeat::breaked == 0)
    {
        TW_FOLLOWPUSH(exprstmt);
        TW_FOLLOWPOP();
        test++;
        if(test == $repeat::tours)
            break;
        TW_FOLLOWPUSH(repeatstmt);
        CTX->repeat(CTX);
        TW_FOLLOWPOP();
    }   
}
    :   ^(REPEAT DIGIT stmt)
        {           
            $repeat::tours = $DIGIT.text->toInt32($DIGIT.text);
        }

But nothing happened (stmt is parsed juste once).

Do you have an idea about this please?

About the homemade errors messages, i've found the macro GETLINE() in the lexer. It works when the tree walker crashes but antlr continues to display errors messages for lexer or parser errors.

Thanks.

JCD