Vous êtes sur la page 1sur 9

Note:

Provide examples when discussing concepts. Make sure you provide complete explanation. Do not just copy and paste; write in your own words.

1. Identify the differences between BNF and EBNF rules. Provide the complete set of rules for two different constructs using both methods. BNF or Backus-Naur Form is used to describe grammar rules in programming languages. Example: <expr> <expr> + <term> | <expr> + <term> | <term> <term> <term> * <factor> | <term> / <factor | <factor> <factor> <exp> ** <factor> | <exp> <exp> ( <expr> ) | id However BNF does not describe repetition. This is where EBNF comes in to play. EBNF is mainly used to describe repetition. For example the rule in BNF form can be written in EBNF form as <expr> <term> {(+ | -) <term>} <term> <factor> {(* | /) <factor>} <factor> <exp> {** <exp>} <exp> ( <expr> ) | id The repeated part in the BNF form is put into the curly braces for easy repetition. This is not only easier to read, but also quicker to write. 2. Indicate whether the following sentences are/ are not in the language generated by the grammar provided in question 12? Show all the steps of the derivation. Grammar: <S> a <S> c <B> | <A>| b <A> c <A> | c

<B> d | <A> a.) accccdccb Not in the language

d cannot by in the middle of a sentence because it is a terminal and will end all sentences. b.) aaacccd Not in the language

The parse tree shows that this sentence is impossible with the given grammar. c.) abcdabcd Not in the language

Once again, d cannot be in the middle of a sentence. The parse tree shows that abcd can be produced once but not twice. 3. Compute the weakest precondition for each of the following segments of code and the post conditions. Explain your answers. a.) b = (c + 10) / 3 ; { b > 16) (c + 10) / 3 > 16 (c + 10) > 16 c > 38 To find the weakest precondition we insert the segments of code into the post condition. We then solve for the unknown variable and find the weakest precondition. Therefore, the weakest precondition is (c > 38). b.) if ( x < y) x = x +1 else x = 4 * x; { x > 5 } In this case we want to insert the if case and the else case conditions into the post condition to get the preconditions. For the if case we get: X+1>5 X>4 And for the else case we get: 4*X>5 X > 5/4 or X > 1.25 Since the precondition in the else case is smaller than the precondition in the if case the Weakest Precondition for the entire segment of code is x > 5/4. 4.) Write the lexical analyzer program segments to recognize the following list of reserved words and return their token codes:

While (while_code,201), do (do_code, 202), if(if_code, 203),else(else_code,204), switch(switch_code, 205) and case(case_code,206) /*Written in C#*/ /* A lexical analyzer for returning a list of reserved words */

/* Token Codes */ #define while_code 201 #define do_code 202 #define if_code 203 #define else_code 204 #define switch_code 205 #define case_code 206 main() { if((in_fp = fopen(front.in, r)) == NULL) printf(ERROR cannot open front.in \n); else { getChar(); do{ lex(); } while (nextToken != EOF); } } int lookup(char ch) { switch (ch) { case while: addChar(); nextToken = break; case do addChar(); nextToken = break; case if: addChar(); nextToken = break; case else: addChar(); nextToken =

while_code;

do_code;

if_code;

else_code;

