Monday, October 20, 2014

Assignment #4 - Programming Language (Chapter 4)

Review Question :
--------------------------------------------------------------------------------------------------------------------------
6. What is a state transition diagram?

  • A state transition diagram is a directed graph. Where the nodes of a state diagram are labeled with state names.
7. Why are character classes used, rather than individual characters, for the letter and digit transitions of a state diagram for a lexical analyzer?
  • Suppose we need a lexical analyzer that recognizes only arithmetic expressions,
    including variable names and integer literals as operands. Assume that
    the variable names consist of strings of uppercase letters, lowercase letters, and digits but must begin with a letter. Names have no length limitation. The first
    thing to observe is that there are 52 different characters (any uppercase or lowercase letter) that can begin a name, which would require 52 transitions from the transition diagram’s initial state. However, a lexical analyzer is interested only in determining that it is a name and is not concerned with which specific
    name it happens to be. Therefore, we define a character class named LETTER
    for all 52 letters and use a single transition on the first letter of any name.
8. What are the two distinct goals of syntax analysis?
  • First, the syntax analyzer must check the input program to determine whether it is syntactically correct.
    When an error is found, the analyzer must produce a diagnostic message and
    recover. In this case, recovery means it must get back to a normal state and
    continue its analysis of the input program. This step is required so that the
    compiler finds as many errors as possible during a single analysis of the input
    program. If it is not done well, error recovery may create more errors, or at
    least more error messages. The second goal of syntax analysis is to produce a
    complete parse tree, or at least trace the structure of the complete parse tree,
    for syntactically correct input. The parse tree (or its trace) is used as the basis
    for translation.
9. Describe the differences between top-down and bottom-up parsers.
  • Top-down, meaning they construct left most derivations and a parse tree in top-down order, which mean the tree is built from the root downward to leaves. In bottom-up order the parse tree is built from leaves upward to the root.
10. Describe the parsing problem for a top-down parser.
  • The general form of a left sentential form is xAy, whereby our notational conventions x is a string of terminal symbols, A is a non terminal, and y is a mixed string. Because x contains only terminals, A is the leftmost non terminal in the sentential form, so it is the one that must be expanded to get the next sentential form in a left- most derivation. Determining the next sentential form is a matter of choosing the correct grammar rule that has A as its LHS. For example, if the current sentential form is xAy and the A-rules are A → bB, A → cBb, and A → a, a top-down parser must choose among these three rules to get the next sentential form, which could be xbBy, xcBby, or xay. This is the parsing decision problem for top-down parsers.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Problem Set :
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
6. Given the following grammar and the right sentential form, draw a parse tree and show the phrases and simple phrases, as well as the handle.

S→AbB | bAc  A→Ab | aBB  B→Ac | cBb | c a. 
a. aAcccbbc =  S -> AbB -> aBBbB -> aAcBbB -> aAccBbbB -> aAcccbbc
b. AbcaBccb = S -> AbB -> AbcBb -> AbcAcb -> AbcaBBcb -> AbcaBccb
c. baBcBbbc = S ->  bAc -> baBBc -> baBcBbc -> baBcBbbc
7. Show a complete parse, including the parse stack contents, input string, and action for the string id * (id + id), using the grammar and parse table in Section 4.5.3.
Stack Input Action
0 id * (id + id) $ Shift 5
0id5 * (id + id) $ Reduce 6 (Use GOTO[0, F])
0F3 * (id + id) $ Reduce 4 (Use GOTO[0, T])
0T2 * (id + id) $ Reduce 2 (Use GOTO[0, E])
0T2*7 (id + id) $ Shift 7
0T2*7(4 id + id ) $ Shift 4
0T2*7(4id5 + id ) $ Shift 5
0T2*7(4F3 + id ) $ Reduce 6 (Use GOTO[4, F])
0T2*7(4T2 + id ) $ Reduce 4 (Use GOTO[4, T])
0T2*7(4E8 + id ) $ Reduce 2 (Use GOTO[4, E])
0T2*7(4E8+6 id ) $ Shift 6
0T2*7(4E8+6id5 ) $ Shift 5
0T2*7(4E8+6F3 ) $ Reduce 6 (Use GOTO[6, F])
0T2*7(4E8+6T9 ) $ Reduce 4 (Use GOTO[6, T])
0T2*7(4E8 ) $ Reduce 1 (Use GOTO[4, E])
0T2*7(4E8)11 $ Shift 11
0T2*7F10 $ Reduce 5 (Use GOTO[7, F])
0T2 $ Reduce 5 (Use GOTO[0, T])
0E1 $ Reduce 2 (Use GOTO[0, E])
–ACCEPT–
8.Show a complete parse, including the parse stack contents, input string, and action for the string (id + id) * id, using the grammar and parse table in Section 4.5.3.
Screen Shot 2014-10-17 at 4.27.59 PM
9. Write an EBNF rule that describes the while statement of Java or C++. Write the recursive-descent subprogram in Java or C++ for this rule.
  • <while_stmt> -> WHILE ‘(‘ (<arith_expr> | <logic_expr>) ‘)’ <block> <block> -> <stmt> | ‘{‘ <stmt> {<stmt>} ‘}’
