CS 3723 Programming Languages
|

Recognizing C-style comments:
| C Program With gotos | C Program Without gotos |
|---|---|
/* scan.h: scanner header file */ void scan(char *s); | /* scan.h: scanner header file */ void scan(char *s); |
| Run and Output | Run and Output |
% cc -o comment comment.c scan.c % cat comment.source x = 47 / 13 * 12; /**/ /***/ /****/ /*/ ?? * / */ /* abc; */ /* over two lines */ JUNK! 3.14159; /*quit*/ % comment < comment.source Next comment:"/**/" Next comment:"/***/" Next comment:"/****/" Next comment:"/*/ ?? * / */" Next comment:"/* abc; */" Next comment:"/* over two lines */" Next comment:"/*quit*/" | % cc -o comment2 comment.c scan2.c % cat comment.source x = 47 / 13 * 12; /**/ /***/ /****/ /*/ ?? * / */ /* abc; */ /* over two lines */ JUNK! 3.14159; /*quit*/ % comment2 < comment.source Next comment:"/**/" Next comment:"/***/" Next comment:"/****/" Next comment:"/*/ ?? * / */" Next comment:"/* abc; */" Next comment:"/* over two lines */" Next comment:"/*quit*/" |
| Java Program to Recognize Comments |
|---|
/* Scan.java: scanner implementation.
* Recognizes C-type comments
* Based on a finite-state automaton.
*/
import java.io.*;
public class Scan {
Reader in; // internal file name for input stream
boolean fileOpen = false; // is the file open yet?
String fileName; // name of input file, if present
// Scan(): constructor providing no input file name
public Scan() {
fileName = "";
}
// Scan(String ): constructor providing input file name
public Scan(String f) {
fileName = f;
}
// getComment: recognize and return the next comment
public String getComment() {
int state = 0; // state for the finite automaton
char ch = 0; // single-character buffer
String s = "/*";
while (state != 4) {
if (ch == 65535) { //end-of-file
System.out.println("Th-th-th-th-that's all folks");
System.exit(0);
}
switch (state) {
case 0: ch = getNextChar();
if (ch == '/') state = 1;
else state = 0; break;
case 1: ch = getNextChar();
if (ch == '*') state = 2;
else state = 0; break;
case 2: ch = getNextChar();
s += ch;
if (ch == '*') state = 3;
else state = 2; break;
case 3: ch = getNextChar();
s += ch;
if (ch == '*') state = 3;
else if (ch == '/') state = 4;
else state = 2; break;
case 4: return s;
} // end of switch
} // end of while
return s;
}
// getNextChar: fetches next char. Also opens input file
private char getNextChar() {
if (!fileOpen) {
try {
fileOpen = true;
if (fileName == "")
in = new InputStreamReader(System.in);
else
in = new FileReader(fileName);
} catch (IOException e) {
System.out.println("Exception opening " + fileName);
System.exit(1);
}
}
char ch = ' '; // keep compiler happy
try {
ch = (char)in.read();
} catch (IOException e) {
System.out.println("Exception reading character");
System.exit(1);
}
return ch;
}
}
|
| Java Run and Output |
% javac Scan.java
% javac ScanTest.java
% cat -n comment.source
1 x = 47 / 13 * 12; /**/
2 /***/ /****/ /*/ ?? * / */
3 /* abc; */ /* over
4 two lines */ JUNK! 3.14159; /*quit*/
% java ScanTest (the file comment.source pasted 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
% 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
% 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
|