Nested Switch Alternative

While playing with NLP, I ran into a small problem:

switch(var1)
{
case Variant1_1:
    if( cond1 )
    {
        if( cond2 )
        {
            if( cond3 )
            {
                switch(var2)
                {
                case Variant2_1:
                    return someExpression;
                // another five-six cases
                default:
                    return;
                }
            }
            else // cond3
            {
                switch(var2)
                {
                case Variant2_1:
                    return someExpression;
                // another five-six cases
                default:
                    return;
                }
            } 
        }
        else // cond2
        {
            if( cond3 )
            {
                switch(var2)
                {
                case Variant2_1:
                    return someExpression;
                // another five-six cases
                default:
                    return;
                }
            }
            else // cond3
            {
                switch(var2)
                {
                case Variant2_1:
                    return someExpression;
                // another five-six cases
                default:
                    return;
                }
            } 
        }
    }
    else // cond1
    {
        // same thing

    }
    break;
case Variant1_2:
    // same gigantic tree
    break;
case Variant1_3:
    // here too
    break;
default:
    return;
}

      

What are the alternatives for such a "computational tree"? The only thing that comes to my mind is some kind of tree container with function pointers as leaves and a lot of small functions.

+3


source to share


5 answers


(tongue on the cheek) Every time you come across an expression switch

in a C ++ program, you know you've missed the possibility of inheritance.



The two ways I know of for refactoring multiple parallel switches are (1) building a multidimensional array of function pointers and (2) using a variation of the visitor pattern .

+4


source


A good workaround is using a matrix.

This will work well if you know that all conditions will be assessed anyway.



Make a multidimensional array that will render true-false values ​​for processing functions.

Arrayswitch[var1][cond1][cond2][cond3][var2]();

      

+1


source


I start looking for a data driven approach when the code starts to look like this. It could be as simple as a table, or perhaps a tree of function pointers, as you'd expect.

If it's a hand-crafted parser of some kind, you might want to look at some links to parse ideas on how to use the grammar definition for parsing (either by interpreting the grammar on demand, or by using a code generation tool that uses grammar for input).

I often run paired recursive guerrillas. Typically, I create a class that contains state, exposes one public "Parse" function, and implements each rule as a private member function. These member functions are small and explicitly named, so the code becomes quite readable. It's also very easy to write tests for it.

+1


source


Polymorphism and good code design. http://www.cs.bu.edu/teaching/cpp/polymorphism/intro/

0


source


What you are describing is what the compiler will do from your code anyway :) So you essentially suggest a nested programming language, which leads to Greenspun's law: "Any sufficiently complex C or Fortran program contains a special, informally given, with an error, a slow implementation of half of Common Lisp. "

There are better ways to write this code to express your conditions. when you have many nested if() { if () { if() } } }

s, usually just writing if (!condition) break;

or some other way of escaping, simplifies the code. not always, but many times.

0


source







All Articles