0

Below is my project for a class I am taking. The purpose of this assignment is to take postfix expressions and convert them into assembly language instructions. I cannot get my loop to print out the correct instructions after the first run through. Could someone explain to me what I am doing wrong, as I have been debugging for a while now and I am stuck? Also, as I am newer to java, any comments on how to make my program more efficient or any explanations you would like to point out for me to learn would be greatly appreciated. I am sure there are more ways to do this, but please remember I am newer and something things I have just not learned yet.

What is on the .txt input file:

AB+C- //loop 1

ABC+- //loop 2

AB-C+DEF-+$ //loop 3

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;


public class PostfixConverter{

static int top = 0;
static  String [] mainStack = new String [100];

public static void main(String args[]) throws Exception{
 String string = null;
 String asterisk = "*";
 String divisor = "/";
 String plus = "+";
 String minus = "-";
 int temp =0;
 int directionCounter = 0;
 String load = "LD ";
 String multiply = "ML ";
 String add = "AD ";
 String div = "DV ";
 String subtract = "SB ";
 String store = "ST TEMP";
 String tempString = "TEMP";
 String [] directions = new String [100];
 String example = "AB+C-";
 PostfixConverter s = new PostfixConverter();

 try{
 //file reader code
 FileReader file = new FileReader     ("/Users/ChristopherSchubert/Desktop/PostfixMachineLangInput(1).txt");
 BufferedReader reader = new BufferedReader(file);


 String text = "";
 String line = reader.readLine();
 while (line!= null)
 {
    text += line;
    line = reader.readLine();
    example = text;

  //for loop to print directions 
  for (int i=0; i<example.length(); i++) {


     //get letter entered by user 1 by 1
     char letter  = example.charAt(i);

     //convert char to string
     String convertedChar = java.lang.String.valueOf(letter);

     //finds operands in order or priority
     //multiply character
     if (convertedChar.equals(asterisk)){
        String outcome;
        String multiplyReturn = PostfixConverter.multiply(string);
        String loadmulReturn = PostfixConverter.multiply(string);
        directions[directionCounter] = load + loadmulReturn;
        directionCounter++;
        directions[directionCounter] = multiply + multiplyReturn;
        directionCounter++;
        temp++;
        outcome = tempString + java.lang.String.valueOf(temp);
        directions[directionCounter] = store +     java.lang.String.valueOf(temp);
        directionCounter++;
        s.push(outcome);
        }


        //division character
        else if (convertedChar.equals(divisor)){
           String outcome;
           String divisionReturn = PostfixConverter.addition(string);
           String loaddivReturn = PostfixConverter.addition(string);
           directions[directionCounter] = load + loaddivReturn;
           directionCounter++;
           directions[directionCounter] = div + divisionReturn;
           directionCounter++;
           temp++;
           outcome = tempString + java.lang.String.valueOf(temp);
           directions[directionCounter] = store + java.lang.String.valueOf(temp);
           directionCounter++;
           s.push(outcome);
        }

        //addition character
        else if (convertedChar.equals(plus)){
           String outcome;
           String additionReturn = PostfixConverter.addition(string);
           String loadAddReturn = PostfixConverter.addition(string);
           directions[directionCounter] = load + loadAddReturn;
           directionCounter++;
           directions[directionCounter] = add + additionReturn;
           directionCounter++;
           temp++;
           outcome = tempString + java.lang.String.valueOf(temp);
           directions[directionCounter] = store + java.lang.String.valueOf(temp);
           directionCounter++;
           s.push(outcome);
        }

        //subtraction character
        else if (convertedChar.equals(minus)){
           String outcome;
           String subtractionReturn = PostfixConverter.addition(string);
           String loadsubReturn = PostfixConverter.addition(string);
           directions[directionCounter] = load + loadsubReturn;
           directionCounter++;
           directions[directionCounter] = subtract + subtractionReturn;
           directionCounter++;
           temp++;
           outcome = tempString + java.lang.String.valueOf(temp);
           directions[directionCounter] = store +  java.lang.String.valueOf(temp);
           directionCounter++;
           s.push(outcome);
        }

        //letter character
        else {
           s.push(convertedChar);
        }

  }

  //print out the instructions
  System.out.println("Assembly Directions are as follows: ");
  int printDirections = 0;
  for (int i=0; i< directionCounter; i++){
        System.out.println(directions[printDirections]);
        printDirections++;
  }
  printDirections=0;
  directionCounter=0;
  System.out.println("This is the end of the directions.");
  System.out.println("");
  directionCounter = 0;
  temp = 0;
  top = 0;

 }
}
 catch (FileNotFoundException exception)
 {
     System.out.println("The file was not found.");
   }
 }


