----------------------------------------------------------------------

CSE 401 Autumn 2001 (Henry)

[Home] [Admin] [Details] [Help] [Other]

Assignment 5 (Lex, Yacc and NaNs)

($Revision: 1.8 $)

----------------------------------------------------------------------

Due Monday, November 5, 2001

  • In this assignment you will be extending a simple calculator that I have written using lex and yacc. All of this assignment is to be done individually (no groups!).

    Read about the use and representation of IEEE-format floating point numbers. There is a discussion of them in the computer architecture textbook by Hennessey and Patterson. See also this brief overfiew on IEEE format numbers.

    Remember a fundamental rule of compiler construction: the compiler should not "mess" up floating point computations unless the compiler writer really, really, really knows what he/she is doing. None of us do.

    This assignment should be straightforward.

    You should not have to spend more than 2 hours on the assignment.

    You must do this assignment on the instructional unix servers. It is unlikely that you'll get the right answers for the special floating point numbers on other boxes, such as on wintel boxes.

  • Read ASU 3.5 (lex) and 4.9 (yacc).

  • On the instructional unix machies, copy the files calc.l, calc.y and Makefile from the directory
    /projects/cse/courses/cse401/01au/calc
    
    into your own separate directory named "calc". This way you can keep this work separate from the other cse401 related work you are doing.

  • Extend the lexical specification to support floating point numbers, using the lexical structure we discussed in class. Use the C library routine double atof(const char *) to convert from base 10 ascii strings to floating point numbers. You will also be required to scan NaN and Inf; see below.

  • Change the synthesized attribute type (in the yacc %union declaration) to use the type double, instead of the type int. Extend the calculator as appropriate to print out double precision numbers, instead of ints.

  • Extend the calculator as appropriate to do infix binary +, -, * and /; to do unary prefix + and -; to do the 6 infix comparision operators; to do distfix () operator (eg, normal parenthesis). All these operators should have the conventional meaning, precedence and associativity. The comparison operators should be implemented so they return 1.0 on success and 0.0 on failure.

  • Extend the calculator as appropriate to recognize special prefix unary functions sin, cos, tan, asin, acos, atan; these prefix unary functions expect a single parenthesized argument, and should be implemented by calling the corresponding C library functions. (These functions manipulate radians, not degrees!) Read the man page for sin (eg, the Unix command man 3 sin) to learn about these trigonometric functions.

  • Extend the lexical specification to support two special floating point numbers. These floating point numbers have special lexical rules, and special arithmetic that is implemented directly by the underlying hardware.

    One special floating point number lexically appears as NaN or NaNS, where the letters can be in either upper or lower case. NaN This means "Not a Number". You can call the function double makenan() to return a floating point number encoding a NaN. (On Linux machines, it seems that you can call the the routine atof to scan and convert this string, but these semantics are unlikely to work on non-Linux machines.)

    One special floating point number lexically appears as "Inf", in any case. This means (positive) infinity. You can call the function double makeinf() to return a floating point number encoding an infinity. (On Linux machines, it seems that you can call the the routine atof to scan and convert this string, but these semantics are unlikely to work on non-Linux machines.)

    Aside from scanning these numbers and calling the special functions to make instances of these special numbers, you do not have to do ANYTHING else special to parse or attribute NaNs or Infs. Everything else should be done for you by the runtime system or by the underlying hardware.

  • Experiment with expresssions like 0/0, Inf/Inf, NaN*0, 1<Nan, 1>Nan, and other expressions involving boundary conditions for real numbers.

    This lex/yacc assignment was intended to "kill 2 birds with one stone": do a simple lex+yacc assignment (which entails copying pretty much directly from the text book, with some extensions), and to also "learn by experimentation" about some special floating point numbers.

  • Use the turnin program to turnin the source code calc.l and calc.y.

  • Your grammar should have no shift/reduce or reduce/reduce conflicts, as reported by yacc.

  • Examine the file named y.output which yacc produces to describe the state machine it produced. The output is a little terse. The output uses "_" (underscore) to mark the current location in an item instead of using the more normal convention "." (period) we have been using in class.