Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 332869

Summary: [EOL] 'and' and 'or' operators have the same precedence
Product: [Modeling] Epsilon Reporter: Antonio Garcia-Dominguez <agarcdomi>
Component: CoreAssignee: Dimitris Kolovos <dkolovos>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard:
Attachments:
Description Flags
Patch with an acceptance test case that illustrates the issue
none
Fixed version of 185448 without ANSI escape sequences
dkolovos: iplog-
Simple EOL script showing the precedence of 'or', 'and' and '=' none

Description Antonio Garcia-Dominguez CLA 2010-12-17 12:49:52 EST
Build Identifier: 20100917-0705

Normally, a Java or C programmer would expect this expression to yield "true":

true or false and false

However, in Epsilon it is being evaluated to "false". Apparently, it is being interpreted as

(true or false) and false

instead of

true or (false and false)

The problem appears to be in the grammar itself (EolParserRules.g). 'and', 'or', 'xor' and 'implies' are all lumped together:

expressionStatement
  :  logicalExpression ';'!
  ;

logicalExpression
  :  relationalExpression (('or'|'and'|'xor'|'implies')^ relationalExpression
       {if (root_0.getToken() != null) root_0.getToken().setType(OPERATOR);})*
  ;

In order to make EOL consistent with most programming languages, I would suggest that logical operators are divided into three levels of precedence: and, or+xor, and implies. Perhaps something like this would work. Please note that it is untested. I have been unable to run the "Build EOL Parser" launchers in the o.e.epsilon.eol.engine, as I'm using GNU/Linux and I can't find the o.e.epsilon.antlr.dev project anywhere in the source code :-/.

expressionStatement
  :  logicalExpressionAnd ';'!
  ;

logicalExpressionAnd
  :  logicalExpressionOr ('and'^ logicalExpressionOr
       {if (root_0.getToken() != null) root_0.getToken().setType(OPERATOR);})*
  ;

logicalExpressionOr
  :  logicalExpressionImplies (('or'|'xor')^ logicalExpressionImplies
       {if (root_0.getToken() != null) root_0.getToken().setType(OPERATOR);})*
  ;

logicalExpressionImplies
  :  relationalExpression ('implies'^ relationalExpression
       {if (root_0.getToken() != null) root_0.getToken().setType(OPERATOR);})*
  ;


Reproducible: Always

Steps to Reproduce:
1. Run the EOL script in the patch.
2. Check the output in the console.
Comment 1 Antonio Garcia-Dominguez CLA 2010-12-17 12:51:02 EST
Created attachment 185448 [details]
Patch with an acceptance test case that illustrates the issue
Comment 2 Antonio Garcia-Dominguez CLA 2010-12-17 12:51:45 EST
I would also suggest that the precedence of the operators is documented in the Epsilon book.
Comment 3 Antonio Garcia-Dominguez CLA 2010-12-17 12:53:08 EST
Created attachment 185449 [details]
Fixed version of 185448 without ANSI escape sequences
Comment 4 Antonio Garcia-Dominguez CLA 2010-12-17 13:17:07 EST
Created attachment 185450 [details]
Simple EOL script showing the precedence of 'or', 'and' and '='
Comment 5 Antonio Garcia-Dominguez CLA 2010-12-17 13:22:21 EST
The operator '=' (which deprecated ':=' as assignment operator a few releases ago, IIRC) also seems to have a wrong precedence. Normally, the assignment operator is always last, but according to the grammar, it has the same precedence as the relational operators. The ':=' and '::=' operators work fine, though.

I have attached a simple EOL script which illustrates these problems.

By the way, I think I got the order of the logicalExpression rules wrong: it's the other way around. Like this:

expressionStatement
  :  logicalExpressionImplies ';'!
  ;

logicalExpressionImplies
  :  logicalExpressionOr ('implies'^ logicalExpressionOr
       {if (root_0.getToken() != null) root_0.getToken().setType(OPERATOR);})*
  ;

logicalExpressionOr
  :  logicalExpressionAnd (('or'|'xor')^ logicalExpressionAnd
       {if (root_0.getToken() != null) root_0.getToken().setType(OPERATOR);})*
  ;

logicalExpressionAnd
  :  relationalExpression ('and'^ relationalExpression
       {if (root_0.getToken() != null) root_0.getToken().setType(OPERATOR);})*
  ;
Comment 6 Dimitris Kolovos CLA 2011-06-04 05:06:38 EDT
Have any of these changes made it into the latest version of the EOL grammar in the SVN?
Comment 7 Antonio Garcia-Dominguez CLA 2011-06-04 06:57:53 EDT
No, I have neither tested nor integrated these changes yet.
Comment 8 Dimitris Kolovos CLA 2013-04-08 03:51:32 EDT
(In reply to comment #5)
> The operator '=' (which deprecated ':=' as assignment operator a few
> releases ago, IIRC) also seems to have a wrong precedence. Normally, the
> assignment operator is always last, but according to the grammar, it has the
> same precedence as the relational operators. The ':=' and '::=' operators
> work fine, though.

The = issue has been fixed in r2195. Changing the precedence of operators at this stage could (rather inconspicuously) break existing code so I'd be inclined to keep it as-is. Closing as fixed but please feel free to reopen if needed.
Comment 9 Dimitris Kolovos CLA 2013-04-27 05:44:00 EDT
Fixed in the latest interim version (1.0.0.201304211529).
Comment 10 Dimitris Kolovos CLA 2013-09-01 08:14:24 EDT
Fixed in 1.1