import java.util.*; import java.*; import java.io.*; public class Parser { private Scanner my_scanner; private PrintWriter output; //This scanner gets the input numbers from input_values file. java.util.Scanner input_list; // Store all the IDENTS ID and their values here private Hashtable variables = new Hashtable(); public Parser(String input_file, String input_values, String output_file) { my_scanner = new Scanner(input_file); output = new PrintWriter(new FileOutputStream(new File(output_file)), true); input_list = new java.util.Scanner(new File(input_values)); } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ public void code_interpreter() { computation(); // Add the necessary code output.close(); } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* This is the first method that should be called for parsing ** The program should of the form "main" [ varDecl ] "{" statSequence "}" "." ** If this template is violated in the input program, a parsing error should be generated */ public void computation() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** This method is responsible for parsing variable declaration list and populating the list of the defined variables. ** Variable decleration should have the form of "var" ident {"," ident } ";" An error should be generated if this form is violated. */ public void varDecl() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse statSequence: statement {";" statement }. */ public void statSequence() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse statement: assignment | funcCall | ifStatement */ public void statement() { int token = my_scanner.GetSym(); //Be aware that if you're using GetSym method, you are actually reading the token and advancing to the next token. //This means that if the token you read is "let" the next time you call GetSym you will read the next token in the input file // Check for assignment if (token == 100) assignment(); // Check for function call else if (token == 101) funcCall(); // check for if statement else if (token == 102) ifStatement(); else Error("The statement is neither an assignment or a function call or an \"if\" statement" ); } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse ifStatement: "if" relation "then" statSequence [ "else" statSequence ] "fi" */ public void ifStatement() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** "call" ident [ "(" [expression { "," expression } ] ")" ] ** ** If the called function is OutputNum or OutputNewLine then the return value of the function is assumed to be 0. */ public int funcCall() { int temp = my_scanner.GetSym(); if (temp != 61) Error("After \"call\" identifier of a function should be mentioned!"); if((my_scanner.Id2String(my_scanner.id)).compareTo("InputNum") == 0) return InputNum(); if((my_scanner.Id2String(my_scanner.id)).compareTo("OutputNum") == 0) OutputNum(); else if((my_scanner.Id2String(my_scanner.id)).compareTo("OutputNewLine") == 0) OutputNewLine(); return 0; } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse assignment: "let" ident "<-" expression ** make sure that you update the value of the variable which has been assigned to! */ public void assignment() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse relation: expression relOp expression ** The output of the relation will determine if you need to execute the statement sequence after then or ** the statement sequence after else (if there is any!) */ public bool relation() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse expression: term {("+"|"-") term} */ public int expression() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse term: factor {("*"|"/") factor} */ public int term() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse factor: ident | number | "(" expression ")" | funcCall | InputStat */ public int factor() { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse InputStat: "InputNum" "(" ")" ** I assume that the way that you know you have to execute this method is through parsing factor. So I assume that token "InputNum" ** has already been detected and here you are going to check for "(" and ")". Then you read a number from the input_values file and ** you will return the number as the value of the function! */ public int InputNum() { int temp = my_scanner.GetSym(); if (temp != 50) Error("\"(\" is missing after InputNum!"); temp = my_scanner.GetSym(); if (temp != 35) Error("\")\" is missing after InputNum("); return input_list.nextInt(); } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse "OutputNum" "(" expression ")" ** I assume that "OutputNum" is detected and then this method is called. */ public void OutputNum() { int temp = my_scanner.GetSym(); if (temp != 50) Error("\"(\" is missing after OutputNum."); int value = expression(); temp = my_scanner.GetSym(); if (temp != 35) Error("\")\" is missing after OutputNum(expression"); output.print(value); output.print("\t"); return; } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* ** Parse "OutputNewLine" "(" ")" ** I assume that "OutputNewLine" is detected and then this method is called. */ public void OutputNewLine() { int temp = my_scanner.GetSym(); if (temp != 50) Error("\"(\" is missing after OutputNewLine."); temp = my_scanner.GetSym(); if (temp != 35) Error("\")\" is missing after OutputNewLine("); output.print("\n"); return; } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ /* A call to this method should generate the error message, generate the necessary information (line number, etc) and then ** halt the program execution! */ private void Error (String errMsg) { //To be completed } //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ }//End of public class parser