/* Java code generated by "translate.java.pss" */ import java.io.*; import java.util.regex.*; import java.util.*; // contains stack public class plzero { // using int instead of char so that all unicode code points are // available instead of just utf16. (emojis cant fit into utf16) private int accumulator; // counter for anything private int peep; // next char in input stream private int charsRead; // No. of chars read so far private int linesRead; // No. of lines read so far public StringBuffer workspace; // text accumulator private Stack stack; // parse token stack private int LENGTH; // tape initial length // use ArrayLists instead with .add() .get(n) and .set(n, E) // ArrayList al=new ArrayList(); private List tape; // array of token attributes private List marks; // tape marks private int tapePointer; // pointer to current cell private Reader input; // text input stream private boolean eof; // end of stream reached? private boolean flag; // not used here private StringBuffer escape; // char used to "escape" others "\" private StringBuffer delimiter; // push/pop delimiter (default is "*") private boolean markFound; // if the mark was found in tape /** make a new machine with a character stream reader */ public plzero(Reader reader) { this.markFound = false; this.LENGTH = 100; this.input = reader; this.eof = false; this.flag = false; this.charsRead = 0; this.linesRead = 1; this.escape = new StringBuffer("\\"); this.delimiter = new StringBuffer("*"); this.accumulator = 0; this.workspace = new StringBuffer(""); this.stack = new Stack(); this.tapePointer = 0; this.tape = new ArrayList(); this.marks = new ArrayList(); for (int ii = 0; ii < this.LENGTH; ii++) { this.tape.add(new StringBuffer("")); this.marks.add(new StringBuffer("")); } try { this.peep = this.input.read(); } catch (java.io.IOException ex) { System.out.println("read error"); System.exit(-1); } } /** read one character from the input stream and update the machine. */ public void read() { int iChar; try { if (this.eof) { System.exit(0); } this.charsRead++; // increment lines if ((char)this.peep == '\n') { this.linesRead++; } this.workspace.append(Character.toChars(this.peep)); this.peep = this.input.read(); if (this.peep == -1) { this.eof = true; } } catch (IOException ex) { System.out.println("Error reading input stream" + ex); System.exit(-1); } } /** increment tape pointer by one */ public void increment() { this.tapePointer++; if (this.tapePointer >= this.LENGTH) { this.tape.add(new StringBuffer("")); this.marks.add(new StringBuffer("")); this.LENGTH++; } } /** remove escape character */ public void unescapeChar(char c) { if (workspace.length() > 0) { String s = this.workspace.toString().replace("\\"+c, c+""); this.workspace.setLength(0); workspace.append(s); } } /** add escape character */ public void escapeChar(char c) { if (workspace.length() > 0) { String s = this.workspace.toString().replace(c+"", "\\"+c); workspace.setLength(0); workspace.append(s); } } /** whether trailing escapes \\ are even or odd */ // untested code. check! eg try: add "x \\"; print; etc public boolean isEscaped(String ss, String sSuffix) { int count = 0; if (ss.length() < 2) return false; if (ss.length() <= sSuffix.length()) return false; if (ss.indexOf(this.escape.toString().charAt(0)) == -1) { return false; } int pos = ss.length()-sSuffix.length(); while ((pos > -1) && (ss.charAt(pos) == this.escape.toString().charAt(0))) { count++; pos--; } if (count % 2 == 0) return false; return true; } /* a helper to see how many trailing \\ escape chars */ private int countEscaped(String sSuffix) { String s = ""; int count = 0; int index = this.workspace.toString().lastIndexOf(sSuffix); // remove suffix if it exists if (index > 0) { s = this.workspace.toString().substring(0, index); } while (s.endsWith(this.escape.toString())) { count++; s = s.substring(0, s.lastIndexOf(this.escape.toString())); } return count; } /** reads the input stream until the workspace end with text */ // can test this with public void until(String sSuffix) { // read at least one character if (this.eof) return; this.read(); while (true) { if (this.eof) return; if (this.workspace.toString().endsWith(sSuffix)) { if (this.countEscaped(sSuffix) % 2 == 0) { return; } } this.read(); } } /** pop the first token from the stack into the workspace */ public Boolean pop() { if (this.stack.isEmpty()) return false; this.workspace.insert(0, this.stack.pop()); if (this.tapePointer > 0) this.tapePointer--; return true; } /** push the first token from the workspace to the stack */ public Boolean push() { String sItem; // dont increment the tape pointer on an empty push if (this.workspace.length() == 0) return false; // need to get this from this.delim not "*" int iFirstStar = this.workspace.indexOf(this.delimiter.toString()); if (iFirstStar != -1) { sItem = this.workspace.toString().substring(0, iFirstStar + 1); this.workspace.delete(0, iFirstStar + 1); } else { sItem = this.workspace.toString(); this.workspace.setLength(0); } this.stack.push(sItem); this.increment(); return true; } /** swap current tape cell with the workspace */ public void swap() { String s = new String(this.workspace); this.workspace.setLength(0); this.workspace.append(this.tape.get(this.tapePointer).toString()); this.tape.get(this.tapePointer).setLength(0); this.tape.get(this.tapePointer).append(s); } /** save the workspace to file "sav.pp" */ public void writeToFile() { try { File file = new File("sav.pp"); Writer out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(file), "UTF8")); out.append(this.workspace.toString()); out.flush(); out.close(); } catch (Exception e) { System.out.println(e.getMessage()); } } public void goToMark(String mark) { this.markFound = false; for (var ii = 0; ii < this.marks.size(); ii++) { if (this.marks.get(ii).toString().equals(mark)) { this.tapePointer = ii; this.markFound = true; } } if (this.markFound == false) { System.out.print("badmark '" + mark + "'!"); System.exit(1); } } /** parse/check/compile the input */ public void parse(InputStreamReader input) { //this is where the actual parsing/compiling code should go //but this means that all generated code must use //"this." not "mm." } public static void main(String[] args) throws Exception { String temp = ""; plzero mm = new plzero(new InputStreamReader(System.in)); script: while (!mm.eof) { lex: { mm.read(); /* read */ // make character numbers (for error messages) relative // to line numbers if (mm.workspace.toString().equals("\n")) { mm.workspace.setLength(0); /* clear */ mm.charsRead = 0; /* nochars */ break lex; } if (mm.workspace.toString().matches("^\\p{Space}+$")) { mm.workspace.setLength(0); /* clear */ break lex; } if (mm.workspace.toString().equals("+") || mm.workspace.toString().equals("-")) { mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("opadd*"); /* add */ mm.push(); break lex; } if (mm.workspace.toString().equals("*") || mm.workspace.toString().equals("/")) { mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("opmul*"); /* add */ mm.push(); break lex; } // modern pascal style comments, but not (* ... *) because // they are tricky to parse. if (mm.workspace.toString().equals("{")) { // save the line number for possible error message later mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.linesRead); /* lines */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("{"); /* add */ mm.until("}"); if (mm.workspace.toString().endsWith("}")) { // can convert to another format mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ // create a "comment" parse token // comment-out this line to remove multiline comments from the // translated code // add "comment*"; push; break lex; } // make an unterminated multiline comment an error // to ease debugging of scripts. mm.workspace.setLength(0); /* clear */ mm.workspace.append("[pl/0 error] Unterminated pascal comment { ... } \n"); /* add */ mm.workspace.append("stating at line number "); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ System.out.print(mm.workspace); /* print */ mm.workspace.setLength(0); /* clear */ break script; } if (mm.workspace.toString().equals("*") || mm.workspace.toString().equals("/")) { mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("opmul*"); /* add */ mm.push(); break lex; } // literal tokens // '!' is the print command in pl/0 // '?' is the read command in pl/0 // '#' means != // '.' marks the end of a program. if (mm.workspace.toString().equals(".") || mm.workspace.toString().equals(",") || mm.workspace.toString().equals("=") || mm.workspace.toString().equals(";") || mm.workspace.toString().equals("(") || mm.workspace.toString().equals(")")) { mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.append("*"); /* add */ mm.push(); break lex; } if (mm.workspace.toString().equals("!")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append("write"); /* add */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("!*"); /* add */ mm.push(); break lex; } if (mm.workspace.toString().equals("?")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append("read"); /* add */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("?*"); /* add */ mm.push(); break lex; } // also need to parse <= >= comparison operators // '=' is comparison and also constant assignment. if (mm.workspace.toString().equals("<") || mm.workspace.toString().equals(">") || mm.workspace.toString().equals("#")) { /* while */ while (Character.toString((char)mm.peep).matches("^[=]+$")) { if (mm.eof) { break; } mm.read(); } if (!mm.workspace.toString().equals("<") && !mm.workspace.toString().equals(">") && !mm.workspace.toString().equals(">=") && !mm.workspace.toString().equals("<=") && !mm.workspace.toString().equals("#")) { // error, message and quit mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("[pl/0 error] unrecognised operator "); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" at line/char "); /* add */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append("/"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append("\n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } if (mm.workspace.toString().equals("#")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append("!="); /* add */ } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("compare*"); /* add */ mm.push(); } if (mm.workspace.toString().equals(":")) { if (mm.eof) { mm.workspace.setLength(0); /* clear */ mm.workspace.append("trailing : at end of file!\n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } mm.read(); /* read */ if (mm.workspace.toString().equals(":=")) { mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.append("*"); /* add */ mm.push(); break lex; } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("[pl/0 error] unrecognised operator "); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" at line/char "); /* add */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append("/"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append("\n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } if (mm.workspace.toString().matches("^[0-9]+$")) { /* while */ while (Character.toString((char)mm.peep).matches("^[0-9]+$")) { if (mm.eof) { break; } mm.read(); } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("number*"); /* add */ mm.push(); break lex; } if (mm.workspace.toString().matches("^\\p{Alpha}+$")) { /* while */ while (Character.toString((char)mm.peep).matches("^\\p{Alpha}+$")) { if (mm.eof) { break; } mm.read(); } // make keywords case insensitive mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); /* lower */ for (int i = 0; i < mm.workspace.length(); i++) { char c = mm.workspace.charAt(i); mm.workspace.setCharAt(i, Character.toLowerCase(c)); } // synonym with ! if (mm.workspace.toString().equals("write") || mm.workspace.toString().equals("writeln")) { mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("!*"); /* add */ mm.push(); break lex; } // keywords in pl/0 if (mm.workspace.toString().equals("const") || mm.workspace.toString().equals("var") || mm.workspace.toString().equals("if") || mm.workspace.toString().equals("then") || mm.workspace.toString().equals("while") || mm.workspace.toString().equals("do") || mm.workspace.toString().equals("begin") || mm.workspace.toString().equals("end") || mm.workspace.toString().equals("proc") || mm.workspace.toString().equals("procedure") || mm.workspace.toString().equals("call") || mm.workspace.toString().equals("odd")) { // or add ".key*" to remind us that these are keywords, // not parse tokens // add a space here for pretty printing later mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); if (mm.workspace.toString().equals("procedure")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append("proc"); /* add */ } mm.workspace.append("*"); /* add */ mm.push(); break lex; } // restore non-lower case identifier mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("ident*"); /* add */ mm.push(); break lex; } if (!mm.workspace.toString().equals("")) { // error unrecognised character mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append(":"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append(" [pl/0 error] incorrect character '"); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("'\n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } } parse: while (true) { // To visualise token reduction uncomment this below: mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append(":"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append(" "); /* add */ System.out.print(mm.workspace); /* print */ mm.workspace.setLength(0); /* clear */ mm.workspace.append("\n"); /* add */ while (mm.pop()); /* unstack */ System.out.print(mm.workspace); /* print */ if (mm.workspace.length() > 0) { /* clip */ mm.workspace.delete(mm.workspace.length() - 1, mm.workspace.length()); } while(mm.push()); /* stack */ // we will do these 5 token reductions first, so that // "statement*end*" does not have precedence mm.pop(); mm.pop(); mm.pop(); mm.pop(); mm.pop(); // sometimes statements are terminated by expressions, which // in turn must be terminated by something else, so there is a // trailing token there if (mm.workspace.toString().startsWith("if*condition*then*statement*") && !mm.workspace.toString().equals("if*condition*then*statement*")) { /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("if*condition*then*statement*", "statement*"); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.push(); mm.push(); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(" "); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ // transfer 'invisible' token value mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.setLength(0); /* clear */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ continue parse; } if (mm.workspace.toString().startsWith("while*condition*do*statement*") && !mm.workspace.toString().equals("while*condition*do*statement*")) { /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("while*condition*do*statement*", "statement*"); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.push(); mm.push(); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(" "); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ // transfer invisible token value, and realign tape pointer mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.setLength(0); /* clear */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ continue parse; } mm.push(); mm.push(); mm.push(); mm.push(); mm.push(); //----------------- // 1 token mm.pop(); // errors if (mm.eof && !mm.workspace.toString().equals(".*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append(":"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append(" [pl/0 error] Missing '.' at end of program ? \n"); /* add */ mm.workspace.append(" \n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } //----------------- // 2 tokens mm.pop(); // Some errors if (mm.workspace.toString().equals("ident*ident*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append(":"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append(" [pl/0 error] 2 variable names in a row (is there a \n"); /* add */ mm.workspace.append(" missing operator?) \n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } if (mm.workspace.toString().equals("vardec*const*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append(":"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append(" [pl/0 error] Constant declarations must precede variable \n"); /* add */ mm.workspace.append(" declarations in pl/0 \n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } if (mm.workspace.toString().equals("condec*const*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append(":"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append(" [pl/0 error] only 1 constant declaration block is allowed \n"); /* add */ mm.workspace.append(" in each scope \n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } if (mm.workspace.toString().equals("vardec*var*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append(":"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append(" [pl/0 error] only 1 variable declaration block is allowed \n"); /* add */ mm.workspace.append(" in each scope \n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } if (mm.workspace.toString().equals(";*end*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.linesRead); /* lines */ mm.workspace.append(":"); /* add */ mm.workspace.append(mm.charsRead); /* chars */ mm.workspace.append(" [pl/0 error] Last statement in block does not require \n"); /* add */ mm.workspace.append(" a semi-colon ';' \n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } // add an empty procset* (set of procedures) if there is // not one already. This simplifies program reduction later // it doesnt matter if there is 1 or 2 tokens here. if (mm.workspace.toString().endsWith("proc*") && !mm.workspace.toString().startsWith("procset*")) { if (!mm.workspace.toString().equals("proc*")) { // need to conserve the preceding token mm.push(); mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.setLength(0); /* clear */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.append("procset*proc*"); /* add */ mm.push(); mm.push(); continue parse; } // only 1 token mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.setLength(0); /* clear */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.append("procset*proc*"); /* add */ mm.push(); mm.push(); continue parse; } // procedure headers (name etc) if (mm.workspace.toString().equals("procset*proceed*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("procset*"); /* add */ mm.push(); continue parse; } // "=" can be used for constant assignment but also as // a comparison operator if (mm.workspace.toString().equals("=*ident*") || mm.workspace.toString().equals("=*exp*")) { /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("=*", "compare*"); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.push(); mm.push(); continue parse; } if (mm.workspace.toString().equals("exp*=*")) { /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("=*", "compare*"); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.push(); mm.push(); continue parse; } // expression transmog if (mm.workspace.toString().equals("opmul*ident*") || mm.workspace.toString().equals("opadd*ident*") || mm.workspace.toString().equals("opmul*number*") || mm.workspace.toString().equals("opadd*number*") || mm.workspace.toString().equals("compare*ident*") || mm.workspace.toString().equals("compare*number*") || mm.workspace.toString().equals(":=*ident*") || mm.workspace.toString().equals(":=*number*") || mm.workspace.toString().equals("if*ident*") || mm.workspace.toString().equals("if*number*") || mm.workspace.toString().equals("while*ident*") || mm.workspace.toString().equals("while*number*") || mm.workspace.toString().equals("(*ident*") || mm.workspace.toString().equals("(*number*") || mm.workspace.toString().equals("!*ident*") || mm.workspace.toString().equals("!*number*")) { mm.push(); mm.workspace.setLength(0); /* clear */ mm.workspace.append("exp*"); /* add */ mm.push(); continue parse; } // expression transmutation if (mm.workspace.toString().equals("ident*opmul*") || mm.workspace.toString().equals("ident*opadd*") || mm.workspace.toString().equals("number*opmul*") || mm.workspace.toString().equals("number*opadd*") || mm.workspace.toString().equals("ident*compare*") || mm.workspace.toString().equals("number*compare*")) { /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("ident*", "exp*"); mm.workspace.setLength(0); mm.workspace.append(temp); } /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("number*", "exp*"); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.push(); mm.push(); continue parse; } if (mm.workspace.toString().equals("const*conlist*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("condec*"); /* add */ mm.push(); continue parse; } // non-tail reduction for variables if (mm.workspace.toString().equals("var*ident*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("varlist*"); /* add */ mm.push(); continue parse; } // variable decs if (mm.workspace.toString().equals("varlist*;*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("vardec*"); /* add */ mm.push(); continue parse; } if (mm.workspace.toString().equals("block*.*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append("program*"); /* add */ mm.push(); continue parse; } if (mm.workspace.toString().equals("call*ident*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("statement*"); /* add */ mm.push(); continue parse; } if (mm.workspace.toString().equals("?*ident*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("statement*"); /* add */ mm.push(); continue parse; } // a multi statement block, between begin/end if (mm.workspace.toString().equals("begin*statementset*")) { // ident statements, mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("\n", "\n "); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.workspace.append("\nend"); /* add */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("statement*"); /* add */ mm.push(); continue parse; } // tail reduction for statementsets if (mm.workspace.toString().equals("statement*end*")) { mm.workspace.setLength(0); /* clear */ //get; ++; get; --; put; clear; mm.workspace.append("statementset*"); /* add */ mm.push(); continue parse; } //----------------- // 3 tokens mm.pop(); // ! expression must be parsed while looked at the // trailing token, like all expression parsing if (mm.workspace.toString().startsWith("!*exp*") && !mm.workspace.toString().equals("!*exp*") && !mm.workspace.toString().endsWith("opmul*") && !mm.workspace.toString().endsWith("opadd*")) { // need to conserve the "invisible" last token /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("!*exp*", "statement*"); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.push(); mm.push(); // also transfer attributes if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.increment(); /* ++ */ continue parse; } // procedure headers (name etc) if (mm.workspace.toString().equals("proc*ident*;*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("prochead*"); /* add */ mm.push(); continue parse; } // procedure headers (name etc) if (mm.workspace.toString().equals("prochead*statement*;*")) { // indent the statement if it is not a begin/end construct mm.workspace.setLength(0); /* clear */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (!mm.workspace.toString().startsWith("begin")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(" "); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("\n", "\n "); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); } if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("proceed*"); /* add */ mm.push(); continue parse; } // expressions, this could be the trickiest aspect of // the grammar. transmog ident/number to exp if (mm.workspace.toString().equals("exp*opmul*exp*") || mm.workspace.toString().equals("exp*opadd*exp*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("exp*"); /* add */ mm.push(); continue parse; } if (mm.workspace.toString().equals("(*exp*)*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("exp*"); /* add */ mm.push(); continue parse; } // this is reverse reduction of statements, which can be // useful since exp* requires a trailing token in order to // resolve. if (mm.workspace.toString().equals("statement*;*statementset*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(";\n"); /* add */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("statementset*"); /* add */ mm.push(); continue parse; } // variable decs if (mm.workspace.toString().equals("varlist*,*ident*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("varlist*"); /* add */ mm.push(); continue parse; } //----------------- // 4 tokens mm.pop(); // procedure headers (name etc). Need to indent the variable decs etc if (mm.workspace.toString().equals("prochead*vardec*statement*;*") || mm.workspace.toString().equals("prochead*condec*statement*;*")) { // indent the variable/constant declaration mm.workspace.setLength(0); /* clear */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("\n", "\n "); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("proceed*"); /* add */ mm.push(); continue parse; } // ident and number have already been transmog'ed into exp* // and =* into compare* if (mm.workspace.toString().startsWith("exp*compare*exp*") && !mm.workspace.toString().equals("exp*compare*exp*") && !mm.workspace.toString().endsWith("opmul*") && !mm.workspace.toString().endsWith("opadd*")) { // need to conserve the "invisible" last token /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("exp*compare*exp*", "condition*"); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.push(); mm.push(); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ // transfer trailing token value mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.increment(); /* ++ */ mm.workspace.setLength(0); /* clear */ continue parse; } // also see the 5 token reduction, because of the trailing token // required by exp* if (mm.workspace.toString().equals("if*condition*then*statement*") || mm.workspace.toString().equals("while*condition*do*statement*")) { // indent the statement if it is not a begin/end construct mm.workspace.setLength(0); /* clear */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (!mm.workspace.toString().startsWith("begin")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(" "); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("\n", "\n "); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); } if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.setLength(0); /* clear */ mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("statement*"); /* add */ mm.push(); continue parse; } // lookahead for expressions in statements // the problem is: x:=4*3+1 will be parsed at // statement*+1 if no lookahead. // If the expression // is not followed by a */+- then it is a complete statement // and can be reduced. lets transmog ident and number to make simpler if (mm.workspace.toString().startsWith("ident*:=*exp*") && !mm.workspace.toString().equals("ident*:=*exp*") && !mm.workspace.toString().endsWith("opmul*") && !mm.workspace.toString().endsWith("opadd*")) { // need to conserve the "invisible" last token /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("ident*:=*exp*", "statement*"); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.push(); mm.push(); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.increment(); /* ++ */ mm.increment(); /* ++ */ continue parse; } // tail reduction for constant decs if (mm.workspace.toString().equals("ident*=*number*;*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("conlist*"); /* add */ mm.push(); continue parse; } // if (mm.workspace.toString().equals("ident*;*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("varlist*"); /* add */ mm.push(); continue parse; } //----------------- // 5 tokens mm.pop(); // procedure headers (name etc), need to indent condec vardec if (mm.workspace.toString().equals("prochead*condec*vardec*statement*;*")) { // indent the variable and constant declarations mm.workspace.setLength(0); /* clear */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("\n", "\n "); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ /* replace */ if (mm.workspace.length() > 0) { temp = mm.workspace.toString().replace("\n", "\n "); mm.workspace.setLength(0); mm.workspace.append(temp); } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("proceed*"); /* add */ mm.push(); continue parse; } // constant declarations, tail reduction, but tail redux not // necessary if (mm.workspace.toString().equals("ident*=*number*,*conlist*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append(" "); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("conlist*"); /* add */ mm.push(); continue parse; } // program reduction if (mm.eof) { if (mm.workspace.toString().equals("statement*.*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("program*"); /* add */ } if (mm.workspace.toString().equals("vardec*statement*.*") || mm.workspace.toString().equals("condec*statement*.*") || mm.workspace.toString().equals("procset*statement*.*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n{ main program }\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("program*"); /* add */ } if (mm.workspace.toString().equals("condec*vardec*statement*.*") || mm.workspace.toString().equals("vardec*procset*statement*.*") || mm.workspace.toString().equals("condec*procset*statement*.*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n{ main program }\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("program*"); /* add */ } if (mm.workspace.toString().equals("condec*vardec*procset*statement*.*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n{ main program }\n"); /* add */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.increment(); /* ++ */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ if (mm.tapePointer > 0) mm.tapePointer--; /* -- */ mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("program*"); /* add */ } } if (mm.eof) { while (mm.pop()); /* unstack */ if (mm.workspace.toString().equals("program*")) { mm.workspace.setLength(0); /* clear */ mm.workspace.append("{ ok pl/0 }\n"); /* add */ mm.workspace.append("{ code checked and formatted by eg/plzero.pss }\n"); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } mm.tape.get(mm.tapePointer).setLength(0); /* put */ mm.tape.get(mm.tapePointer).append(mm.workspace); mm.workspace.setLength(0); /* clear */ mm.workspace.append("Pl/0 program did not parse well \n"); /* add */ mm.workspace.append("The final parse tokens were: "); /* add */ mm.workspace.append(mm.tape.get(mm.tapePointer)); /* get */ mm.workspace.append("\n"); /* add */ System.out.print(mm.workspace); /* print */ break script; } mm.push(); mm.push(); mm.push(); mm.push(); mm.push(); break parse; } } } }