//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=""; public int in_flag =0; public int out_flag=0; public String input=""; public String output=""; } //array of commands to hold in case of piping class CommandArray { public Vector Commands = new Vector(3,1); public int count = 0; //adds a new command to the list public void Append(Command nCommand){ Commands.addElement(nCommand); count++; } } //the guts of the parser public class Parser extends WorkerThread { //------------------------------- //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; boolean input_func = false; Command currentCommand =new Command(); CommandArray cmd_list = new CommandArray(); System.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 ++; System.out.println("create virtual machine vm" + vmcount + ": " + 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; 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; 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++; System.out.println("create pipe p" + pipecount); xstate = state; state=6; 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 { //return an argument in command.args expecting = false; currentCommand.args = currentCommand.args +" "+ t; } System.out.println("In State 1:" + t); continue NEXT; case 2: //state for input redirect state = xstate; //check to make sure you only accept one input redirect if (isIdentifier(t) && !(input_func)){ currentCommand.input = t; currentCommand.in_flag = 1; expecting = false; input_func = true; System.out.println("set vm" + vmcount + ".IN = open file: " + t); } else if (input_func) { //error throw(new Exception("Unexpected Continuation of Line")); } else { //error throw (new Exception( "File Name Expected. 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)){ System.out.println("create pipe p" + pipecount++ ); state=6; 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; } } //dumb way to catch the error, but using an else does not work //gives error that System.out line below is unreachable if (!isPipe(t) && !isOutputRedirect(t)) { //error throw(new Exception("File Name Expected. 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; System.out.println("set vm" + vmcount + ".OUT = creator's OUT"); } else { //error throw(new Exception("File Name Expected. Found:"+t)); } continue NEXT; case 5: //empty state - hopefully will remove in future System.out.println("In State 5:" + t); continue NEXT; case 6: System.out.println("set vm" + vmcount + ".OUT = p" + pipecount + ".IN"); if (isIdentifier(t)){ //a command has been recognized currentCommand.command=t; state = 3; expecting = false; vmcount++; System.out.println("create virtual machine vm" + vmcount + ": " + t); System.out.println("set p" + pipecount + ".OUT = vm" + vmcount + ".IN"); } else { //error throw(new Exception("Command Expected. Found:"+t)); } continue NEXT; default: System.out.println("In State x:" + t); break; } if ( expecting ){ throw(new Exception("Unexpected end of line")); } } //end NEXTswitch return cmd_list; } //end parse } //end class