0
votes

I new one in using antlr and with my c# I am facing to problem in this very simple grammar:

grammar quest;

prog:   stat+ ;

stat:   expr NEWLINE
    ;

expr:   INT '+' INT 
    |   INT '-' INT 
    ;

INT :   [0-9]+ ;
NEWLINE:'\r'? '\n' ;

In my Main method I go throght the grammar with input 3+24 which starting in prog rule. After that code jump from Main method to my class EvalVisitor where all magic happens and also there is my question goes.

class EvalVisitor : questBaseVisitor<int>
{
    public override int VisitStat([NotNull] questParser.StatContext context)
    {
        int value = Visit(context.expr());
        Console.WriteLine(value);
        return 0;
    }

    public override int VisitExpr([NotNull] questParser.ExprContext context)
    {
        int left = int.Parse(context.INT(0).GetText());
        int right = int.Parse(context.INT(1).GetText());

        if (context.children[1].GetText() == "+")
        {
            return left + right;
        }
        else
        {
            return left - right;
        }
    }
}
  1. Is there in IF statemant possible to visit node value of my ANTLR tree which contains token '+' without using children? I do not want also use label alternatives or another rule for the '+' token.

  2. If I would add new rules for tokens '+' and '-' at the end of my grammar:

    ADD : '+' ;

    SUB : '-' ;

than I would be able to in IF statement (on right side of equality) use instead of "+" number belonging to token '+' by this command:

questParser.ADD

and again I do not know how to properly find number of token '+' in my context (without using children). For me would be best solution if I could in my IF statement compare:

if (...number_of_token_in_my_context... == questParser.ADD)

Which is similar to ANTLR4 reference by Terence Parr:

/* expr op=('*'|'/') expr */
    public override int VisitMulDiv([NotNull] LabeledExprParser.MulDivContext context)
    {
        int left = Visit(context.expr(0)); // get value of left subexpression
        int right = Visit(context.expr(1)); // get value of right subexpression
        if (context.op.Type == LabeledExprParser.MUL)
        {
            return left * right;
        }
        else
        {
            return left / right;
        }
    }

But I dont want to use no "op" functions, label alternatives etc. because in my aplication I have very complex and general written grammar and I do not want to edit it. I also give a picture of my tree below:

picture_of_tree

Can anybody help me please?

1

1 Answers

0
votes

I would suggest that, the more complex your grammar is the MORE you want to use explicit Lexer rules (ex: ADD: "+";) and the MORE you want to label the parts of your parser rules (like op=).

These give you tools to write visitor/listener code that is easier to follow and less prone to errors.

"Is there in IF statement possible to visit node value of my ANTLR tree which contains token '+' without using children?" -> yes, label the operator in your parse rule with the op= notation. Then you can refer to is by name rather than it's position within your children nodes.

There really isn't an answer to making things easier while not doing the things you say you don't want to do.

Trust me, start using tools like explicit Lexer rules and labelling the parts of your parser rules. You'll be glad you did in the long run.