2

I'm trying to create a grammar in ANTLR that evaluates propositional logic formulas. So for the input (1 & 0) | 1, it should return true.

I have constructed the following:

code returns[boolean value]
  : formula EOF {$value = $formula.value;}
  ; 

formula returns [boolean value]
  : equiv {$value = $equiv.value;}
  ; 

equiv returns [boolean value]
  : a=implies  {$value = $a.value;} 
  ( '#' b=implies {$value = $value == $b.value;}  
  )* 
  ;

implies returns [boolean value]
  : a=or   {$value = $a.value;} 
  ( '>' b=or {$value = !$value || $b.value;}
  )* 
  ;  

or returns [boolean value]
  : a=and {$value = $a.value;}
  ( '|' b=and {$value ||= $b.value;}
  )* 
  ;

and returns [boolean value]
  :  a=term {$value = $a.value;}
  ( '&' b=term {$value &&= $b.value;}
  )* 
  ; 

term returns [boolean value]
  : '(' formula ')' {$value = $formula.value;}
  | '0' {$value = false;}
  | '1' {$value = true;}
  | '¬' term {$value = !$term.value;}
  ;

WHITESPACE: (' '|'\t'|'\r'|'\f'|'\n')+{$channel = HIDDEN;} ; 

However I keep getting the error java.lang.NoSuchFieldError: offendingToken. Is there anyway to find out where the error is or how to fix it?

Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
charlie123
  • 253
  • 1
  • 5
  • 17
  • 1
    As a non-ANTLR expert, I debug these problems by looking at the generated Java code. Your stack trace should include line numbers, and the generated code will have comments that indicate which part of which rule is represented. – Nathaniel Waisbrot Jun 11 '13 at 17:54

1 Answers1

2

There are 3 issues:

  • {$value ||= $b.value;} should be {$value = $value || $b.value;}
  • {$value &&= $b.value;} should be {$value = $value && $b.value;}
  • the label $term in the fourth alternative of the term rule is ambiguous: is could refer to the rule itself, or the term followed by '¬'


I.e., the following:

term returns [boolean value]
  : ...
  | '¬' term {$value = !$term.value;}
  ;

should be:

term returns [boolean value]
  : ...
  | '¬' t=term {$value = !$t.value;}
  ;

Having made those changes, the following test class:

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    String source = "(1 & 0) | 1";
    TestLexer lexer = new TestLexer(new ANTLRStringStream(source));
    TestParser parser = new TestParser(new CommonTokenStream(lexer));
    System.out.println(source + " = " + parser.code());
  }
}

produces the desired output:

java -cp antlr-3.3.jar org.antlr.Tool Test.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main

(1 & 0) | 1 = true
Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
  • Thank you very much for all your help! I was trying to follow one of your earlier posts on evaluating +,-,/,* operations but could not see where I was going wrong here. I really thought ||= and &&= would be allowed. Thank you again! – charlie123 Jun 11 '13 at 18:39