CSCE 434 Lecture 16

From Notes
Jump to navigation Jump to search

« previous | Monday, September 30, 2013 | next »

Lecture Slides

Tangent: Recursive Programs

Speed: Recursion is not usually fast.

  1. Create stack frame
  2. push arguments onto stack
  3. execute function call
  4. pop stack

Some compilers convert them to loops instead of recursion.

Optimizing a for-loop is easier than a while-loop because a for-loop is bounded. (something about GPUs) Both are difficult, but an unbounded while-loop is harder.

Predictive parsing

  • tables built from specification
  • state stack
  • parser reads from tables; process is an implementation of a finite state machine

LL(1) Parse Algorithm

int tos = 0;
stack[tos++] = eof;
stack[tos++] = start_symbol;
Token token = next_token();
Token X = Stack[tos];
do {
  if (X is a terminal || X == eof) {
    if (X == Token) {
      pop X;
      token = next_token();
    } else error();
  } else {  // X is a non-terminal
    if (M[X,token] == "X ::= { Y[1], Y[2], ..., Y[k] }")
      pop X;
      push Y[k], Y[k-1], ..., Y[1]
    } else error()
  }
  X = stack[tos];
} while (X != eof)

LL(1) Table for our grammar

  id num + - * / eof
<goal> <g> ::= <e> <g> ::= <e>
<expr> <e> ::= <t> <e'> <e> ::= <t> <e'>
<expr'> <e'> ::= + <t> <e'> <e'> ::= - <t> <e'> <e'> ::= ε
<term> <t> ::= <f> <t'> <t> ::= <f> <t'>
<term'> <t'> ::= ε <t'> ::= ε <t'> ::= * <f> <t'> <t'> ::= / <f> <t'> <t'> ::= ε
<factor> <f> ::= id <f> ::= num

First Set

is the set of terminal symbols that begin strings derived from α

If , then .

Building :

  1. If is a terminal, .
  2. If , then
  3. If , then put in
  4. If is a non-terminal and , then if and for (keep looking at the next until we get one that can't go to )

Follow Set

For nonterminal , define as the set of terminals that can appear immediately to the right of in some sentential form.

Thus a non-terminal's follow set specifies the tokens that can legally appear after it

A terminal symbol has now follow set.

To build:

  1. If , then put in . We don't know enough about , but this rule tells us something about .
  2. If , then put in
  3. If and , then put in (almost the same thing as above; if nothing follows , then anything that follows can follow by this rule)

Constructing a Parse Table

  1. For any production , perform steps 2–4
  2. for any terminal a in first(\alpha), add to
  3. If , add to for all terminals .
  4. If and , add to .
  5. Set each undefined entry of to error

If this fails, the grammar is not LL(1), so we can make it LL(1) by adding non-terminals:

Adding non-terminals to the grammar does not change the language it accepts.

LL(1) Grammars

A grammar is LL(1) if and only if for all non-terminals , teach distinct pair of productions and satisfy the following condition: .

Properties:

  • no left-recursive grammar is LL(1)
  • no ambiguous grammar is LL(1)
  • LL(1) parsers operate in linear time
  • epsilon-free grammar , where each alternative expansion for begins with a distinct terminal is a simple LL(1) grammar.