break; case switch: addChar(); nextToken = switch_code; break; case case: addChar(); nextToken = case_code; break; } return next Token; } //addChar and get Char is the same //getNonBlank is the same //lex is also the same 5.) Using the LR parsing table of Figure 4.5 provide a trace of a parse of the string id + id * (id + id) * id
Stack 0 0id5 GOTO[0, F]) 0F3 GOTO[0, T]) 0T2 GOTO[0, E]) 0E1 0E1+6 0E1+6id5 GOTO[6, F]) 0E1+6F3 GOTO[6, T]) 0E1+6T9 0E1+6T9*7 0E1+6T9*7(4 0E1+6T9*7(4id5 0E1+6T9*7(4F3 0E1+6T9*7(4T2 0E1+6T9*7(4E8 0E1+6T9*7(4E8+6 0E1+6T9*7(4E8+6id5 0E1+6T9*7(4E8+6F3 GOTO[6, T]) 0E1+6T9*7(4E8+6T9 GOTO[6, E]) 0E1+6T9*7(4E8+6E0 0E1+6T9*7(4E8+6E0)11 Input Action id + id * (id + id) * id $ Shift 5 + id * (id + id) * id $ Reduce 6 (use + id * (id + id) * id $ + id * (id + id) * id $ Reduce 4 (use Reduce 2 (use

+ id * (id + id) * id $ Shift 6 id * (id + id) * id $ Shift 5 * (id + id) * id $ Reduce 6 (use * (id + id) * id $ * (id + id) * id $ (id + id) * id $ id + id) * id $ + id) * id $ + id) * id $ + id) * id $ + id) * id $ id) * id $ ) * id $ ) * id $ ) * id $ Reduce 4 (use Shift 7 Shift 4

Shift 5 Reduce 6 (use GOTO[4,F]) Reduce 4 (use GOTO[4,T]) Reduce 2 (use GOTO[4, E]) Shift 6 Shift 5 Reduce 6 (use GOTO[6, F]) Reduce 4 (use Reduce 2 (use Shift 11 Reduce 6 (use GOTO[11, F])

) * id $ * id $

0E1+6T9*7(4E8+6E0)11F0 * id $ GOTO[11, T]) 0E1+6T9*7(4E8+6E0)11T0 * id $ 0E1+6T9*7(4E8+6E0)11T0*7 id $ 0E1+6T9*7(4E8+6E0)11T0*7id5 $ 0E1+6T9*7(4E8+6E0)11T0*7F10 $ GOTO[6, T]) 0E1+6T9 $ 0E1 $

Reduce 4 (use Shift 7 Shift 5 Reduce 6 (use GOTO[7, F]) Reduce 3 (use Reduce 1 (use GOTO[0, E]) Accept

6.) Problem 9 of chapter 5: procedure Main is X, Y, Z : Integer; procedure Sub1 is A, Y, Z : Integer; begin -- of Sub1 end; -- of Sub1 procedure Sub2 is A, X, W : Integer; procedure Sub3 is A, B, Z : Integer; begin -- of Sub3 end; -- of Sub3 begin -- of Sub2 end; -- of Sub2 begin -- of Main end; -- of Main List all the variables, along with the program units where they are

declared, that are visible in the bodies of Sub1, Sub2, and Sub3, assuming static scoping is used. Variables that are visible in Sub1: A, Y, Z ------obtained from Sub1 X ------obtained from Main Variables that are visible in Sub2: A, X, W -------obtained from Sub2 Y, Z -------obtained from Main Variables that are visible in Sub3: A, B, Z ------obtained from Sub3 X, W ------obtained from Sub2 Y ------obtained from Main

7.) Problem 12 of chapter 5: Consider the following program: procedure Main is X, Y, Z : Integer; procedure Sub1 is A, Y, Z : Integer; begin -- of Sub1 end; -- of Sub1 procedure Sub2 is A, B, Z : Integer; begin -- of Sub2 end; -- of Sub2 procedure sub3 is A, X, W : Integer; begin -- of Sub3 end; -- of Sub3 begin -- of Main end; -- of Main Given the following calling sequences and assuming that dynamic scoping is used, what variables are visible during execution of the last subprogram activated? Include with each visible variable the name of the unit where it is declared.

a. Main calls Sub1; Sub1 calls Sub2; Sub2 calls Sub3. Variables that are visible at the last function call: Y -------- Declared in Sub1 B, Z -------- Declared in Sub2 A, X, W -------- Declared in Sub3 b. Main calls Sub1; Sub1 calls Sub 3. Variables that are visible at the last function call: Y, Z ------- Declared in Sub1 A, X, W ------- Declared in Sub3 c. Main calls Sub2; Sub2 calls Sub3; Sub3 calls Sub1. Variables that are visible at the last function call: B ------- Declared in Sub2 X, W ------- Declared in Sub3 A, Y, Z ------- Declared in Sub1 d. Main calls Sub3; Sub3 calls Sub1. Variables that are visible at the last function call: X, W ------- Declared in Sub3 A, Y, Z ------- Declared in Sub1 e. Main calls Sub1; Sub1 calls Sub3; Sub3 calls Sub2. Variables that are visible at the last function call: Y ------- Declared in Sub1 X, W ------- Declared in Sub3 A, B, Z ------- Declared in Sub2 f. Main calls Sub3; Sub3 calls Sub2; Sub2 calls Sub1. Variables that are visible at the last function call: X, W ------- Declared in Sub3 B ------- Declared in Sub2 A, Y, Z ------- Declared in Sub1

8.) Write three functions in C++: one that declares a large array statically, one that declares the same large array on the stack, and one that creates the same large array from the heap. Call each of these subprograms a large number of times (at least 1000 times?) and output the time required by each. Explain the results. main(){

StaticArray(1000); HeapArray(1000); } void StaticArray() { static int x[1]; } void HeapArray() { int *a; a = new int[1]; }

Vous aimerez peut-être aussi