Reputation: 153
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 "(b-c)" 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;}
}
Upvotes: 0
Views: 203
Reputation: 18813
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.
Upvotes: 1