1

I copied this program from a textbook (Compilers Principles, Techniques and Tools) and changed somethings in it to do what I wanted. It's a program to translate infix expressions into pretfix form. Here's the code:

package prefixTrans;
import java.io.*;
public class Parser {
    static int lookahead;

    public Parser() throws IOException{
        lookahead = System.in.read();
    }

    void exp() throws IOException{
        while(true) {
            if (lookahead == '*'){
                match('*'); System.out.write('*'); exp(); term();
            }
            else if (lookahead == '/'){
                match('/'); System.out.write('/'); exp(); term();
            }
            else return;
        }
    }

    void term() throws IOException{
        if (lookahead == '+'){
            match('+'); System.out.write('+'); factor(); term();}
        else if (lookahead == '-'){
            match('-'); System.out.write('-'); factor(); term();}
        else return;

    }

    void factor() throws IOException{
        if ( Character.isDigit((char)lookahead))  { 
            int v = 0;
            while(Character.isDigit((char)lookahead)){
                v = v * 10 + lookahead; 
            }
        }
        else if(Character.isAlphabetic(lookahead)){
            String lexeme = "";
            while(Character.isLetter(lookahead)){
                lexeme = lexeme + lookahead;
            }
        }
        System.out.write((char)lookahead); match(lookahead);
    }

    void match(int t) throws IOException{
        if(lookahead == t) lookahead = System.in.read();
        else throw new Error("syntax error");
    }

    public static void main(String [] args) throws IOException{
        Parser parse = new Parser();
        parse.exp(); System.out.write('\n');

    }
}

Every time I enter an an input in the console inside Eclipse the program terminates.

I've edited my code, it doesn't terminate now but I get no output. here's the edited one:

package prefixTrans;

import java.io.*;
import java.util.Scanner;


public class Parser {
    static int lookahead;
    Scanner input;

    public Parser() throws IOException{
        //lookahead = System.in.read();
         input = new Scanner(System.in);
            lookahead = input.next().charAt(0);
        }

    void exp() throws IOException{

        if (lookahead == '*'){
                match('*'); System.out.write('*');exp();term();  
            }
            else if (lookahead == '/'){
                match('/'); System.out.write('/');exp();term(); 
            }
            else term();

    }

    void term() throws IOException{

        if (lookahead == '+'){
            match('+'); System.out.write('+'); factor(); term(); }
        else if (lookahead == '-'){
            match('-'); System.out.write('-'); factor(); term(); }
        else factor();

    }

    void factor() throws IOException{
        if ( Character.isDigit((char)lookahead))  { 
            int v = 0;
            while(Character.isDigit((char)lookahead)){
                v = v * 10 + lookahead; 
                }
            }
            else if(Character.isLetter(lookahead)){
                String lexeme = "";
                while(Character.isLetter(lookahead)){
                    lexeme = lexeme + lookahead;
                }
            }
            System.out.write((char)lookahead); match(lookahead);
        }

     void match(int t) throws IOException{
        if(lookahead == t) /*lookahead = System.in.read();*/ lookahead = input.next().charAt(0);
        else throw new Error("syntax error");
    }


         public static void main(String [] args) throws IOException{
             Parser parse = new Parser();
             parse.exp(); System.out.write('\n');

     }
}
3
  • Ugly, unreadable code. You're getting a stack trace that you aren't telling us about. Try running in a command shell instead of Eclipse. It'll tell you what you're doing wrong. lookahead int/char issue is my guess. Commented Jul 6, 2015 at 14:53
  • Sorry, I'm not an expert in these things so I can't understand what you're telling me to do Commented Jul 6, 2015 at 14:57
  • Don't use Eclipse. Run your code in a command shell so you can see the stack trace when it comes. Commented Jul 6, 2015 at 14:58

2 Answers 2

1

You start by calling exp. If the first character is neither * nor /, you call return, hence existing the function and the program. That's probably not what you want. Also the character is only read (on my machine) when the enter key is pressed, so that lookahead has then the value "\n", which you don't cater for. Basically, since you're running in Eclipse, debug your program to see step by step what's happening.

Sign up to request clarification or add additional context in comments.

3 Comments

Really? When I ran your code, I could see that typing any else than * or / cause the code to stop because of the return. Typing / followed by enter causes lookahead to be set to the new line, which then causes your code to exit. So your code as it is will always exit after the first character.
So that's what you meant by debugging, sorry I'm inexperienced in these terms. Can you suggest me a fix or I should do that myself?
no, what I'm saying is that if you debug your program, you'll go step by step and understand why it's acting the way it is. You look at the state of your lookahead variable, etc. Once you understand how your program behaves and why, then you can change it.
0

As suggested by "JP Moresmau" in another answer, the issue here is that System.in.read() reads only one byte (in constructor Parser) and the carriage return (Enter character pressed after entering * or /) is read in the next System.in.read() in method match(). And since the carriage return doesn't match * or /, your program terminates.

Either consume carriage return or use the Scanner API in the following way to get what you intended.

public class Parser {
    private char lookahead;
    Scanner input;

    public Parser() throws IOException{
        input = new Scanner(System.in);
        lookahead = input.next().charAt(0);
    }

    void exp() throws IOException{
        while(true) {
            if (lookahead == '*'){
                match('*'); System.out.write('*'); exp(); term();
            }
            else if (lookahead == '/'){
                match('/'); System.out.write('/'); exp(); term();
            }
            else return;
        }
    }

    void term() throws IOException{
        if (lookahead == '+'){
            match('+'); System.out.write('+'); factor(); term();}
        else if (lookahead == '-'){
            match('-'); System.out.write('-'); factor(); term();}
        else return;

    }

    void factor() throws IOException{
        if ( Character.isDigit((char)lookahead))  { 
            int v = 0;
            while(Character.isDigit((char)lookahead)){
                v = v * 10 + lookahead; 
            }
        } else if(Character.isAlphabetic(lookahead)){
                String lexeme = "";
            while(Character.isLetter(lookahead)){
                lexeme = lexeme + lookahead;
            }
        }
        System.out.write((char)lookahead); match(lookahead);
    }

    void match(char t) throws IOException{
        if(lookahead == t) lookahead = input.next().charAt(0);
        else throw new Error("syntax error");
    }

    public static void main(String [] args) throws IOException{
         Parser parse = new Parser();
         parse.exp(); System.out.write('\n');
    }
}

2 Comments

still the same error, but I noticed after your edit that now that I can enter multiplication sign '*' without the program being terminated then after that if I enter more inputs it gets terminated.
True, its because your program continuous only when you enter either * or /, you need to modify your program if you want to accept more characters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.