Consider the following grammar:
E ---> dig | '(' P E E ')' P ---> '+' | '-' | '*' | '/' dig ---> '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
You are to add code to the listing above (not shown here) so that the program will return the correct double value as it parses input. Here is an interactive session showing legal input and what should be returned by your program.
% java Evaluate 6 6.0 % java Evaluate (+ (* 3 3) (* 4 4)) 25.0 % java Evaluate (* (+ (* 5 4) (/ 4 2) ) 3) 66.0 % java Evaluate (+ 3 (/ 1 (+ 7 (/ 1 (+ (* 4 4)))))) The above input was included in error. It is legal in Lisp, but not according to the above grammar or the above parser. It should have been: (+ 3 (/ 1 (+ 7 (/ 1 (* 4 4))))) 3.1415929203539825Answer the following questions:
(* (+ (* 5 4) (/ 4 2) ) 3)
E(66) | +---+-------------------------------+------------------------------+----+ | | | | | | | E(22) | | | | | | | | | +---+-----------+-----------+-----------+-------------+ | | | | | | | | | | | | | | | E(20) E(2) | | | | | | | | | | | | | | | | +---+---+----+----+ +----+----+----+----+ | | | | | | | | | | | | | | | | | | | | | | | | | | E(5) E(4) | | | E(4) E(2) | | E(3) | | | | | | | | | | | | | | | | | | | P | P | P dig dig | | P dig dig | | dig | | | | | | | | | | | | | | | | | | ( * ( + ( * 5 4 ) ( / 4 2 ) ) 3 )
// Evaluate: evaluates simple S-expressions as doubles // using the grammar below // grammar: S ---> dig | '(' P S S ')' // P ---> '+' | '-' | '*' | '/' // dig ---> '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' // public class Evaluate { private char tok; // = ' '; // eval: evaluate an S-expression public void eval() { double result = S(); System.out.println("Result: " + result); } // S: recognize a lisp s-expression private double S() { char opcode; double operand1, operand2; tok = gettoken(); if (Character.isDigit(tok)) return (double)(tok - '0'); else if (tok == '(') { tok = gettoken(); if (tok == '+' || tok == '-' || tok == '*' || tok == '/' || tok == '^') { opcode = tok; operand1 = S(); operand2 = S(); tok = gettoken(); if (tok == ')') return eval2(opcode, operand1, operand2); else { err(0); return 0; } } else { err(1); return 0; } } else { err(2); return 0; } } private double eval2(char op, double arg1, double arg2) { switch (op) { case '+': return arg1 + arg2; case '-': return arg1 - arg2; case '*': return arg1 * arg2; case '/': return arg1 / arg2; case '^': return Math.pow(arg1, arg2); default: { err(3); return 0; } } } // err: error message private void err(int i) { System.out.println("Error number: " + i); System.exit(1); } // gettoken: fetch next token (here just a char) private char gettoken() { char next = ' '; do { try { next = (char)System.in.read(); } catch (Exception e){ err(2); } } while ( next == ' ' || next == '\n'); return next; } public static void main(String[] args) { Evaluate e = new Evaluate(); e.eval(); } }
This question concerns the series of recitations used to translate programs from the "Tiny" language to MIPS assembler code.
The portion of the grammar for Tiny that handles assignment statements is:
A ---> lower-case '=' E ';'
Here is my version of the portion of the parser needed to handle this assignment statement. I removed three occurrences of else error(9) in order to simplify the code. I also marked 4 "POSITIONS" in the code, locations to refer to below. This is just the bare parser, and you should realize that a number of additional features and statements must be added to this function to get the final compiler.
private void A() { // here have already scanned for the first token of A // POSITION A if (Character.isLowerCase(next)) { // POSITION B scan(); } if (next == '=') scan(); // POSITION C E(); if (next == ';') scan(); // POSITION D }
Suppose your program is translating the following statement:
a = b + 3*c;
Stated another way, the function A has no way to know what is on the right side of the assignment operator, only that it is an expression and that the address where the value of the expression will be found is returned into A.
> (car '((a b) c d (e))) (A B) > (cdr '(a (b c d))) ((B C D)) > (cdr (car '((a b) c))) (B) > (cons '(a b) '(c)) ((A B) C) > (list '(a b) '(c)) ((A B) (C)) > (append '(a b) '(c)) (A B C) > (cond ((= 4 (* 2 3)) 47) (t 54)) 54 > () NIL
(defun power (b e) (cond ((= e 0) 1) (t (* b (power b (- e 1))))))
((a b) c (d))
Here is an answer:
+---+---+ +---+---+ +---+---+ ((a b) c (d)):--->| o | o-|--->| o | o-|-------------->| o | o-|---> nil +---+---+ +---+---+ +---+---+ | | | | v | | c v | +---+---+ v | o | o-|---> nil +---+---+ +---+---+ +---+---+ | o | o-|--->| o | o-|---> nil | +---+---+ +---+---+ v | | d v v a b
/Times-Roman findfont 100 scalefont setfont 0 0 moveto (UTSA) show showpage
Rewrite this code so that it prints the UTSA 8 inches up from the bottom, and exactly right-justified 50 points from the right edge. Thus the right side of the "A" should be 50 points from the right edge of the paper. [Hints: The page is 8.5 inches wide. There are 72 points to an inch. The Postscript code (UTSA) stringwidth pop will give the horizontal extent of the string.] Here is an answer:
%!PS-Adobe-2.0 %% problem 11 on final exam /inch {72 mul} def /Times-Roman findfont 100 scalefont setfont 8.5 inch 50 sub (UTSA) stringwidth pop sub 8 inch moveto (UTSA) show showpage
Part a. | Part b. | Part c. | Part d. |
/box { newpath 0 0 moveto 0 72 rlineto 72 0 rlineto 0 -72 rlineto closepath } def 45 rotate 200 200 translate box stroke showpage | /box { newpath 0 0 moveto 0 72 rlineto 72 0 rlineto 0 -72 rlineto closepath } def 200 200 translate 45 rotate box stroke showpage | /box { newpath 0 0 moveto 0 72 rlineto 72 0 rlineto 0 -72 rlineto closepath } def 200 200 translate 45 rotate 0.25 0.25 scale box stroke showpage | /box { newpath 0 0 moveto 0 72 rlineto 72 0 rlineto 0 -72 rlineto closepath } def 0.25 0.25 scale 200 200 translate 45 rotate box stroke showpage |
prob12a.pdf | prob12b.pdf | prob12c.pdf | prob12d.pdf |
---|
/line { newpath 0 0 moveto 1000 1000 lineto stroke } def /lines { 1 1 300{ 5 0 translate line } for } def % PART A: 1 setlinewidth gsave -900 0 translate lines grestore % PART B: /Helvetica-Bold findfont 100 scalefont setfont 1 setgray % white 50 500 moveto (SUBVERT) show 0 setgray % black % PART C: newpath 50 500 moveto (SUBVERT) false charpath clip 1.25 setlinewidth -901 0 translate lines showpage |
lines.pdf lines2.pdf lines3.pdf lines4.pdf |
---|
def year @year end
Emma by Austen, Jane Released: Aug 1994 Mansfield Park by Austen, Jane Released: Jun 1994 Doctor Marigold by Dickens, Charles Released: Aug 1998 George Silverman's Explanation by Dickens, Charles Released: Feb 1997 Sir Nigel by Doyle, Arthur Conan Released: Aug 2005 Tales of Terror and Mystery by Doyle, Arthur Conan Released: Aug 2005
We want to rewrite these in the following form. This assumes that the book title is always ended by "by", that the author's last name is always followed by "," and that the first name(s) is(are) always followed by "Released:".
Jane Austen, "Emma" (Aug 1994) Jane Austen, "Mansfield Park" (Jun 1994) Charles Dickens, "Doctor Marigold" (Aug 1998) Charles Dickens, "George Silverman's Explanation" (Feb 1997) Arthur Conan Doyle, "Sir Nigel" (Aug 2005) Arthur Conan Doyle, "Tales of Terror and Mystery" (Aug 2005)Write a Ruby program using Ruby code and regular expressions to do this translation. If you have forgotten various items, just fake it as best you can, but you are not supposed to be using Perl for this problem. If you didn't do Recitation 13 the way I suggested but used some method of your own, then you should mention this. Answer:
#!/usr/local/bin/ruby while line = gets # fetch next line of input file re = /^(.+)by\s+([-a-zA-Z]+),\s+(.+)Released:\s+(.*)$/ # main RE m = re.match(line) # match line with RE newline = m[3].strip + " " + m[2].strip + ", \"" + m[1].strip + "\" (" + m[4].strip + ")\n" print newline end