331

Lakukan tugas rumah & ujian kamu dengan baik sekarang menggunakan Quizwiz!

Implement a lexer (lexical analyzer) that is able to recognize floating point numbers with an optional sign (+ or -), and with an optional whole part, i.e. the number can start with a dot symbol.

( ( + | - ) ?) ( [0-9]* ) ( . [0-9]+ )

Write a lambda expression with two input variables that is applied to two arguments and returns the multiplication of them.

((lambda (x y) (* x y)) 7 8)

Write the previous lambda expression in the form of two lambda expressions each taking one input.

((lambda (x) ((lambda (y) (* x y)) 8)) 7)

Write regular expressions to recognize the strings that start with either a or z followed by zero or more repetition of any combination of b and c followed by either a or z. If the string starts with a it should end with z, and if it starts with z it should end with a. The string cannot start and end with a. It cannot start and end with z. Examples of accepted strings: az, za, abcz, zcba, abbccbz, zcccba Examples of rejected strings: aa, zz, abca, zbcz

(a[bc]*z|z[bc]*a) or (a(b|c)*z|z(b|c)*a)

Write a function that takes an input as the radius of a disk and returns the area of the disk?

(define (area-of-disk r) (* 3.14 r r))

Write a function that takes two input values as radiuses of two disks and uses the previous function to calculate the area of the donut constructed from the two disks.

(define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner)))

Write a function that takes a parameter and returns true if the parameter is a root of the equation 4n2 + 6n + 2 = 462. Check whether 10, 12, or 14 are the solutions of the equation.

(define (equation n) (= (+ (* 4 (sqr n)) (* 6 n) 2) 462)) ; note the root of equation is 10

Write the factorial function in the form of tail recursive.

(define (factorial n) (define (helper n acc) (if (<= n 1) acc (helper (- n 1) (* acc n)))) (helper n 1) )

Write a function that takes an input and calculates the function n/3 + 2.

(define (func1 n) (+ 2 (/ n 3)))

Write a function that takes an input and calculates the function n^2 + 10.

(define (func2 n) (+ 10 (* n n)))

Write a function that takes an input and calculates the function ½ n^2 + 20.

(define (func3 n) (+ 20 (* 1/2 (* n n)))) ; note it reads 1/2 as an exact (fraction) number, output is exact form ;(define (func3 n) (+ 20 (* (/ 1 2) (* n n)))) ;(define (func3 n) (+ 20 (* 0.5 (* n n))))

Write a function that takes an input and calculates the function 2 - 1/n.

(define (func4 n) (- 2 (/ 1 n))) ; note (- 2 1/n) gives the error "unbound identifier in: 1/n

Suppose the bank pays 4% for deposits of up to $1000 (inclusive), 4.5% for deposits of up to $5000 (inclusive), and 5% for deposits of more than $5000. Write a program including two functions that takes an amount of deposit and returns the amount of interest. One function returns the interest rate, and one function calculates the amount of interest.

(define (interest-rate amount) (cond [(< amount 0) 0] [(and (<= 0 amount) (<= amount 1000)) 0.04] [(and (< 100 amount) (<= amount 5000)) 0.045] [(> amount 5000) 0.05])) (define (calc-interest n) (* n (interest-rate n)))

Enhance the previous program to format the output (amount of interest) with exactly two decimal points. And if the user enters a negative number the function outputs an error message instead of the interest amount.

