% cc -o source -lm source.c
In Java you can just use Math.pow().
Writing a recognizer for indiviual tokens: The most common way to write such a recognizer is to first write a finite state machine (FSM) that describes the token. Then the FSM is converted to a program, either by hand or using a automated software tool to produce the program (such as lex in unix).
C-style comments: C-style comments, material between and initial /* and a terminal */ form a comment. A recognizer for these constructs is illustrated here: C-style comments.
Floating point constants: This is the token that will be worked with in this recitation. For our purposes here, a floating point constant consists of an optional initial sign (+ or -), followed by any number (including 0) of digits, followed by an optional decimal point(.), followed by any number (including 0) of digits, followed by an optional exponent part, which is an e or E, followed by an optional sign (+ or -), followed by 1 or more digits for the exponent. There must be at least one digit before or after the decimal point (or both), and if there is no decimal point there must be at least one digit. There must be either a decimal point or the exponent part (or both).
Actual floating point constants in Java can also have an optional trailing f or F for float constants and the optional trailing d or D for double constants. (With no optional trailing letter the constant is double by default.) You should ignore these possibilities. You should also ignore the limitation on the size of the exponent, so the last illegal constant in the program below would be accepted by your FSM. Finally, the initial optional sign (+ or -) would usually be treated as a separate operator, but you should handle it as part of the constant here.
Here is a short program that tries out various floating point constants in Java. The program only shows a few of the possibilities, since there can also be an initial + sign if there is no -. All the constants shown are legal in Java except for the two that are commented out. Your code should accept all but the last one.
// Doub: try out double constants
public class Doub {
public static void main(String[] args) {
System.out.println("-1.2e-2 = " +(-1.2e-2)); // normal
System.out.println("-.2e-2 = " +(-.2e-2)); // no digit before .
System.out.println("-1.e-2 = " +(-1.e-2)); //no digit after .
System.out.println("-1e-2 = " +(-1e-2)); // no .
System.out.println("-1.2E-2 = " +(-1.2E-2)); // cap E
System.out.println("-1.2 = " +(-1.2)); // no e or E
System.out.println("-.2 = " +(-.2)); // no e, no digit before .
System.out.println("-1. = " +(-1.)); // no e, no digit after .
// same as above without signs
System.out.println("1.2e2 = " +(1.2e2)); // normal
System.out.println(".2e2 = " +(.2e2)); // no digit before .
System.out.println("1.e2 = " +(1.e2)); //no digit after .
System.out.println("1e2 = " +(1e2)); // no .
System.out.println("1.2E2 = " +(1.2E2)); // cap E
System.out.println("1.2 = " +(1.2)); // no e or E
System.out.println(".2 = " +(.2)); // no e, no digit before .
System.out.println("1. = " +(1.)); // no e, no digit after .
System.out.println( // too many digits
"-33333333333333333333.2222222222222222222222222e-2 = "
+(-33333333333333333333.2222222222222222222222222e-2));
// System.out.println("-1.0e-444 = " +(-1.0e-444)); // ILLEGAL
// System.out.println("-.e-2 = " +(-.e-2)); // only ., ILLEGAL
}
}
Output:% java Doub -1.2e-2 = -0.012 -.2e-2 = -0.0020 -1.e-2 = -0.01 -1e-2 = -0.01 -1.2E-2 = -0.012 -1.2 = -1.2 -.2 = -0.2 -1. = -1.0 1.2e2 = 120.0 .2e2 = 20.0 1.e2 = 100.0 1e2 = 100.0 1.2E2 = 120.0 1.2 = 1.2 .2 = 0.2 1. = 1.0 -33333333333333333333.2222222222222222222222222e-2 = -3.3333333333333331E17The two commented out constants produced error messages:
Doub.java:26: floating point number too small
System.out.println("-1.0e-444 = " +(-1.0e-444));
^
Doub.java:13: illegal start of expression
System.out.println("-.e-2 = " +(-.e-2));
^
In either case you next should write a program that simulates your FSM, as illustrated with comments above, and in your text in Section 4.2. (This does not need to be as formal a translation from the FSM as is illustrated.)
As a second part of the assignment, you must add "semantic" code so that your program will produce the value (as a double) of the string of characters describing a floating point constant. This value must be calculated "from scratch" without using any fancy C, C++, or Java library functions.
What to turn in: You should turn in to the instructor a diagram of your FSM, your simulation code, and a sample run using the sample input below, showing that the code successfully recognizes the examples given in the sample input. For legal floating point numbers, your code should also print the value of the number as a double. This value should be calculated from scratch without using a library function (see below).
All the examples in the code above are lexically legal floating point constants except for the next-to-the-last one: "-.e-2". Other examples of illegal floating point constants include an integer constant "47", numbers with more than one decimal point, or with more than one "e" part, with a decimal point inside the "e" part, or numbers with an odd embedded character.
Hints on calculating the value of a scanned double: In C it would be possible to use a library function to convert a string of characters representing a floating point number to an actual double. You could use sscanf for example. In ordinary code it is usually a good idea to use library functions rather than rewrite them from scratch. In this recitation, however, we are studying some of the low-level language mechanisms, and for this assignment you are not to use the library function. Instead, you should realize that given the code:
char ch = '4'; int i = ch -'0';the variable i takes on the integer value 4. At each stage of reading the initial digits of the constant, you can multipy by 10 and add in the next integer value. Then you have to take the "." and the exponent part appropriately into account.
Java also has library functions (such as Double.parseDouble(String)) that should not be used. The same trick above also works in Java.
Sample input (all are legal):
3.1415926 -0.0132 +22.334455e4 -.12345e-5 -567.e+4 +123e+12 3489. .7821Key ideas: The tokens that are recognized by the lexical level of a programming language can be described by FSMs. These FSMs can be used to write the code for an actual recognizer (a program that simply says whether or not the token in legal).