Author Topic: a bug in the expression solver (handling conditional preprocessor directive)  (Read 13695 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6035
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
the code has some bug, see below:

plugins\codecompletion\parser\expression.cpp

Code
long ExpressionNode::GetNodeTypePriority(ExpressionNodeType type)
{
    switch (type)
    {
    case LParenthesis:
    case RParenthesis:
        return 9;
    case Not:
        return 8;
    case Mod:
        return 7;
    case MultiPly:
    case Divide:
    case Power:
        return 6;
    case Plus:
    case Subtract:
        return 5;
    case LShift:
    case RShift:
        return 4;
    case BitwiseAnd:
    case BitwiseOr:
        return 3;
    case Equal:
    case Unequal:
    case GT:
    case LT:
    case GTOrEqual:
    case LTOrEqual:
        return 2;
    case And:
    case Or:
        return 1;
    default:
        return 0;
    }
}

The "And" and "Or" should have different precedence.

see:
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B

BTW, I'm implementing some similar code (I think it was much simpler, in my quex parser tester)
see:
Yesterday, I have implement a quite simple expression parser by shunting yard algorithm combined with Quex lexer. it was very much like the yacc calculator in the demo folders.
The source code was:
http://code.google.com/p/quexparser/source/browse/trunk/cppparser/expression_eval.cpp
http://code.google.com/p/quexparser/source/browse/trunk/cppparser/expression_main.cpp

and the reference was:
http://en.literateprograms.org/Shunting_yard_algorithm_%28C%29
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6035
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
seems no one was interested on this issue.... :(

Here is the test code to produce this issue:

Code
#if 1 || 1 && 0
int main();
#endif

Now, the cc will skip the "main" function.
But the conditional expression value is "true".
« Last Edit: January 05, 2011, 07:18:57 am by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9699
seems no one was interested on this issue.... :(
I guess it's Loaden who should give a statement. It seems you are right, obviously.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline Loaden

  • Lives here!
  • ****
  • Posts: 1014
seems no one was interested on this issue.... :(
I guess it's Loaden who should give a statement. It seems you are right, obviously.
Fixed in rev6983.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6035
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Nice work! loaden
I'm currently testing a same shunting yard algorithm(directly infix expression, avoid the postfix generation).
see:
http://code.google.com/p/quexparser/source/browse/trunk/cppparser/ConstExpression.h
and
http://code.google.com/p/quexparser/source/browse/trunk/cppparser/ConstExpression.cpp

I think you don't need to generate a postfix, then calculate the postfix again.
I think you can avoid the "generate a postfix" stage, and calculate the value directly. you can see my code, it will be more faster.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.