//Dennis Version of parser import java.io.*; import java.util.*; //class to store the elements of a command line class Command { public String command = ""; public String[] args = new String[20]; public int in_flag = 0; public int out_flag = 0; public String input = ""; public String output = ""; public int argcount = 0; public void ArgAppend(String nArg){ args[argcount] = nArg; argcount++; } } //array of commands to hold in case of piping class CommandArray { public Command[] Commands = new Command[20]; public int count = 0; //adds a new command to the list public void Append(Command nCommand){ Commands[count] = (nCommand); count++; } } //the guts of the parser public class Parser extends VMachine { //------------------------------- //checker functions - look for identifiers, input, output, and pipes //check to see if p is a command public boolean isIdentifier(String p) { int len = p.length(); for (int i=0; i') { return true; } return false; } //check to see if p is a pipe public boolean isPipe(String p){ if(p.charAt(0)=='|') { return true; } return false; } //------------------------------------------------- //below is the parse function public CommandArray Parse( String lineToParse ) throws Exception { //declarations int state = 0; int xstate = 0; int vmcount = 0; int pipecount = 0; boolean gotToken = false; String t =""; boolean expecting = true; boolean done = false; Command currentCommand = new Command(); CommandArray cmd_list = new CommandArray(); // PrintWriter out = console.PrintWriter(); // out.println("\nThis is the line to be Parsed: " + lineToParse + "\n"); StringTokenizer tokens = new StringTokenizer(lineToParse); //check the line and continue while there is text on the line NEXT:while (gotToken || tokens.hasMoreTokens()) { if (!gotToken){ t = tokens.nextToken(); } gotToken = false; if (done){ throw(new Exception("Unexpected Continuation of Line")); } //switch on states switch (state){ case 0: //state for command //this must be an identifier to a command if (isIdentifier(t)) { //we have a command currentCommand.command=t; vmcount ++; // out.println("VM" + vmcount + " = create_vm(IN=STDIN, OUT=STDOUT, thr = \"" + t + "\")"); state = 1; } else { //if not an Identifier (a letter followed by letters or digits) //error throw(new Exception("Command Expected. Found: \"" + t + "\"")); } expecting = false; continue NEXT; case 1: //could be: inputredir, outputredir, pipe, arguement, or nothing //check for input redirect if (isInputRedirect(t)){ xstate = state; state=2; //if (expecting == false) { out.println("VM" + vmcount + ".args: \"" + currentCommand.args + "\""); } expecting = true; if (t.length()>1) { t = t.substring(1); gotToken = true; continue NEXT; } else { gotToken = false; continue NEXT; } //check for output redirect } else if(isOutputRedirect(t)) { xstate = state; state=4; //if (expecting == false) { out.println("VM" + vmcount + ".args: \"" + currentCommand.args + "\""); } expecting = true; if (t.length()>1){ t = t.substring(1); gotToken = true; continue NEXT; } else { gotToken = false; continue NEXT; } //check for a pipe } else if(isPipe(t)){ pipecount++; //if (expecting == false) { out.println("VM" + vmcount + ".args: \"" + currentCommand.args + "\""); } // out.println("P" + pipecount + " = create_pipe()"); xstate = state; state=5; expecting = true; cmd_list.Append(currentCommand); currentCommand = new Command(); if (t.length()>1){ t = t.substring(1); gotToken = true; continue NEXT; } else { gotToken = false; continue NEXT; } } if (!isPipe(t) && !isOutputRedirect(t) && !isInputRedirect(t)) { //return an argument in command.args expecting = false; currentCommand.ArgAppend(t); } continue NEXT; case 2: //state for input redirect state = 3; //check to make sure you only accept one input redirect if (isIdentifier(t)) { currentCommand.input = t; currentCommand.in_flag = 1; expecting = false; // out.println("VM" + vmcount + ".IN = open file(\"" + t + "\")"); } else { //error throw(new Exception("ERROR: Expecting Input File Name. Found: " + t)); } continue NEXT; case 3: //state for after input redirect - can be either pipe or output redirect xstate = state; if(isOutputRedirect(t)) { state=4; expecting = true; if (t.length()>1){ t = t.substring(1); gotToken = true; continue NEXT; } else { gotToken = false; continue NEXT; } } else if(isPipe(t)){ pipecount++; // out.println("P" + pipecount + " = create_pipe()"); // out.println("create pipe p" + pipecount); state=5; expecting = true; cmd_list.Append(currentCommand); currentCommand = new Command(); if (t.length()>1){ t = t.substring(1); gotToken = true; continue NEXT; } else { gotToken = false; continue NEXT; } } else if (isIdentifier(t)) { //return an argument in command.args expecting = false; currentCommand.ArgAppend(t); } //dumb way to catch the error, but using an else does not work //gives error that out line below is unreachable if (!isPipe(t) && !isOutputRedirect(t) && !isIdentifier(t)) { //error throw (new Exception( "ERROR: Expecting Pipe or Output Redirection. Found: \"" + t + "\"")); } continue NEXT; case 4: //state for output redirection state = xstate; if (isIdentifier(t)){ currentCommand.output = t; currentCommand.out_flag = 1; expecting = false; done = true; // out.println("VM" + vmcount + ".OUT = open_file(\"" + t + "\")"); } else { //error throw(new Exception("File Name Expected. Found:"+t)); } continue NEXT; case 5: sysapi.Write(OUT,"John"); // out.println("VM" + vmcount + ".OUT = open_pipe(P" + pipecount + ", w)"); if (isIdentifier(t)){ //a command has been recognized currentCommand.command=t; state = 3; expecting = false; vmcount++; // out.println("VM" + vmcount + " = create_vm(IN=open_pipe(P" + pipecount + ", r), OUT=STDOUT, thr = \"" + t + "\")"); // out.println("create virtual machine vm" + vmcount + ": " + t); // out.println("set p" + pipecount + ".OUT = vm" + vmcount + ".IN"); } else { //error throw(new Exception("Command Expected. Found:"+t)); } continue NEXT; default: // out.println("In State x:" + t); break; } if ( expecting ){ throw(new Exception("Unexpected end of line")); } } //end NEXTswitch //if (state == 1) { out.println("VM" + vmcount + ".args: \"" + currentCommand.args + "\""); } // out.println("EXIT"); cmd_list.Append(currentCommand); return cmd_list; } //end parse } //end class