• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 322
  • Last Modified:

function to process control flow - nested if-then-else

This function currently handles a single if-then-else control flow. It does not handle nested if-then-else. It reads from the command line -- (one line at a time). How can I modify this function to handle the nested if-then-else?

int do_control_command(char **args)
/*
 * purpose: Process "if", "then", "else", "fi" - change state or detect error
 * returns: 0 if ok, -1 for syntax error
 */
{
      char      *cmd = args[0];
      int      rv = -1;

      if( strcmp(cmd,"if")==0 ){
            if ( if_state != NEUTRAL )
                  rv = syn_err("if unexpected");
            else {
                  last_stat = process(args+1);
                  if_result = (last_stat == 0 ? SUCCESS : FAIL );
                  if_state = WANT_THEN;
                  rv = 0;
            }
      }
      else if ( strcmp(cmd,"then")==0 ){
            if ( if_state != WANT_THEN )
                  rv = syn_err("then unexpected");
            else {
                  if_state = THEN_BLOCK;
                  rv = 0;
            }
      }
      else if ( strcmp(cmd, "else") == 0 ) {
            if ( if_state != THEN_BLOCK )
                  rv = syn_err("else unexpected");
            else {
                  if_state = ELSE_BLOCK;
                  rv = 0;
            }
      }
      else if ( strcmp(cmd,"fi")==0 ){
            if ( if_state != THEN_BLOCK && if_state != ELSE_BLOCK )
                  rv = syn_err("fi unexpected");
            else {
                  if_state = NEUTRAL;
                  rv = 0;
            }
      }
      else
            fatal("internal error processing:", cmd, 2);
      return rv;
}
0
ericworldz
Asked:
ericworldz
  • 2
  • 2
  • 2
  • +1
1 Solution
 
leflonCommented:
Hi ericworldz,

so i'm not really into what you try to do, you seem to insert a level to handle the nested statements. so each if increments the level and each fi decrements it.
you can handle the level var the same way you do with the if_state (seems to be a global var).

hth
leflon
0
 
Avik DasguptaCommented:
check for elif
0
 
Avik DasguptaCommented:
The construct can be like this...

else if ( strcmp(cmd, "elif") == 0 ) {
....
ur code to handle "else if " portion.
...
}

Remember if ur checking the control flow of a bash shell script...looks like one...then u must check whether the then statement appears in the same line then it must be seperated from the if or elif statement by a ';' .

Avik.
0
Live webcast with Pinal Dave

Pinal Dave will teach you tricks to help identify the real root cause of database problems rather than red herrings. Attendees will learn scripts that they can use in their environment to immediately figure out their performance Blame Shifters and fix them quickly.

 
Sjef BosmanGroupware ConsultantCommented:
"Nested" implies a recursive solution. If you're trying to construct a recursive-descent interpreter for your language, you could do things a lot better:
- make a lexical analyser that returns tokens (i.e. it returns TOKEN_ELIF instead of having to work with "elif")
- in case of a TOKEN_VAR, you need an additional value, namely the name of the variable
- use these tokens when scanning the code, it's quite easy

if_stat() {
    int token;

    token= getnexttoken();
    if (token!=TOKEN_IF) {
        pushbacktoken();
        return 0;
    }
    if(!condition()) {
        return 0;
    }

etc.
0
 
ericworldzAuthor Commented:
Below is a simple nested if-ten-else script. How can I modify my function above to process this script correctly - it will read in line by line.

CMD=echo
echo Output should consist of lines 1 2 3 4 5 6
if echo line 1
then
        $CMD line 2
        if false
        then
                echo error 1
                echo error 2
        else
                if echo line 3
                then
                        echo line 4
                else
                        echo error 3
                fi
        fi
        echo line 5
else
        if true
        then
                echo error 4
        else
                echo error 5
        fi
        echo error 6
fi
echo line 6
0
 
leflonCommented:
ericworldz,
what is the goal of your app? telling you if there is an error in the if-then-else structure?

leflon
0
 
ericworldzAuthor Commented:
yes, the problem with the code above is that when it see the first "if" and then see another "if" it reports an error when it shouldn't be, because the script is a nested if-then-else.
0
 
Sjef BosmanGroupware ConsultantCommented:
Please comment on my earlier post. Is it that it wasn't clear enough, that there were incomprehensible things in it, or was I too blunt?

I meant to say that you are developing some kind of computer language. Every computer language has some sort of syntax, with syntax rules. A language contains several types of statements, like yours, e.g. in C the for-statement, the while-statement, the if-statement and the compound-statement. Language rules for these statements are NESTED, which means that inside a statement there can be other statements. Some C-language-like definitions:

    statement ::= if-statement | while-statement | for-statement | assignment-statement | expression-statement | compound statement
    compound-statement ::= "{" statements "}
    statements ::= statement statements | <nothing>

    if-statement ::= "if" "(" condition-expression ")" statement

What you are trying to do is to view every statement as a flat statement, withou the possibility of having other statements. What you need is a stack, either explicitly or implicitly using recursive functions. That's what's in my first post.

Your language in production rules should be something like, assuming you have only if-statements

    statement ::= if-statement | executable statement
    statements ::= statement statements | <nothing>

    if-statement ::= "if" condition "\n" "then" "\n" statements "\n" else-part "fi"
    else-part ::= "else" statements "\n" | <nothing>

If you want to interpret your language, create a function for each of the above rules. If you want to see an example, read the last chapter of a C Programming Language book, the C Reference Manual.

Hope I'm making sense to you.
0

Featured Post

Live webcast with Pinal Dave

Pinal Dave will teach you tricks to help identify the real root cause of database problems rather than red herrings. Attendees will learn scripts that they can use in their environment to immediately figure out their performance Blame Shifters and fix them quickly.

  • 2
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now