(define (interest-rate amount) (cond [(< amount 0) 0] [(and (<= 0 amount) (<= amount 1000)) 0.04] [(and (< 100 amount) (<= amount 5000)) 0.045] [(> amount 5000) 0.05])) (define (calc-interest n) (if (>= n 0) (~r (* n (interest-rate n)) #:precision '(= 2)) (error "Wrong investment value")))

Write a recursive function that takes a list as input and returns the number of list members.

(define (len l) (if (empty? l) 0 (+ 1 (len (cdr l))) )) or (define (len l) (cond [(empty? l) 0] [else (+ 1 (len (cdr l)))] ))

Write the tail recursive version of the function in previous question using a let statement.

(define (len l) (let helper ((l l)(acc 0)) (cond [(empty? l) acc] [else (helper (cdr l) (+ acc 1))] ) ) )

Write a function that takes the number of audiences in a theater as an input parameter and returns the profit of a performance. Every performance costs $20 plus $0.50 per person. The price of a ticket is $5.00.

(define (total-profit customers) (- (* 5 customers) (+ 20 (* 0.50 customers))))

.Write a function to calculate the volume of a cylinder from its radius and height. Use the function previously written to calculate the area of the circle. Format the output to 4 precision.

(define (volume-of-cylinder radius height) (~r (* (area-of-disk radius) height) #:precision 4)) ; note this format returns answer up to 4 precision (define (volume-of-cylinder radius height) (~r (* (area-of-disk radius) height) #:precision '(= 4))) ; note this format gives exactly 4 precision including trailing zeros

Write a for loop that iterates through two lists and prints the multiplication of corresponding members in the lists.

(for ([i '(1 2 3)] [j '(4 5 6)]) (display (* i j)) (display " "))

Write a for/list loop that iterates through two lists and returns the multiplication of corresponding members in the lists.

(for/list ([i '(1 2 3)] [j '(4 5 6)]) (* i j))

Write the function that counts the list members in the form of tail recursive.

(require racket/trace) (define (len l) (define (helper l acc) (cond [(empty? l) acc] [else (helper (cdr l) (+ acc 1))] ) ) (trace helper) ;note, if not calling helper, it gives error "no expression after a sequence" (helper l 0) )

(λx.x) (λy.y)

(λ(λy.y). (λy.y)) (λy.y)

(λx.λy.x y) (λz.z) 2

(λ(λz.z).λy. (λz.z) y) 2 (λy. (λz.z) y) 2 (λ2. (λz.z) 2) (λz.z) 2 (λ2.2) 2

(λx.x) 2

(λ2.2) 2

Backtracking algorithms

-They do not require rewriting the ambiguous grammar rules -They try all possible grammar rules until parsing passes, or it fails -If there is a failure in parsing it backtracks and starts over with another rule

Predictive algorithms

-They require rewriting grammar rules to remove ambiguities. Since these algorithms preform left-most derivation, the problematic ambiguities are left recursion and common left factors (please refer to the provided example) -At every attempt there is only one way to go, therefore, there is no backtracking

Top-down parsing

-Use left-most derivation -Written for small grammars -Mostly are written manually

Bottom-up parsing

-Use right-most derivation -Written for large grammars -Mostly are generated by parser generators

Steps to write a bottom-up parser

1. Create a unique start symbol and start rule if required 2. Remove grammar ambiguities such as having two-sided recursion in a rule, or the operation precedence, or operator associativity, etc. 3. Create a DFA using the grammar (all terminals and non-terminals are transitions; states consist of grammar rules) 4. Create a parse table using the DFA 5. Implement the parser using the parse table and a stack data structure.

Steps to write a top-down parser

1. Rewrite rules to remove ambiguities if necessary 2. Determine the nullable values for LHS and RHS (please refer to provided example) 3. Determine the first sets for LHS and RHS (please refer to provided example) 4. Determine the follow sets for LHS (please refer to provided example) 5. Create the parse table using nullable values, first sets, and follow sets (please refer to provided example) 6. Implement the parser using the parse table

Write a context-free grammar in the form of BNF notation to satisfy the following requirements, Write a grammar for the "for" statement in Python. The grammar should only satisfy the following examples. In Python "for" loops can be written in many other forms. We do not intend to satisfy the forms which their examples are not presented here. In example 1, "i" is a variable and the list [45, 6, 7, 78] can have any number of members. Members of the list can only be numbers. In example 2, "key" and "value" are variables separated by commas, and the list [(11,12), (3,4), (5,7)] is a list of tuples. Variables only consist of alphabet characters. Example 1 => "for i in [45, 6, 7, 78]:" Example 2 => "for key,value in [(11,12), (3,4), (5,7)]:" Example 3 => "for index,key,value in [(1,11,12), (2,3,4), (3,5,7)]:"

<for_statement> ::= for <variable_list> in <list> <variable_list> ::= <variable> | <variable>, <variable_list> <list> ::= [<numbers_list>] | [<tuples_list>] <numbers_list> ::= <number> | <number>, <numbers_list> <tuples_list> ::= (<numbers_list> | <numbers_list>), <tuples_list> <number> ::= <digit> <number> | <digit> <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 <variable> ::= <char> | <char> <variable> <char> ::= a | b | c | d | ... z | A | B | C | D | ... Z

Write a context-free grammar in the form of BNF notation to satisfy the following requirements, The strings in the language are whole numbers with any number of digits, Examples, 9 146 973780043

<number> ::= <digit> | <digit> <number> <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Write a BNF grammar for a simple Lisp language. Lisp is a language based on manipulating lists of words and numbers. A list is a left parenthesis followed by some number of expressions (separated by spaces) followed by a right parenthesis. A list can be empty. In the following examples, "mySumFun" and "aName" are words. Assume names consist of one or more letters. Lists can come in nested form. Assume the following examples are all acceptable forms. You can use the word "epsilon" if you need to show an empty string. Reminder, your grammar should be able to generate any word and any number. ( mySumFun 1 23 5 ) ( ) ( ( mySumFun ( aName 65 98 ) ) )

<sentence> = ( <seq> ) <seq> = <item> | <item> <seq> | <sentence> <item> = <number> | <name> | epsilon <number> = <digit> | <digit> <number> <name> = <char> | <char> <name> <digit> = 0 | 1 | 2 ... | 9 <char> = a | b | ... | z | A | B | ... | Z

term = factor Y Y = * factor | epsilon factor = ~ factor | power power = atom X X = ** power| epsilon atom = NUM

FIRST for LHS of Rules FIRST(term) = FIRST(factor Y) = {~, NUM} FIRST(Y) = FIRST(* factor) ∪ FIRST(epsilon) = {*} FIRST(factor) = FIRST(~ factor) ∪ FIRST(power) = {~, NUM} FIRST(power) = FIRST(atom X) = {NUM} FIRST(X) = FIRST(** power) ∪ FIRST(epsilon) = {**} FIRST(atom) = FIRST (NUM) = {NUM}

term = factor Y Y = * factor | epsilon factor = ~ factor | power power = atom X X = ** power| epsilon atom = NUM

FIRST for RHS of Rules FIRST(factor Y) = FIRST(factor) = {~, NUM} Note: factor is not Nullable, then we do not need to include FIRST(Y) here FIRST(* factor) = FIRST(*) = {*} FIRST(epsilon) = {} FIRST(~ factor) = FIRST(~) = {~} FIRST(power) = FIRST(power) = {NUM} FIRST(atom X) = FIRST(atom) = {NUM} Note: atom is not Nullable, then we do not need to include FIRST(X) here FIRST(** power) = FIRST(**) = {**} FIRST(NUM) = {NUM}

A bottom-up parsing table defines a non-deterministic finite automaton.

False

A context-free grammar is a recognizer mechanism.

False

A grammar rule with both left recursion and right recursion always generates the same parse tree.

False

BNF notation uses curly brackets, i.e. "{" and "}" symbols, to indicate zero or more repetition of a symbol.

False

Backtracking parsing algorithms are very efficient in regard with execution time and memory consumption.

False

Bottom-up parsers perform left-most derivation.

False

Denotational semantics are specified based on first order logic concepts.

False

In Axiomatic semantics, the strongest precondition is the one that is logically implied by all other preconditions.

False

In a BNF grammar a terminal symbol can be replaced by other symbols.

False

In a DFA, there can be more than one transition out from a state for an input.

False

In a parse tree, the operator with the lowest precedence must appear at the lowest level of the tree.

False

In a recursive descent parsing algorithm we use a stack data structure to perform parsing.

False

In regular grammars the epsilon symbol is a special non-terminal symbol which can be replaced with another symbol.

False

LR parsing algorithms belong to the top-down parsers group.

False

The static semantics are mostly used to prove the correctness of programs.

False

The syntax analyzer verifies whether the tokens in a program are correct.

False

Determine the FIRST set for the non-terminal "prog" in the following BNF grammar. Please note, you should be able to distinguish between non-terminals and terminals depending on where they appear in the rules, i.e. LHS vs RHS. Count terminals with multiple characters as one, e.g. consider ++ as one terminal, or consider => as one terminal. Then if you need to include these terminals in the answer, they should appear like {++, =>}. Curly brackets are terminals in the language. Only write the final answer, i.e. FIRST set, you do not need to include FIRST statements. prog = stmt stmt = if expr then block stmt = while expr do block stmt = expr ; expr = term => id expr = isZero? term expr = not expr expr = ++ id expr = −− id term = id term = const block = stmt block = { stmts } stmts = stmt stmts stmts = ε

First(prog) = {if, while, id, const, isZero?, not, ++, −−}

term = factor Y Y = * factor | epsilon factor = ~ factor | power power = atom X X = ** power| epsilon atom = NUM

Nullable for LHS of Rules Nullable(term) = Nullable(factor Y) = false Nullable(Y) = Nullable(* factor) ∨ Nullable(epsilon) = true Nullable(factor) = Nullable(~ factor) ∨ Nullable(power) = false Nullable(power) = Nullable(atom X) = false Nullable(X) = Nullable(** power) ∨ Nullable(epsilon) = true Nullable(atom) = Nullable(NUM) = false

term = factor Y Y = * factor | epsilon factor = ~ factor | power power = atom X X = ** power| epsilon atom = NUM

Nullable for RHS of Rules Nullable(factor Y) = Nullable(factor) ∧ Nullable(Y) = false Nullable(* factor) = Nullable(*) ∧ Nullable(factor) = false Nullable(epsilon) = true Nullable(~ factor) = Nullable(~) ∧ Nullable(factor) = false Nullable(power) = Nullable(atom X) = false Nullable(atom X) = Nullable(atom) ∧ Nullable(X) = false Nullable(** power) = Nullable(**) ∧ Nullable(power) = false Nullable(NUM) = false

Determine the FOLLOW set for the non-terminal "X" and the non-terminal "Y" in the following grammar. Please note, vertical bar indicates logical OR. S → X Z | X Y Z X → X c | a | ε Y → X b | ε Z → Y d

S → X Z - first(Z) is in follow(X) S → X Y Z - first(Y) is in follow(X) Y is nullable then first(Z) is in follow(X) X → X c - first(c) is in follow(X) Y → X b - first(b) is in follow(X), X is nullable then first(Y) = {b} Z → Y d - Y is nullable then first(Z) = {d} Therefore, follow(X) = {c, b, d} - (6 points) follow(Y) = {d} - (2 points)

A BNF grammar is a generative mechanism.

True

A rule with both left recursion and right recursion makes the grammar ambiguous.

True

An advantage of LR parsers over LL parsers is that less rewriting of grammar rules is required.

True

EBNF notation allows for a more concise grammar compared to an equivalent grammar in BNF notation.

True

Finite Automata are recognizer tools.

True

In LR parsers, reduce operation means replacing a RHS with its equivalent LHS of a grammar rule.

True

Lexical analysis generates a stream of valid tokens.

True

Operational semantics present the meanings of language's constructs in the form of smaller actions.

True

Parsing algorithms build parse trees by finding a derivation for a program.

True

Removing left recursion from grammar is desirable when implementing top-down parsing algorithms.

True

The Python and C++ languages implement the same associativity for arithmetic operators.

True

The behaviors that can be checked at compile time are generally specified by static semantics.

True

The string 0b_0011_1111_0100_1110 belongs to the language specified by the following context-free grammar. bininteger = "0" ("b" | "B") ["_"] bindigit { ["_"] bindigit } bindigit = "0" | "1"

True

There is only one non-terminal on the RHS of a rule in regular grammars.

True

To implement left associativity for an operator we use left recursion.

True

Write regular expressions to recognize natural numbers between 0 and 256 inclusively. It means that 0 and 256 are also recognized by the regular expressions. Numbers with preceding zeros are not accepted. For example, 002 is not recognized but 2 is recognized. You can only use the basic regular expression syntax, not language specifics.

[0-9] | [1-9] [0-9] | 1 [0-9] [0-9] | 2 [0-4] [0-9] | 2 5 [0-6] Steps: [0-9] (can only be 0-9) [1-9][0-9] (can only be 10-99) 1 [0-9][0-9] (can only be 100-199) 2 [0-4][0-9] (can only be 200-249) 2 5 [0-6] (can only be 250-256)

a = 4 * (3 * b - a); b = 4 * a - 6; { b > 10 }

a = 4 * (3 * b - a); b = 4 * a - 6; { b > 10 } b > 10 = 4*a-6>10 = 4*a>16 = a>4 a>4 = 4*(3*b-a)>4 = 3*b-a>1 = -a>1-3*b = a>3*b-1 precondition = a>3*b-1

The expression (λs.s s) is called

a self-application expression. One may note that in the body of this function the s is applied to s.

The expression (λy.y) is called

an identity function

Generators

context-free grammar, regular grammar

square brackets ([ and ])

defines the class of characters

backslash (\)

escape character, it is used to escape the special characters

Rewrite the following grammar to remove common left factor(s). Please note, write one rule at a line. You can use the word "epsilon" if you need to show an empty string. expression = expression phrase expression = phrase phrase = the man phrase = the woman

expression = expression phrase expression = phrase phrase = the Y Y = man Y = woman

if (x > y) y = x - 5 else if (x < y) y = x + 8 else y = 3x { y > 15}

if (x > y) y = x - 5 else if (x < y) y = x + 8 else y = 3x { y > 15} y>15 = x-5>15 = x>20 -> y>15/x>20 y>15 = x+8>15 = x>7 = x<20 -> y>15/x>7 x>7/x>15; x>20 is true <- precondition

The following BNF grammar presents some language's rules in Python. Rewrite this partial BNF grammar in EBNF notation. <if_stmt> ::= if <namedexpr_test> : <suite> | if <namedexpr_test> : <suite> else : <suite> | if <namedexpr_test> : <suite> <else_if_stmt> | if <namedexpr_test> : <suite> <else_if_stmt> else : <suite> <else_if_stmt> ::= elif <namedexpr_test> : <suite> | elif <namedexpr_test> : <suite> <else_if_stmt>

if_stmt = 'if' namedexpr_test ':' suite {'elif' namedexpr_test ':' suite} ['else' ':' suite]

or sign (|)

logical or

period (.)

matches any one character no matter what

plus sign (+)

one or more repetition

Write the leftmost derivation for the following program using the provided grammar. Please note, you need to write every step in a new line. Please pay attention to the terminals, for example, in the rule "assignment = identifier = expression ;" the second assignment operator is a terminal in the language. void main() { int x ; x = 1 ; } program = void main ( ) { declarations statements } declarations = declaration | declaration declarations statements = statement | statement statements declaration = type identifier ; statement = assignment assignment = identifier = expression ; expression = literal type = int | double | char identifier = x | y | z literal = 1 | 2 | 3

program void main ( ) { declarations statements } void main ( ) { declaration statements } void main ( ) { type identifier ; statements } void main ( ) { int identifier ; statements } void main ( ) { int x ; statements } .......the answer continues to generate the string........ void main ( ) { int x ; statement } void main ( ) { int x ; assignment } void main ( ) { int x ; identifier = expression ; } void main ( ) { int x ; x = literal ; } void main ( ) { int x ; x = 1 ; }

Recognizers

regular expressions, Finite Automaton

dollar sign ($)

specifies the exact end

Derivation

the process of replacing non-terminal symbols with their equivalents using the rules. The derivation process starts at the start symbol and continues until there is no more non-terminal to replace

In an attributes grammar an intrinsic attribute gets its value from ......

the symbol table

caret (^)

two meanings, it negates, and it specifies the exact start

Axiomatic semantics

uses first order logic to prove whether the language constructs are working correctly

What is the weakest precondition for the following assignment statement? You need to show your calculations and the final answer. Please note, you need to write every step of your work in a new line. That means the last line presents the final answer. {P} x = y / 2 + 5 {x > 6}

y / 2 + 5 > 6 y / 2 > 1 y > 2

What is the strongest precondition for the following sequence of statements? You need to show your calculations and the final answer and explain why you chose that answer. Please note, you need to write every step of your work in a new line. { ? } if (a > b) x = y - 34; else x = y - 20; { x > 0 }

y-34>0 y>34 y-20>0 y>20 y>34 is the strongest precondition because although a value can be y>20, that does not necessarily mean that it is y>34. Thus, y>34 is the strongest precondition while y>20 is the weakest precondition.

x = 3*y+1; y=x-4; {y<0}

y<0 x-4<0 x<4 3*y+1<4 3*y<4-1 3*y<3 y<1 y<1 would be the precondition

if (x>0) then y=y+2 else y=y+3 {y>0}

y>0 y+2>0 y>-2 y>0 y+3>0 y>-3 y > -2 => y > -3 strongest precondition is y > -2

asterisk (*)

zero or more repetition

question mark (?)

zero or one occurrence, it defines option

Determine the FIRST set for the non-terminal "S" in the following grammar. Please note, vertical bar indicates logical OR. S → X Z | X Y Z X → X c | a | ε Y → t Z → b | w

{a,b,c,t,w}

actions associated with transitions

• A terminal transition means a shift action, i.e. we change the state and we remove the corresponding terminal from the input string. • A non-terminal transition means a go-to operation, i.e. we only change the state and move to the next state. • If the parsing marker is at the end of a rule we perform the reduce action, i.e. we replace the RHS with its equivalent LHS. • If the parsing marker is at the end of start rule it indicates the end of successful parsing (accepting the input string).

BNF notation has the following components:

• Non-terminal symbols (we write them in angular brackets, they can be replaced) • Terminal symbols (they cannot be replaced) • Operators (::= for assignment, | for logical OR) • Rules (a rule is a combination of non-terminals and terminals) • LHS (the symbol on the left side of the assignment operator) • RHS (the combination of non-terminals and terminals on the right side of assignment) • Start symbol (the starting non-terminal)

Write the left-most derivation for the following ALGOL statement using the provided Partial grammar. if k < 1 then A/B else B/A ⟨arithmetic expression⟩ ::= ⟨simple arithmetic expression⟩ | ⟨if clause⟩⟨simple arithmetic expression⟩ else ⟨arithmetic expression⟩ ⟨Boolean expression⟩ ::= ⟨simple Boolean⟩ | ⟨if clause⟩⟨simple Boolean⟩ else ⟨Boolean expression⟩ ⟨if clause⟩ ::= if ⟨Boolean expression⟩ then ⟨simple arithmetic expression⟩ ::= A/B | B/A ⟨simple Boolean⟩ ::= k < 1 | a > 0

⟨arithmetic expression⟩ ⟨if clause⟩ ⟨simple arithmetic expression⟩ else ⟨arithmetic expression⟩ if ⟨Boolean expression⟩ then ⟨simple arithmetic expression⟩ else ⟨arithmetic expression⟩ if ⟨simple Boolean⟩ then ⟨simple arithmetic expression⟩ else ⟨arithmetic expression⟩ if k < 1 then ⟨simple arithmetic expression⟩ else ⟨arithmetic expression⟩ if k < 1 then A/B else ⟨arithmetic expression⟩ if k < 1 then A/B else ⟨simple arithmetic expression⟩ if k < 1 then A/B else B/A


Set pelajaran terkait

Third-Party Ownership and Insurable Interest

View Set

Networking Plus Chapter Three, Network Ch.3, Network+ Ch3 quiz, Networking Final Quizlet

View Set

Operations Management - Project Management

View Set