RedX
RedX

Reputation: 15165

Token empty when matching grammar although rule matched

So my rule is

/* Addition and subtraction have the lowest precedence. */
additionExp returns [double value]
    :    m1=multiplyExp       {$value = $m1.value;} 
         ( op=AddOp m2=multiplyExp )* {
                                       if($op != null){ // test if matched
                                         if($op.text == "+" ){
                                           $value += $m2.value;
                                         }else{
                                           $value -= $m2.value;
                                         }                                         
                                        }
                                       }
    ;

AddOp : '+' | '-' ;

My test ist 3 + 4 but op.text always returns NULL and never a char.

Does anyone know how I can test for the value of AddOp?

In the example from ANTLR4 Actions and Attributes it should work:

stat: ID '=' INT ';'
   {
    if ( !$block::symbols.contains($ID.text) ) {
      System.err.println("undefined variable: "+$ID.text);
    }
   }
   | block
   ;

Upvotes: 1

Views: 509

Answers (1)

Sam Harwell
Sam Harwell

Reputation: 99859

Are you sure $op.text is always null? Your comparison appears to check for $op.text=="+" rather than checking for null.

  1. I always start these answers with a suggestion that you migrate all of your action code to listeners and/or visitors when using ANTLR 4. It will clean up your grammar and greatly simplify long-term maintenance of your code.

  2. This is probably the primary problem here: Comparing String objects in Java should be performed using equals: "+".equals($op.text). Notice that I used this ordering to guarantee that you never get a NullPointerException, even if $op.text is null.

  3. I recommend removing the op= label and referencing $AddOp instead.

    1. When you switch to using listeners and visitors, removing the explicit label will marginally reduce the size of the parse tree.

    2. (Only relevant to advanced users) In some edge cases involving syntax errors, labels may not be assigned while the object still exists in the parse tree. In particular, this can happen when a label is assigned to a rule reference (your op label is assigned to a token reference), and an error appears within the labeled rule. If you reference the context object via the automatically generated methods in the listener/visitor, the instances will be available even when the labels weren't assigned, improving your ability to report details of some errors.

Upvotes: 1

Related Questions