250 likes | 354 Views
CS 403 - Programming Languages. Class 05 September 7, 2000. Today’s Agenda. Announcement: Collecting samples of student work for CSAB accreditation visit next year. Chapter 3 Finish Syntax Semantics Assignment: Read chapter 4 for Tuesday. Study Recommendations.
E N D
CS 403 - Programming Languages Class 05 September 7, 2000
Today’s Agenda • Announcement: Collecting samples of student work for CSAB accreditation visit next year. • Chapter 3 • Finish Syntax • Semantics • Assignment: Read chapter 4 for Tuesday.
Study Recommendations • You should be able to do the exercises on pages 151, 152 & 153.
Reading Quiz • Give the phrase for these acronyms • BNF • CFG • Draw a line, confer with mates, correct your answers if necessary. • Turn them in.
Chapter 3: Syntax & Semantics • Syntax:the form or structure of the expressions statements, and program units • Semantics: the meaning of the expressions, statements, and program units
Ambiguous Grammars • A grammar is ambiguous iff (if and only if) it generates a sentential form that has two or more distinct parse trees. • A simple example: <expr> <expr> <op> <expr> | const <op> / | - • Can you draw two parse trees for this expression? const - const / const
<expr> <expr> <expr> <op> <expr> <expr> <op> <expr> <expr><op><expr> <expr><op><expr> const - const / const const - const / const Two Parse Trees: Ambiguous! Expression:const - const / const Operator precedence?
Operator Precedence (one way) • If we use the parse tree to indicate precedence levels of the operators, we cannot have ambiguity • An unambiguous expression grammar: <expr> <expr> - <term> | <term> <term> <term> / const | const
Operator Precedence • An unambiguous expression grammar: <expr> <expr> - <term> | <term> <term> <term> / const | const <expr> <expr> - <term> <term> <term> / const const const
Grammar for Precedence <expr> <expr> - <term> <term> - <term> const - <term> const - <term> / const const - const / const
Extended BNF 1. Optional parts are placed in brackets ([]) <proc_call> -> ident [ ( <expr_list>)] 2. Put alternative parts of RHSs in parentheses and separate them with vertical bars <term> -> <term> (+ | -) const 3. Put repetitions (0 or more) in braces ({}) <ident> -> letter {letter | digit}
BNF <--> EBNF BNF: <expr> -> <expr> + <term> | <expr> - <term> | <term> <term> -> <term> * <factor> | <term> / <factor> | <factor> EBNF: <expr> -> <term> {(+ | -) <term>} <term> -> <factor> {(* | /) <factor>}
type_identifier ( identifier ) , .. constant constant Syntax Graphs • Put the terminals in circles or ellipses and put the nonterminals in rectangles; connect with lines with arrowheads: e.g., Pascal type declarations
Recursive Descent Parsing • Parsing is the process of tracing or constructing a parse tree for a given input string. • Parsers usually do not analyze lexemes; that is done by a lexical analyzer, which is called by the parser. • A recursive descent parser traces out a parse tree in top-down order; it is a top-down parser.
Recursive Descent Parsing • Each nonterminal in the grammar has a subprogram associated with it; the subprogram parses all sentential forms that the nonterminal can generate. • The recursive descent parsing subprograms are built directly from the grammar rules. • Recursive descent parsers, like other top-down parsers, cannot be built from left-recursive grammars.
Recursive Descent Parsing • Example: For the grammar: <term> -> <factor> {(* | /) <factor>} • We could use the following recursivedescent parsing subprogram (this one is written in C) void term() { factor(); /* parse the first factor*/ while (next_token == asterisk_code || next_token == slash_code) { lexical(); /* get next token */ factor(); /* parse the next factor */ } }
Static semantics • (Have nothing to do with “meaning”) • Categories: 1. Context-free but cumbersome (e.g. type checking) 2. Noncontext-free (e.g. variables must be declared before they are used)
Attribute Grammars (AGs) • CFGs cannot describe all of the syntax of programming languages • Additions to CFGs to carry some semantic info along through parse trees • Primary value of AGs: 1. Static semantics specification 2. Compiler design (static semantics checking)
Attribute Grammars • Definition: An attribute grammar is a CFG G = (S, N, T, P) with the following additions: 1. For each grammar symbol x there is a set A(x) of attribute values. 2. Each rule has a set of functions that define certain attributes of the nonterminals in the rule. 3. Each rule has a (possibly empty) set of predicates to check for attribute consistency.
AG Example 1 • Let X0 -> X1 ... Xn be a rule. • Functions of the form S(X0) = f(A(X1), ... A(Xn)) define synthesized attributes. • Pass information up the parse tree. • Functions of the form I(Xj) = f(A(X0), ... , A(Xn)), for i <= j <= n, define inherited attributes. • Pass information down the parse tree. • Initially, there are intrinsic attributes on the leaves (i.e.: data type).
AG Example 1 (2) • Example: expressions of the form id + id • id's can be either int_type or real_type • types of the twoid's must be the same • type of the expression must match its expected type
AG Example 2 (3) • BNF: <expr> -> <var> + <var> <var> -> id • Attributes: • actual_type - synthesized for <var> and <expr> • expected_type - inherited for <expr>
Attribute Example B (1) 1. Syntax rule: <expr> -> <var>[1] + <var>[2] Semantic rules: <var>[1].env <expr>.env <var>[2].env <expr>.env <expr>.actual_type <var>[1].actual_type Predicate: <var>[1].actual_type = <var>[2].actual_type <expr>.expected_type = <expr>.actual_type
Attribute Example B (2) 2. Syntax rule: <var> -> id Semantic rule: <var>.actual_type <- lookup (id, <var>.env)