10. Write an EBNF rule that describes the for statement of Java or C++. Write the recursive-descent subprogram in Java or C++ for this rule.
  • Assume the following non-terminals are given: <type>, <id>, <literal>, <assign>, <expr>, and <stmt_list>.
<for> -> for ‘(‘ [[<type>] <id> = <expr> {, [<type>] <id> = <expr>}] ; [<expr>] ; [<expr> {, <expr>}] ‘)’ ‘{‘ <stmt_list> ‘}’

Assignment #3 - Programming Language (Chapter 3)

Review Question :
--------------------------------------------------------------------------------------------------------------------------
6. Define a left-recursive grammar rule.

  • A left-recursive grammar means that the parser can get into a loop in the parsing rules without making any progress consuming the input. A grammar is left-recursive if we can find some non-terminal A which will eventually derive a sentential form with itself as the left-symbol.
7. What three extensions are common to most EBNFs?
  • Denotes an optional part of a RHS, which is delimited by brackets, the use of braces in an RHS to indicate that the enclosed part can be repeated indefinitely or left out altogether, deals with multiple choice options.
8. Distinguish between static and dynamic semantics.
  • Static semantics is only indirectly related to the meaning of programs during execution. Dynamic semantics is not universally accepted in notation.
9.What purpose do predicates serve in an attribute grammar?
  • The use of predicates functions is to state the static semantic rules of the language.
10. What is the difference between a synthesized and an inherited attribute?
  • An inherited attribute proceeds in a top-down order, from roots to leaves. A synthesized attribute proceeds in a completely bottom-up order, from leaves to root.
---------------------------------------------------------------------------------------------------------------------------------
Problem Set :
---------------------------------------------------------------------------------------------------------------------------------

6. Using the grammar in Example 3.2, show a parse tree and a leftmost derivation for each of the following statements :
a. A = A * (B * ( C + A ) )
<assign> -> <id> = <expr>
<id> -> A | B | C
<expr> – > <id> + <expr>
| <id> * <expr>
| ( <expr> )
| <id>
b. B = C * (A + C * B )
<assign> -> <id> = <expr>
<id> -> A | B | C
<expr> – >  <id> * <expr>
| <id> + <id> *<id>
| ( <expr> )
| <id>
c. A = A + (B * (C) )
<assign> -> <id> = <expr>
<id> -> A | B | C
<expr> – > <id> + <expr>
| <id> * <expr>
| ( <expr> )
| (<id>)
| <id>
7. Using the grammar in Example 3.4, show a parse tree and a leftmost derivation for each of the following statements:


a.) A = ( A + B ) * C

<assign> => <id> = <expr>
  •  A = <expr>
  •  A = <term>
  •  A = <factor> * <term>
  •  A = (<expr>) * <term>
  •  A = (<expr> + <term>) * <term>
  •  A = (<term> + <term>) * <term>
  •  A = (<factor> + <factor> ) * <term>
  •  A = (<id> + <term>) * <term>
  •  A = ( A + <term>) * <term>
  •  A = (A + <factor>) * <term>
  •  A = (A + <id>) * <term>
  •  A = (A + B) * <term>
  •  A = (A + B) * <factor>
  •  A = (A + B) * <id>
  •  A = (A + B) * C

b.)A = B + C + A
<assign> => <id>=<expr>
  • A=<expr>
  • A=<expr>+<term>
  • A=<expr>+<term>+<term>
  • A=<term>+<term>+<term>
  • A=<factor>+<term>+<term>
  • A=<id>+<term>+<term>
  • A=A+<term>+<term>
  • A=A+<factor>+<term>
  • A=A+<id>+<term>
  • A=A+C+<term>
  • A=A+C+<factor>
  • A=A+C+<id>
  • A=A+C+A

