Übungsblatt2
                            =============

Author: Jan Schäfer 
Date: 2011-05-09 12:04:25 CEST


Table of Contents
=================
1 Übungsblatt 2 
        1.1 Aufgabe 1 
        1.2 Aufgabe 2 


1 Übungsblatt 2 
~~~~~~~~~~~~~~~~

1.1 Aufgabe 1 
--------------
  + Lösungsweg!!! Nur eine Gruppe! 
  + Wichtig: Zustandsnamen beim DFA als Mengen! 
  + Achtung mit . in REs! 
    . ist oft vordefinierte Character-Klasse, die *alles* matched
    Extra-Warnung: meistens matched . *nicht* line terminators!
    => In der Regel konfigurierbar 
    
  + Fragen 
      * Frage 1 
          - Gibt es immer einen DFA? Wenn, ja, warum? 
            NFA ist endlich
      * Frage 2 
          - Gegeben ein NFA mit n Zuständen, wieviele Zustände hat der DFA maximal? 
            2^n
              + Warum? 
                P(A) kann als n-bit Zahl repräsentiert werden
                
      * Frage 3 
          - Ist der DFA alleine genug für einen Scanner? 
            Nein, es müssen auch die Token zurückgegeben werden (an die Endzustände schreiben)
      * Frage 4 
          - Was wenn mehrere Token matchen? 
            - Regeln definieren, z.B. das erste in der Definitionsliste
      * Frage 5 
          - Ist der erzeugte DFA immer optimal? 
            Nein
      * Frage 6 
          - Wie kann ich den DFA optimieren? 
            Finde äquivalente Zustände und vereinige sie
              + Wann sind Zustände äquivalent? 
                1. Beide final/non-final
                2. Für jedes Symbol s haben beide den gleichen Folgezustand
      * Frage 7 
          - Reicht das? 
            Nein, es geht immer noch einfacher
            

1.2 Aufgabe 2 
--------------
  + a) JFLex-Datei 
      * Klammern und CO 
          - Lösung 1 
            SZE = [(),{}.+-\\*/;]
            {SZE}  { return new Token(Token.SPECIAL); }
          - Lösung 2 
            "(" { return new Token(Token.LPAREN); }
            ...
            
      * Whitespaces 
        WHITESPACE = [ \t\n\r]
      * New Lines 
        NEWLINE = \r|\n|\r\n
        
      * Identifier 
          - Lösung 1 
            IDENT = [a-zA-Z$_][a-zA-Z$_0-9]+
              + Problem 
                matched $ (in Java erlaubt, aber nicht laut Blatt)
          - Lösung 2 
            DIGIT = [0-9]
            LETTER = [a-zA-Z]
            IDENT  = ({LETTER}|_)({LETTER}|{DIGIT}|_)* 
          - Lösung 3 
            BU = [a-zA-Z_]
            BUZI = {BU}|[0-9]
            IDENT = {BU}{BUZI}*
            
          - Identifier String? 
            yytext()
            IDENT  { return token(TokenType.IDENTIFIER, yytext()); }
      * Integer 
          - Lösung 1 
            INTEGER  = [+-]?[0-9]+
              + Problem 
                00005
          - Lösung 2 
            INTEGER  = [+-]?(0|[1-9][0-9]*)
            
          - Vorzeichen? 
            4 + 3
            4 +3
            
            
  + b) Kommentare 
      * Lösung 1 
        COMMENT  = "/*" ([^*] | "*"[^/])* "*"? "*/"
          - Problem 
            /* **/ /* */
            
      * Lösung 2 
        COMMENT = "/*" ( [^*] | "*"[^/*])* "*"? "*/"
          - Problem 
            /** ** **/
            
      * Lösung 3 
        COMMENT = "/*" ( [^*] | "*"+ [^/*])* "*"+ "/"
        
      * Lösung 4 
        COMMENT         = "/*" ~"*/"
        
      * Lösung aus JFlex Doku: 
        TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*"+ "/"
        
        TraditionalComment is the expression that matches the
        string "/*" followed by a character that is not a *,
        followed by anything that does not contain, but ends
        in "*/". As this would not match comments like /****/,
        we add "/*" followed by an arbitrary number (at least
        one) of "*" followed by the closing "/". This is not
        the only, but one of the simpler expressions matching
        non-nesting Java comments. It is tempting to just
        write something like the expression "/*" .* "*/", but
        this would match more than we want. It would for
        instance match the whole of /* */ x = 0; /* */,
        instead of two comments and four real tokens. See
        DocumentationComment and CommentContent for an
        alternative.
      * Probleme mit Buffergröße? 
        - Nein, JFlex vergrößert bei Bedarf den Buffer
          - Alternativlösung (1) 
            "/*" { yybegin(LONGCOMMENT); }
             {
                    "*/" { yybegin(YYINITIAL); }
                    .|\n { }
            }
            
      * End-Of-Line 
        LINECOMMENT     == "//" ~{NEWLINE}
        
  + c) Zeilen-/ Spaltennummern 
    JFlex Direktiven:
    %line
    %column
    
    Token entsprechend erweitern und Werte übergeben:
    "false" { return new Token(yyline, yycolumn, Token.Type.FALSE); }
    
      * Verbesserte Lösung (keine Gruppe) 
        Definiere neue Methoden im Scanner:
        %{
          private Token token(Token.Type type) {
            return new Token(yyline, yycolumn, Token.Type, null);
          }
        
          private Token token(Token.Type type, Object value) {
            return new Token(yyline, yycolumn, Token.Type, value);
          }
        %}
        
                      "false" { return token(Token.Type.FALSE); }
        
  + Hauptprogramm 
      * Triviale Lösung 
        %debug