/media/sda-magnetic/david/Dokumente-15/fernuni-hagen/cs-i-ii/old-cs-2-03/yacc/yacc/lern2.txt


#################################### YACC #####################################


LALR(1)-Parser

parser.y    ->      Yacc            -> y.tab.c
y.tab.c     ->      C-Compiler      -> a.out
Eingabe     ->      a.out           -> Ausgabe

Spezifikationsfile: parser.y

yacc parser.y
gcc y.tab.c -ly

-ly!!! Damit Yacc-Bibliotheken eingebunden werden. 

Der erzeugte Parser steht als Funktion yyparse() zur Verfügung

Yacc-Spezifikation


Deklarationen
%%
Grammatik
%%
Hilfsprozeduren




%{
#include <ctype.h>
#include <stdio.h>
%}
%token NUMBER
%%
lines           : lines expr '\n' {printf("%d\n", $2); }
                | lines '\n'
                |
                ;
expr            : expr '+' term { $$ = $1 + $3; }
                | expr '-' term { $$ = $1 - $3; }
                | term
                ;
term            : term '*' factor { $$ = $1 * $3; }
                | term '/' factor { $$ = $1 * $3; }
                | factor
                ;
factor          : '(' expr ')' { $$ = $2; }
                | NUMBER
                ;
%%
int yylex() {
    int c;
    c = getchar();
    if (isdigit(c)) {
        ungetc(c, stdin); 
        scanf("%d", &yylval);
        return NUMBER;
    }
    return c;
}



Yacc-Spezifikationen, Grammatik-Teil:

- Nichtterminale (lines, expr, term, ...)
- Terminale (Token): 
    - Einzelne Zeichen, Typ char oder int '+', '(', '\n'
    - Explizit deklarierte Token (NUMBER); Im Deklarationsteil 
      %token NUMBER
- Produktionen 




############################## SCHEME ###############################

(+ 5 5 5 5)
(* (+ 2 3) 5)
(* (+ 1 2) 4)
(< 1 2)
(< 2 1)
(> 1 2)
(> 2 1)
(define (square x) (* x x))
(define (sqr x) (* x x))
(square 2)
(sqr 2)

############################ PYTHON ###################################

# Kommentar
2 + 2
(2+2)*4
100/16
1/16
1.0/16.0
"Hallo"
print('Super')
a = [100, 200, 300]
a[0]
a[1]
a[2]

############################## Uebersetzerbau ##########################

Syntaxanalyse: Die zweite Phase der Übersetzung ist die Syntaxanalyse
Syntaxbaum/Ableitungsbaum: Die Aufgabe der Syntaxanalyse besteht darin aus der Folge von Token einen Syntaxbaum zu berechnen

if id[1] cop[>=] const[10] then id[2] := const[1] end

Baum, Abbildung, siehe Seite 41

Grammatik: Basis für die Syntaxanalyse ist eine Grammatik

Einige Regeln einer Grammatik:

stmt    ::= assignment | cond
cond    ::= if boolexpr then stmt end |
            if boolexpr then stmt else stmt end
numexpr ::= id | const

Zwei Strategien:
1. Top-down-Analyse
2. Bottom-up

Top-down-Analyse: Baut den Baum von der Wurzel zu den Blättern hin auf 
Bottom-up-Analyse:  Der Baum wird von den Blättern her aufgebaut 
                    Dabei ist die Grundidee, so lange Token der Eingabefolge zu lesen und sich zu merken, bis eine vollständige rechte Seite einer Grammatikregel gelesen worden ist.
                    
Kontextfreie Grammatiken und Syntaxbäume 

Kontextfreie Grammatiken: Die Syntax höherer Programmiersprachen wird durch kontextfreie Grammatiken beschrieben 

Definition: Eine kontextfreie Grammatik ist ein Quadrupel G = (N, E, P, S), wobei gilt:
1. N ist ein Alphabet von Nichtterminalen 
2. E ist ein Alphabet von Terminalen. Die Alphabete N und E sind disjunkt
3. P = N x (N U E)* ist eine Menge von Produktionsregeln 
4. S in N ist das Startsymbol 

Nichtterminale: stmt, cond, ...
Terminale: if, id, ...
Produktionen: Paare bestehnd aus einem Nichtterminal und einer Folge von Nichtterinalen und Terminalsysmbolen 

stmt ::= assignment | cond

{(stmt, assigment), (stmt, cond)}

Produktionsregeln werden in formalen Betrachtungen häufig mit Pfeilen notiert. 

(A, alpha)
A -> alpha 

A -> alpha1, A -> alpha2, ..., A -> alphan

A -> alpha1 | alpha2 | ... | alphan

Nichtterminale: A, B, C, X, Y, Z, ...
Terminale: a, b, c, ...

...

Top-down-Analyse

Ableitungsbaum und Eingabefolge werden von links nach rechts gelesen 

Solange beide Folgen gleiche ... kann man weiterlesen ...

Falls zwei nicht übereinstimmende Terminalsymbole angetroffen werden, so ist
1. entweder eine vorher getroffene Produktion falsch gewesen und rückgängig zu machen
2. Die Eingabefolge syntaktisch nicht korrekt. 

stmt        ->  assigment | cond | loop
assignment  ->  id := expr
cond        ->  if boolexpr then stmt fi |
                if boolexpr then stmt else stmt fi
loop        ->  while boolexpr do stmt od
expr        ->  boolexpr | numexpr
boolexpr    ->  numexpr cop numexpr
term        ->  term * factor | factor
factor      ->  id | const | (numexpr)

In dieser Sprache:

if b > 0 then a := 1 fi

if id cop const then id := const fi

linksrekursive Produktionen: Das zu ersetzende Nichtterminal auf der rechten Seite der Produktion tritt wieder ganz links auf. 

Top-down-Analyse: Top-down-Analyse mit Backtracking 

Top-Down-Analyse: Linksrekursive Produktionen und Verlaufen in Sackgassen