 //multiply method
 public static String multiply(String a){
    String multVariable = PostfixConverter.pop(mainStack[top]);
    top--;
    return multVariable;
 }

 //addition method
 public static String addition(String a){

    String addVariable = PostfixConverter.pop(mainStack[top]);
    top--;
    return addVariable;
 }

 //subtraction method
 public static String subtraction(String a){
  String subVariable = PostfixConverter.pop(mainStack[top]);
  top--;
  return subVariable;
 }

 //division method
 public static String division(String a){
  String divVariable = PostfixConverter.pop(mainStack[top]);
  top--;
  return divVariable;
  }

 public static boolean empty(){
  if (top == -1)
     return true;
  else 
     return false;

 }

 public static String pop(String j){
  if (empty()){
     System.out.println("Stack Underflow");
     System.exit(1);
    }
   return mainStack[top - 1];
 }

 public void push (String x){
  if (top == 99){
     System.out.println("Stack Overflow");
     System.exit(1);
  }else
     mainStack[top] = x;
     top++;
 }//end push

}

Here is what is being printed out:

Loop 1:

Assembly Directions are as follows:

LD A

AD B

ST TEMP1

LD TEMP1

SB C

ST TEMP2

This is the end of the directions. //looks to be correct

Loop 2:

Assembly Directions are as follows:

LD A //duplicated from above

AD B

ST TEMP1

LD TEMP1

SB C

ST TEMP2

LD B //where the 2nd loop actually starts

AD C

ST TEMP3

LD A

SB TEMP3

ST TEMP4

This is the end of the directions.

2
  • The input is three lines; is each line supposed to be processed independently? What exactly is wrong with the output? Exactly what did you expect? Commented Feb 24, 2016 at 3:27
  • @IanMc each line of the input should run through the program. I am expecting there to be 3 inputs and 3 separate outputs. To be more clear, the above two outputs are for the first two inputs. What is wrong with the program is that if looks like the output is not being pushed onto the array correctly. The output for the 2nd input looks to be taking the output from the first input and starting the print array with the first input as the first couple instructions. Please see where I state "where the 2nd loop actually starts". This should be the first instruction for the 2nd output. Commented Feb 24, 2016 at 4:26

1 Answer 1

1

