Java calculator for n-digits

Viewed 111

I wrote this code for a calculator in Java and, by design, it works only for single-digit numbers. It works with recursion. I tried to make it work for multi-digit numbers but without success. How to change the code so that it works for multi-digit numbers? Could you give me some ideas? Or code? Whatever you want.

Here is the version that works for single digit numbers. It assumes that a single digit is always followed by either

  • an arithmetic operator, i.e. +, -, * or /
  • a bracket, i.e. ( or )
  • the end of the input string
import java.io.IOException;
import java.io.InputStream;

public class Calculator {
    private int lookAheadToken;
    private InputStream inputStream;

    public Calculator(InputStream inputStream) throws IOException,ParseError {
        this.inputStream = inputStream;
        lookAheadToken = inputStream.read();
    }

    private void consume(int symbol) throws IOException, ParseError {
        if (lookAheadToken != symbol) throw new ParseError();
        lookAheadToken = inputStream.read();
    }

    private int evalDigit(int digit) {
        return digit - '0';
    }

    private void goal() throws ParseError, IOException {
        int result = expr();
        if(lookAheadToken == '\n') {
            System.out.println("result = " + result);
        }
        consume(lookAheadToken);
        if(lookAheadToken == -1) return;
        goal();
    }

    private int expr() throws ParseError, IOException {
       int result = term();
       return rest_expr(result);
    }

    private int rest_expr(int factor) throws ParseError, IOException {
        if(lookAheadToken == '\n' || lookAheadToken == ')' || lookAheadToken == -1 ) return factor;

        if(lookAheadToken != '+' && lookAheadToken != '-') throw new ParseError();
        char operator = (char)lookAheadToken;
        consume(lookAheadToken);
        int result = term();

        if(operator == '+') {
            return rest_expr(factor + result);
        }
        else if(operator == '-') {
            return rest_expr(factor - result);
        }
        else return factor;
    }

    private int term() throws ParseError, IOException {
        int result = factor();
        return rest_term(result);
    }

    private int rest_term(int factor) throws ParseError, IOException {
        if(lookAheadToken == '\n' || lookAheadToken == ')' || lookAheadToken == -1 ) return factor;

        if(lookAheadToken == '+' || lookAheadToken == '-') return factor;
        if(lookAheadToken != '*' && lookAheadToken != '/') throw new ParseError();
        char operator = (char)lookAheadToken;
        consume(lookAheadToken);
        int result = factor();

        if(operator == '*') {
            return rest_term(factor * result);
        }
        else if(operator == '/') {
            return rest_term(factor / result);
        }
        return factor;
    }

    private int factor() throws ParseError, IOException {
        if(lookAheadToken == '(') {
            consume(lookAheadToken);
            int result = expr();
            if(lookAheadToken == ')') {
                consume(lookAheadToken);
                return result;
            }
            else throw new ParseError();
        }
        if(lookAheadToken < '0' || lookAheadToken > '9') throw new ParseError();

        int result = evalDigit(lookAheadToken);
        consume(lookAheadToken);
        return result;
    }

    public static void main(String[] args) throws IOException, ParseError {
        InputStream inputStream = System.in;
        Calculator calculator = new Calculator(inputStream);
        calculator.goal();
    }
}
0 Answers
Related