News:

When registered with our forums, feel free to send a "here I am" post here to differ human beings from SPAM bots.

Main Menu

a bug in the expression solver (handling conditional preprocessor directive)

Started by ollydbg, December 31, 2010, 06:58:34 AM

Previous topic - Next topic

ollydbg

the code has some bug, see below:

plugins\codecompletion\parser\expression.cpp

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.

ollydbg

seems no one was interested on this issue.... :(

Here is the test code to produce this issue:


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


Now, the cc will skip the "main" function.
But the conditional expression value is "true".
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.

MortenMacFly

Quote from: ollydbg on January 05, 2011, 02:01:50 AM
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: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

Loaden

Quote from: MortenMacFly on January 05, 2011, 06:57:18 AM
Quote from: ollydbg on January 05, 2011, 02:01:50 AM
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.

ollydbg

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.