Question

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
   ;
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top