简体   繁体   中英

Recursion given grammar

I am to implement a recursive program given the grammar. I understand the concept of recursion, but implementing it can be overwhelming.

I'm having trouble with strings with parenthesis.

Inputing "(bc)" should result in it being a valid expression, but the output says invalid.

I've been tracing the program where it deals with the parenthesis, but i can seem to figure out where I am wrong.

Also, the program may not be perfect, but i'd like to address this issue. Thanks for any help.

Main prompts user for input. I only provided what I believe is necessary.

Main

if(i.findExpression(str)){
    cout << str << " is legal infix expression.\n";
}
else{
    cout << str << " is not a legal infix expression.\n";
}

The grammar to follow is:

expression = term | term + term | term - term

term = factor | factor * factor | factor / factor

factor = letter | (expression)

letter = a|b|...|z

Find Expression

bool infix::findExpression(string strExp){
    int i;
    int n = (int)strExp.length();
    bool found = true;

    for (i = 0; i < n; i++){
        if((strExp.at(i) == '(') and (n != i)){ //
            while((strExp.at(i)!=')') and (n != i)){ //
                i++;
            }
            found = false;
        }
        else if((strExp.at(i) == '+' or strExp.at(i) == '-') and 
            (n != i))
        {
            found = true;
            break;
        }
        else
            found = false;
    }// added
        if(found){
                return(findTerm(strExp.substr(0,i))&&findTerm(strExp.substr(i+1, n-(i+1))));
    }
    else{
        return findTerm(strExp.substr(0,n));
    }
}

Find Term

bool infix::findTerm(string strExp){
    int n = (int)strExp.length();
    bool found = true;
    int i;

    for(i = 0; i < n; i++){
        if((strExp.at(i) == '(')and (n != i)){
            while((strExp.at(i)!=')')and (n != i)){
                i++;
            }
            found = false;
        }
        else if((strExp.at(i)=='*' or strExp.at(i)=='/')and (n != i)){
            found = true;
            break;
        }
        else
            found = false;
    }
    if(found){
        return(findFactor(strExp.substr(0,i)) &&     findFactor(strExp.substr(i+1, n-(i+1))));
    }
    else{
        return findFactor(strExp.substr(0,n));
    }
}

Find Factor

bool infix::findFactor(string strExp)
    int i;
    char ch;
    int n = (int)strExp.length();
    bool found = true;

    ch = strExp.at(0);

    if((n==1)&&islower(ch)){
        return true;
    }
    else if(ch == '('){
        for(i = n; i > 0; i--){

            if((n-1 != i) and (strExp.at(i-1) == ')')){
                found = true;
                break;

            }
            else{
                found = false;

            }

        }
            if(found){
                return findExpression(strExp.substr(1, i-1));

            }
            else{return false;}

        }
        else{return false;}
}

Recursive descent parsers typically have methods exactly reflecting the rules. The rules consume the corresponding input. Typically this is done by operating on some kind of stateful token stream.

If you want to use simple strings, one way to handle how much is consumed by a recursive call is to let the recursion return the new position (although I'd really recommend operating on a token stream instead, as you normally would use the return value to return the corresponding subtree).

In this case, for your example, the method for handling expressions would look similar to this:

// expression = term | term + term | term - term
// Returns the position in strExp after parsing, or -1 for errors.
int infix::parseExpression(string strExp) {
   int pos = parseTerm(strExp);
   if (pos == -1) { // Error signal
     return -1;  
   }
   if (pos >= strExp.length()) {
     return pos;  // done
   }
   if (strExp.at(pos) != '-' && strExp.at(pos) != '+') {
     return -1;  // error
   }
   return parseTerm(strExpr.substr(pos + 1));
 }

 // term = factor | factor * factor | factor / factor
 int infix::parseTerm(string strExp) {
  ...

Comparing the result to the string length should provide whether the expression is valid. You can encapsulate this check in another method for convenience.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM