
#include <iostream>
#include <cstdlib>

using namespace std;

const char *name[] = {
	"NUM", "VARX", "VARY", "ADD", "SUB", "MUL", "DIV", "EXPO", 
	"LPAR", "RPAR", "SEMI", "BAD"
};

enum {
	NUM, VARX, VARY, ADD, SUB, MUL, DIV, EXPO, LPAR, RPAR, SEMI, BAD
};

int tok;	// ultimo token leido
int num;	// ultimo numero leido

void error(const char mesg[])
{
	std::cerr << "ERROR - " << mesg << std::endl;
	exit(EXIT_FAILURE);
}

int gettok(void)
{
	std::cin >> std::ws;	// se come los blancos
	int ch= std::cin.get();
	if (isdigit(ch)) {
		num= 0;
		do {
			num= 10*num + (ch-'0');
			ch= std::cin.get();
		} while (isdigit(ch));
		std::cin.putback(ch);
		tok= NUM;
	}
	else
	switch (ch) {
		case 'x':
		case 'X':	tok= VARX;
				break;
		case 'y':
		case 'Y':	tok= VARY;
				break;
		case '+':	tok= ADD;
				break;
		case '-':	tok= SUB;
				break;
		case '*':	tok= MUL;
				break;
		case '/':	tok= DIV;
				break;
		case '^':	tok= EXPO;
				break;
		case '(':	tok= LPAR;
				break;
		case ')':	tok= RPAR;
				break;
		case ';':	tok= SEMI;
				break;
		case EOF:	tok= SEMI;
				break;
		default:	tok= BAD;
				break;
	}
	return tok;
}

void expr(void);

void prim(void)
{
	switch(tok) {
		case NUM: gettok();
			  break;
		case VARX: gettok();
			   break;
		case VARY: gettok();
			   break;
		case LPAR: gettok();
			   expr();
			   if (tok==RPAR) {
				   gettok();
				   break;
			   } 
			   else
				   error("falta ')'");
		default:   error("se espera <prim>");
	}
}

void factor(void)
{
	prim();
	while (tok==EXPO) {
		gettok();
		factor();
	}
}

void term(void)
{
	factor();
	for (;;) 
		switch (tok) {
			case MUL:	gettok();
					factor();
					break;
			case DIV:	gettok();
					factor();
					break;
			default:	return;
		}
}

void expr(void)
{
	if (tok==ADD) {
		gettok();
		term();
	}
	else
	if (tok==SUB) {
		gettok();
		term();
	}
	else
		term();
	for (;;) 
		switch (tok) {
			case ADD:	gettok();
					term();
					break;
			case SUB:	gettok();
					term();
					break;
			default:	return;
		}
}

void line(void)
{
	gettok();
	expr();
	if (tok==SEMI) 
		std::cerr << "La expresion es correcta\n";
	else 
		error("falta ';'");
}

int main(int argc, char** argv) 
{
	line();
	return EXIT_SUCCESS;
}