I have slightly changed the way the file is being read, and included the output I get with the adjusted code. Let me know if this creates the expected result:

 String line = "";

 while ((line = reader.readLine()) != null)
 {
    example = line;
    // Continue to process ...

EDIT: Here is a more modular approach which demonstrates what I was referring to in the comments (notice the introduction of 'processOperand()', and how it makes the code more readable). It is just an example of looking for common code, and making it 'usable' for a variety of cases (i.e. each operation calls the same code block passing unique parameters)

public class PostfixConverter {

    static int top = 0;
    static String[] mainStack = new String[100];

    final static String asterisk = "*";
    final static String divisor = "/";
    final static String plus = "+";
    final static String minus = "-";
    final static String store = "ST TEMP";

    static int temp = 0;
    static int directionCounter = 0;
    static String[] directions = new String[100];
    static PostfixConverter s = new PostfixConverter();
    static String tempString = "TEMP";

    public static void main(String args[]) throws Exception {

        String string = null;

        String load = "LD ";
        String multiply = "ML ";
        String add = "AD ";
        String div = "DV ";
        String subtract = "SB ";

        String example = "AB+C-";

        try {
            // file reader code
            FileReader file = new FileReader("....");
            BufferedReader reader = new BufferedReader(file);

            String line = "";

            while ((line = reader.readLine()) != null) {
                example = line;

                // for loop to print directions
                for (int i = 0; i < example.length(); i++) {

                    // get letter entered by user 1 by 1
                    char letter = example.charAt(i);

                    // convert char to string
                    String convertedChar = java.lang.String.valueOf(letter);

                    // finds operands in order or priority
                    // multiply character
                    if (convertedChar.equals(asterisk)) {

                        processOperand(PostfixConverter.multiply(string), PostfixConverter.multiply(string), load,
                                multiply);
                    }

                    // division character
                    else if (convertedChar.equals(divisor)) {
                        processOperand(PostfixConverter.addition(string), PostfixConverter.addition(string), load, div);
                    }

                    // addition character
                    else if (convertedChar.equals(plus)) {
                        processOperand(PostfixConverter.addition(string), PostfixConverter.addition(string), load, add);
                    }

                    // subtraction character
                    else if (convertedChar.equals(minus)) {
                        processOperand(PostfixConverter.addition(string), PostfixConverter.addition(string), load,
                                subtract);

                    }
                    // letter character
                    else {
                        s.push(convertedChar);
                    }

                }

                // print out the instructions
                System.out.println("Assembly Directions are as follows: ");
                int printDirections = 0;
                for (int i = 0; i < directionCounter; i++) {
                    System.out.println(directions[printDirections]);
                    printDirections++;
                }
                printDirections = 0;
                directionCounter = 0;
                System.out.println("This is the end of the directions.");
                System.out.println("");
                directionCounter = 0;
                temp = 0;
                top = 0;

            }
        } catch (FileNotFoundException exception) {
            System.out.println("The file was not found.");
        }
    }

    private static void processOperand(String postFileConverterOutput, String postFileConverterOutput2,
            String instruction1, String instruction2) {
        String outcome;
        String opReturn1 = postFileConverterOutput;
        String opReturn2 = postFileConverterOutput2;
        directions[directionCounter] = instruction1 + opReturn2;
        directionCounter++;
        directions[directionCounter] = instruction2 + opReturn1;
        directionCounter++;
        temp++;
        outcome = tempString + java.lang.String.valueOf(temp);
        directions[directionCounter] = store + java.lang.String.valueOf(temp);
        directionCounter++;
        s.push(outcome);
    }

    // multiply method
    public static String multiply(String a) {
        String multVariable = PostfixConverter.pop(mainStack[top]);
        top--;
        return multVariable;
    }

    // addition method
    public static String addition(String a) {

        String addVariable = PostfixConverter.pop(mainStack[top]);
        top--;
        return addVariable;
    }

    // subtraction method
    public static String subtraction(String a) {
        String subVariable = PostfixConverter.pop(mainStack[top]);
        top--;
        return subVariable;
    }

    // division method
    public static String division(String a) {
        String divVariable = PostfixConverter.pop(mainStack[top]);
        top--;
        return divVariable;
    }

    public static boolean empty() {
        if (top == -1)
            return true;
        else
            return false;

    }

    public static String pop(String j) {
        if (empty()) {
            System.out.println("Stack Underflow");
            System.exit(1);
        }
        return mainStack[top - 1];
    }

    public void push(String x) {
        if (top == 99) {
            System.out.println("Stack Overflow");
            System.exit(1);
        } else
            mainStack[top] = x;
        top++;
    }// end push

}

Creating an output of:

Assembly Directions are as follows: 
LD A
AD B
ST TEMP1
LD TEMP1
SB C
ST TEMP2
This is the end of the directions.

Assembly Directions are as follows: 
LD B
AD C
ST TEMP1
LD A
SB TEMP1
ST TEMP2
This is the end of the directions.

Assembly Directions are as follows: 
LD A
SB B
ST TEMP1
LD TEMP1
AD C
ST TEMP2
LD E
SB F
ST TEMP3
LD D
AD TEMP3
ST TEMP4
This is the end of the directions.
Sign up to request clarification or add additional context in comments.

12 Comments

This now works. Thank you very much. As for learning more, is there anything in the code you would do differently? Any code you would suggest to add/subtract. Thank you for your help.
I would encourage you to look for repetitive code blocks (there are several) and refactor them into methods. The arithmetic code blocks share a great deal in common; you could simplify the code greatly, and thus make it more readable and modifiable using this approach. Make sense? I could post example if you are interested. (also can you please mark answer as useful if it helped you ... cheers).
I marked as useful. Thanks again for the help. Yes, if you don't mind posting an example that would be greatly appreciated. I posted this question to debug but more importantly learn how to improve my code, so that would be a big help.
Code refactored to use the repeated blocks in a more modular fashion.
thanks so much for the help. I also added a reader.close(); in there, but i am still getting the below error. any idea why? Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1 at PostfixConverter.pop(PostfixConverter.java:167) at PostfixConverter.multiply(PostfixConverter.java:127) at PostfixConverter.main(PostfixConverter.java:58)
|

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.