four06% cat -n Scan.java 1 /* Scan.java: scanner implementation. 2 * Recognizes C-type comments 3 * Based on a finite-state automaton. 4 */ 5 import java.io.*; 6 public class Scan { 7 Reader in; // internal file name for input stream 8 boolean fileOpen = false; // is the file open yet? 9 String fileName; // name of input file, if present 10 11 // Scan(): constructor providing no input file name 12 public Scan() { 13 fileName = ""; 14 } 15 16 // Scan(String ): constructor providing input file name 17 public Scan(String f) { 18 fileName = f; 19 } 20 21 // getComment: recognize and return the next comment 22 public String getComment() throws IOException { 23 int state = 0; // state for the finite automaton 24 char ch = 0; // single-character buffer 25 String s = "/*"; 26 while (state != 4) { 27 if (ch == 65535) { //end-of-file 28 System.out.println("Th-th-th-that's all folks"); 29 System.exit(0); 30 } 31 switch (state) { 32 case 0: ch = getNextChar(); 33 if (ch == '/') state = 1; 34 else state = 0; break; 35 case 1: ch = getNextChar(); 36 if (ch == '*') state = 2; 37 else state = 0; break; 38 case 2: ch = getNextChar(); 39 s += ch; 40 if (ch == '*') state = 3; 41 else state = 2; break; 42 case 3: ch = getNextChar(); 43 s += ch; 44 if (ch == '*') state = 3; 45 else if (ch == '/') state = 4; 46 else state = 2; break; 47 case 4: return s; 48 } // end of switch 49 } // end of while 50 return s; 51 } 52 53 // getNextChar: fetches next char. Also opens input file 54 private char getNextChar() throws IOException { 55 if (!fileOpen) { 56 fileOpen = true; 57 if (fileName == "") 58 in = new InputStreamReader(System.in); 59 else 60 in = new FileReader(fileName); 61 } 62 return (char)in.read(); 63 } 64 } four06% cat -n ScanTest.java 1 // ScanTest: Test a scanner for C-style comments 2 import java.io.*; 3 public class ScanTest { 4 public static void main(String[] args)throws IOException{ 5 Scan scanner; // the scanner 6 String s; 7 // pass an input file name if present on command line 8 if (args.length > 0) 9 scanner = new Scan(args[0]); 10 else 11 scanner = new Scan(); 12 while (true) { 13 // fetch and print the next comment 14 // end-of-file is detected inside Scan.java 15 s = scanner.getComment(); 16 System.out.println("Next comment: "+"\""+s + "\""); 17 } 18 } 19 } four06% cat -n comment.source 1 x = 47 / 13 * 12; /**/ 2 /***/ /****/ /*/ ?? * / */ 3 /* abc; */ /* over 4 two lines */ JUNK! 3.14159; /*quit*/ four06% java ScanTest (the file comment.source paster here) x = 47 / 13 * 12; /**/ /***/ /****/ /*/ ?? * / */ /* abc; */ /* over two lines */ JUNK! 3.14159; /*quit*/ Next comment: "/**/" Next comment: "/***/" Next comment: "/****/" Next comment: "/*/ ?? * / */" Next comment: "/* abc; */" Next comment: "/* over two lines */" Next comment: "/*quit*/" (control-D typed here) Th-th-th-that's all folks four06% java ScanTest < comment.source (using redirected input) Next comment: "/**/" Next comment: "/***/" Next comment: "/****/" Next comment: "/*/ ?? * / */" Next comment: "/* abc; */" Next comment: "/* over two lines */" Next comment: "/*quit*/" Th-th-th-that's all folks four06% java ScanTest comment.source (using named source file) Next comment: "/**/" Next comment: "/***/" Next comment: "/****/" Next comment: "/*/ ?? * / */" Next comment: "/* abc; */" Next comment: "/* over two lines */" Next comment: "/*quit*/" Th-th-th-that's all folks