/* eval1.c */

#include <stdio.h>
#include <stdlib.h>

FILE	*f;
char	ch;

void GetNextToken (void) {
	do {
		ch = (char)fgetc (f);
		/* getchar returns an int. The cast suppresses a "loss of significant digits" warning.	*/
	} while ((ch == ' ' || ch == '\n') && !feof (f));
	if (feof (f)) exit (1);
}

void ParseExpression (void);	/* Forward declaration.	*/

void ParseFactor (void) {
	if (ch == '(') {
		GetNextToken ();
		ParseExpression ();
	} else {
		putchar (ch);	/* If we were evaluating  expressions, this would be     */
	}					/* pushing a value onto a stack.                         */
	GetNextToken ();	/* We've dealt with this token, so fetch another.  If    */
}						/* this factor was a bracketed expression, the current   */
						/* token (prior to calling GetNextToken()) is the closing*/
						/* bracket to match the one we started with.             */

void ParseTerm (void) {	/* This works just like ParseExpression ().				*/
	ParseFactor ();
	while (ch == '*') {
		GetNextToken ();
		ParseFactor ();
		putchar ('*');
	}
}

void ParseExpression (void) {
	ParseTerm ();						/* Parse the first part of the expression.*/
	while (ch == '+' || ch == '-') {	/* Parse the second part if there is one. */
		char  op = ch;					/* Remember what the second part was.     */
		
		GetNextToken ();				/* Fetch the next token.                  */
		ParseTerm ();					/* Parse the third part of the expression.*/
		putchar (op);					/* Process the operator.                  */
	}
}

int main (void) {
	f = fopen ("eval1.dat", "r");
	/*if (f == NULL) f = stdin;*/
	/* Keyboard input interferes with the output, and makes it looks	*/
	/* like everything has gone horribly wrong. It is OK really though.	*/

	if (f != NULL) {
		GetNextToken ();		/* This actually reads in the first token (=first ch).	*/
		do {
			ParseExpression ();	/* Do whatever it takes to parse an expression.			*/
			putchar ('\n');
		} while (ch != '.');
	}
	
	return 0;
}