Hey guys, just wanted to see if you guys could catch what I can't... It runs fine except that when an invalid character is input the program loops instead of just seeking new input... Is there a flag I need to place and if so where?
#include <iostream>
usingnamespace std;
int gcd(int a, int b);
int max(int a);
int modular(int a, int b);
void command();
int expr();
int term();
int value();
int factor();
int number();
int digit();
int token;
int line = 0;
bool flag = false;
void error(char* message){
flag = true;
cout << "line " << line << ' ' << message << endl;
}
void getToken(){
token = getchar();
while(isspace(token) && token != '\n')
token = getchar();
}
void match(char c, char*message){
if(token == c )
getToken();
else
error(message);
}
void command(){
int result = expr();
if(token == '\n' && flag == false){
cout << "the result is: " << result << endl;
}
else{
error("syntax error");
}
}
int expr(){
int result = term();
while(token == '&'){
getToken();
result = gcd(result, term());
}
return result;
}
int term(){
int result;
if(token == '%'){
getToken();
result = max(value());
}
else
result = value();
return result;
}
int value(){
int result = factor();
while(token == '@'){
getToken();
result = modular(result,factor());
}
return result;
}
int factor(){
int result;
if(token == '('){
match('(', "( expeced");
result = expr();
match(')', ") expected");
}
else
result = number();
return result;
}
int number(){
int result = digit();
while(isdigit(token))
result = 10*result + digit();
return result;
}
int digit(){
int result = 0;
if(isdigit(token)){
result = token - '0';
match(token, "( expected");
return result;
}
else{
error("lexical error");
return result;
}
}
void parse(){
line++;
flag = false;
getToken();
command();
}
int main(){
while(cin){
parse();
}
return 0;
}
int gcd (int a, int b){
a = a + 2;
b = b + 3;
int t;
while (b != 0){
t = b;
b = a % b;
a = t;
}
return t;
}
int max(int a){
int a1 = 5 * a;
int a2 = 3 * a + 10;
if(a1 > a2)
return a1;
elsereturn a2;
}
int modular(int a, int b){
int sol;
a = a + 5;
sol = a % b;
return sol;
}
If you are using while(cin) then why are you using getchar() instead of cin.get() ? I don't know if that has anything to do with the looping problem but it seems like apples and oranges.
Your use of match() puzzles me. There is only one place you use it where it could possibly not be a match and result in an error condition (when you check for the ending paren,) but you use it all over to check a condition you know will not result in an error condition.
When you say "the program loops instead of just seeking new input." What do you want the behavior to be? What input causes the behavior to be other than what you expect it to be?
well the use of while(cin) is to get input by line until eof, using while(getchar()) results in losing the first character of the line.
match() is used to call getToken()... which I could also call directly, thanks.
Well if you type in b it seems to run four, first reaching digit() and saying it is a "lexical error" then it seems to run again reaching command() and saying there is a "syntax error" and it does it again this time incrementing the line lumber
Following the logical structure of the program, when you enter "b\n",the first getToken() sets the token to 'b' and this is propagated through function calls down to digit() where the "lexical error" occurs, then it bubbles back up to command. Because the current token is still 'b' and not '\n' it prints out "syntax error" and returns to parse where the line number is increased, the next token is extracted (which happens to be '\n') and command is called again. Repeat the previous chain of events for '\n'.
It seems to me you need to ensure that command is consuming a full line of text up to and including the newline.
Something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void command(){
int result = expr();
if ( token == '\n' && flag == false)
cout << "the result is: " << result << endl ;
else
{
if ( flag == false ) // no error message has been output yet
error( "Syntax error") ;
while ( token != '\n' )
getToken();
}
}