c.) A = A * (B + C)
<assign> => <id>=<expr>
  • A=<expr>
  • A=<term>
  • A=<term>*<factor>
  • A=<factor>*<factor>
  • A=<id>*<factor>
  • A=A*<factor>
  • A=A*(<expr>)
  • A=A*(<expr>+<term>)
  • A=A*(<term>+<term>)
  • A=A*(<factor>+<term>)
  • A=A*(<id>+<term>)
  • A=A*(B+<term>)
  • A=A*(B+<factor>)
  • A=A*(B+<id>)
  • A=A*(B+C)
d.) A = B * (C * (A + B))

<assign> => <id>=<expr>
  • A=<term>
  • A=<term>*<factor>
  • A=<factor>*<factor>
  • A=<id>*<factor>
  • A=B*<factor>
  • A=B*(<expr>)
  • A=B*(<term>)
  • A=B*(<term>*<factor>)
  • A=B*(<factor>*<factor>)
  • A=B*(<id>*<factor>)
  • A=B*(C*<factor>)
  • A=B*(C*(<expr>))
  • A=B*(C*(<expr>+<term>))
  • A=B*(C*(<term>+<term>))
  • A=B*(C*(<factor>+<term>))
  • A=B*(C*(<id>+<term>))
  • A=B*(C*(A+<term>))
  • A=B*(C*(A+<factor>))
  • A=B*(C*(A+<id>))
  • A=B*(C*(A+B))
8. Prove that the following grammar is ambiguous!
<S> -> <A>
<S> -> <A> * <A> | <id>
<id> -> x | y | z
It has two distinct parse tree. Unambiguous grammar don't have 2 distinct parse tree.
9. Modify the grammar of Example 3.4 to add a unary minus operator that has higher precedence than either + or *!
<assign> -> <id> = <expr>
<id>  ->  A | B | C
<expr> -> <expr> + <term>
| <term>
<term> -> <term> * <factor>
| <factor>
<factor> -> ( <expr> )
| +<id> | -<id>
10. Describe, in English, the language defined by the following grammar:

<S> → <A> <B> <C>
<A> → a <A> | a
<B> → b <B> | b
<C> → c <C> | c
LHS non-terminal S defined to non-terminal A, B, C, where A can be one or more a. B also can be one or more b and C can be one or more c.

Sunday, October 5, 2014

Assignment #2 - Programming Language ( Chapter 2 )

Kembali lagi atas tugas dari dosen saya, kali muncul untuk mengerjakan tugas chapter 2,
------------------------------------------------------------------------------------------------------------
Review Question :
------------------------------------------------------------------------------------------------------------
6. What hardware capability that first appeared in the IBM 704 computer strongly affected the evolution of programming languages? Explain why.
  •  Its capabilities prompted the development of Fortran because it was able to support  floating-point operations hardware.
7. In what year was the Fortran design project begun?
  • May 1954
8. What was the primary application area of computers at the time Fortran was designed?
  • Mathematics
9. What was the source of all of the control flow statements of Fortran I?
  • They were based on 704 instructions
10. What was the most significant feature added to Fortran I to get Fortran II?
  • Independent-compilation capability
------------------------------------------------------------------------------------------------------------
Problem Solving :
------------------------------------------------------------------------------------------------------------
6. Make an educated guess as to the most common syntax error in LISP
programs.
  • Undefined escape sequences in literal strings. The backslash character can be used in literal strings and characters :
    • to escape various characters
    • to introduce an escape sequence representing a character
7. LISP began as a pure functional language but gradually acquired more
and more imperative features. Why?
  • Because there is always many new idea for the uses and so on begin to develop the language.
8. Describe in detail the three most important reasons, in your opinion,
why ALGOL 60 did not become a very widely used language.
  • First, it is an interpreter type of language and focused on ease of use at the expense of system resources. 
  • Second, the running-time of a program that was written with the help of Speedcoding was usually ten to twenty times that of machine code
  • Excessive flexibility hurt ALGOL60 since languages that are difficult to learn were not as well received as languages with a more rigid structure.
9. Why, in your opinion, did COBOL allow long identifiers when Fortran
and ALGOL did not?
  • COBOL is more of a reporting language than Fortran. Since Fortran handles calculations much better, there is not a real need for long identifiers. As a reporting language, COBOL uses long identifiers in tagging the source to the reports it is writing. Also, COBOL is the closest language to a fully, self documenting language, that it gets, and long identifiers provides one more case for it.

10. Outline the major motivation of IBM in developing PL/I.
  • The main motivation for the development of PL/I was to provide a single tool for computer centers that must support both scientific and commercial applications. IBM believed that the needs of the two classes of applications were merging, at least to some degree. They felt that the simplest solution for a provider of systems, both hardware and software, was to furnish a single hardware system running a single programming language that served both scientific and commercial applications
-Dedi Sutomo-
-1801376582-