// Joseph Bergin // Pace University // April, 1996 import java.util.*; import java.lang.Math; import java.lang.String; import java.io.*; import java.awt.*; public class Scanner { private final int allDone = -1; private final int scanningFile = 0; private final int scanningString = 1; private final int scanningTextField = 2; private int state = allDone; public Scanner(FileInputStream s) { inStream = s; state = scanningFile; } public Scanner(String s) { scanString = s; state = scanningString; } public Scanner(TextField t) { scanField = t; state = scanningTextField; } public void setErrorField(TextField t) { errorField = t; errorsToField = true; } static boolean isLetter(char c) { return (c>='a' && c<='z') || (c>='A' && c<='Z'); } static boolean isDigit(char c) { return (c>='0' && c<='9'); } static boolean isLetterOrDigit(char c) { return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'); } public int nextToken() { if (!tokenavailable) gettoken(); return (currenttoken); } public void match(int t) { if (!tokenavailable) gettoken(); if (currenttoken == t) toss(); else { parseError(" Match- trying " + t); } } public void toss() // Use this to reinitialize a Scanner's in buffer. { tokenavailable = false; } public void parseError(String s) { if(errorsToField) errorField.setText(s); else System.out.println(s); } void scanerror() { if(errorsToField) errorField.setText("Scan error."); else System.out.println("Scan error."); } public static final int number = 0; public static final int letter = 1; public static final int sumfunc = 2; public static final int prodfunc = 3; public static final int plusop = 4; public static final int minusop = 5; public static final int timesop = 6; public static final int divideop = 7; public static final int assignop = 8; public static final int rangeop = 9; public static final int lparen = 10; public static final int rparen = 11; public static final int period = 12; public static final int semicolon = 13; public static final int notoken = -1; private int currenttoken; // From the list above. private int value; // only when currentToken == number private String which; // only when currentToken is letter or function public String which() { return which; } public int value() { return value; } public int currenttoken() { return currenttoken; } private boolean tokenavailable = false; private byte [] linebuffer = new byte[81]; private int currentchar = 0; private int linelength = -1; private FileInputStream inStream = null; private String scanString = null; private TextField scanField = null; private TextField errorField = null; private boolean errorsToField = false; void readline() { linelength = 0; try { if(state == scanningFile)linelength = inStream.read(linebuffer); } catch (IOException e) { state = allDone; } if(state == scanningTextField) { String theText = scanField.getText(); // System.out.println(theText); linelength = theText.length(); for(int i = 0; i< linelength; i++) linebuffer[i] = (byte)theText.charAt(i); if(linelength == 0)linebuffer[linelength++] = (byte)';'; } if(state == scanningString) { linelength = scanString.length(); if(linelength > 0) { state = allDone; return; } for(int i = 0; i< linelength; i++) linebuffer[i] = (byte)scanString.charAt(i); } linebuffer[linelength] = ' '; currentchar = 0; } char inspect() { if (currentchar > linelength) readline(); return (char)linebuffer[currentchar]; } void advance() { currentchar++; } public final char tab = '\t'; public final char newline = '\n'; public final char space = ' '; int checkFunctions(String s) { if(s.equals("sum")) return sumfunc; if(s.equals("prod")) return prodfunc; return letter; } void gettoken() { char ch, TEMP, TEMP1; if(state == allDone) { currenttoken = notoken; return; } char [] spelling = new char[40]; String newSpell; int loc; TEMP = inspect(); while (TEMP == tab || TEMP == space || TEMP == newline) { advance(); TEMP = inspect(); } switch (TEMP) { case '=': currenttoken = assignop; advance(); break; case '+': currenttoken = plusop; advance(); break; case '-': currenttoken = minusop; advance(); break; case '*': currenttoken = timesop; advance(); break; case '/': currenttoken = divideop; advance(); break; case '(': currenttoken = lparen; advance(); break; case ')': currenttoken = rparen; advance(); break; case ';': currenttoken = semicolon; advance(); break; case '.': currenttoken = period; advance(); if(inspect()== '.') { currenttoken = rangeop; advance(); } break; default: if (isDigit(TEMP)) { currenttoken = number; value = inspect() - '0'; advance(); while (isDigit(inspect())) { value = value * 10 + inspect() - '0'; advance(); } } else if (isLetter(TEMP)) { ch = inspect(); if (Character.isUpperCase(ch)) ch = Character.toLowerCase(ch); spelling[0] = ch; loc = 1; advance(); while(isLetterOrDigit(inspect())) { spelling[loc++] = inspect(); advance(); } loc--; //spelling[loc] = '\0'; // newSpell = new char(strlen(spelling) +1); // strcpy(newSpell, spelling); which = (new String(spelling)).trim();//newSpell; currenttoken = checkFunctions(which); } break; } tokenavailable = true; } void dumptoken(int t) { System.out.println(""); break; case letter: System.out.println("let >"); break; case sumfunc: case prodfunc: System.out.println("fun >"); break; case plusop: System.out.println("+ >"); break; case minusop: System.out.println("- >"); break; case timesop: System.out.println("* >"); break; case divideop: System.out.println("/ >"); break; case assignop: System.out.println("= >"); break; case rangeop: System.out.println(".. >"); break; case lparen: System.out.println("( >"); break; case rparen: System.out.println(") >"); break; case period: System.out.println(". >"); break; case semicolon: System.out.println("; >"); break; } } }