<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki-de.moshellshocker.dns64.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=77.21.252.61</id>
	<title>Wikipedia (Deutsch) – Lokale Kopie - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-de.moshellshocker.dns64.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=77.21.252.61"/>
	<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php/Spezial:Beitr%C3%A4ge/77.21.252.61"/>
	<updated>2026-06-12T08:49:17Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki-de.moshellshocker.dns64.de/index.php?title=LL-Parser&amp;diff=357324</id>
		<title>LL-Parser</title>
		<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=LL-Parser&amp;diff=357324"/>
		<updated>2021-04-06T17:55:49Z</updated>

		<summary type="html">&lt;p&gt;77.21.252.61: /* Beispiel Implementierung in Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im [[Compilerbau]] ist ein &#039;&#039;&#039;LL-Parser&#039;&#039;&#039; ein Top-Down-[[Parser]], der die Eingabe von &#039;&#039;&#039;L&#039;&#039;&#039;inks nach rechts abarbeitet, um eine [[Linksableitung|&#039;&#039;&#039;L&#039;&#039;&#039;inksableitung]] der Eingabe zu berechnen.&amp;lt;ref&amp;gt;Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman: &#039;&#039;Compilers, Principles, Techniques, and Tools&#039;&#039;. ISBN 0-201-10088-6, S. 191&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein LL-Parser heißt &#039;&#039;&#039;LL(k)-Parser&#039;&#039;&#039;, wenn er während des Parsens &#039;&#039;k&#039;&#039; [[Token (Übersetzerbau)|Tokens]] vorausschauen kann und im Gegensatz zum [[LF-Parser]] den Kellerinhalt benutzt. &#039;&#039;k&#039;&#039; wird dabei als &#039;&#039;[[Lookahead]]&#039;&#039; bezeichnet. Diesem Parsertyp liegen die [[LL(k)-Grammatik]]en zu Grunde.&lt;br /&gt;
&lt;br /&gt;
Obwohl die LL(k)-Grammatiken relativ eingeschränkt sind, werden LL(k)-Parser oft benutzt. Die Entscheidung, nach welcher Regel expandiert wird, kann allein durch Analyse des Lookahead getroffen werden. Eine einfache Möglichkeit zur Implementierung dieser Parsertechnik bietet die Methode des [[Rekursiver Abstieg|rekursiven Abstiegs]].&lt;br /&gt;
&lt;br /&gt;
== Funktionsweise ==&lt;br /&gt;
Ausgangspunkt ist eine Grammatik &amp;lt;math&amp;gt;G = (N, \Sigma, P, S)&amp;lt;/math&amp;gt;.&lt;br /&gt;
Der Parser arbeitet mit einer Zustandsmenge &amp;lt;math&amp;gt;Q = (N \cup \Sigma)^* \times \Sigma^* \times \mathbb{N}^*&amp;lt;/math&amp;gt;, wobei sich ein Zustand &amp;lt;math&amp;gt;q = (k, w, z) \in Q&amp;lt;/math&amp;gt; so zusammensetzt:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ist der aktuelle Inhalt eines [[Stapelspeicher|Laufzeitkellers]], der für die Speicherung der aktuellen Symbole verwendet wird. &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; kann sowohl Terminal- als auch Nichtterminalsymbole beinhalten.&lt;br /&gt;
* &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; ist der Teil der Eingabe, der noch nicht gelesen wurde.&lt;br /&gt;
* &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; ist die Ausgabe, eine Folge natürlicher Zahlen, die die Nummern der Regeln der Linksableitung enthält.&lt;br /&gt;
&lt;br /&gt;
Der [[Nichtdeterminismus|nichtdeterministische]] [[Automat (Informatik)|Automat]] für die LL(k)-Analyse ist dann:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\mathcal{A} = (Q, \delta, q_0, F)&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;q_0 = (S, w, \epsilon)&amp;lt;/math&amp;gt; (Anfangszustand)&lt;br /&gt;
* &amp;lt;math&amp;gt;F = (\epsilon, \epsilon, z)&amp;lt;/math&amp;gt; (Endzustand)&lt;br /&gt;
&lt;br /&gt;
Dabei ist &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; das Startsymbol der zugrundeliegenden Grammatik und &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; die Linksanalyse der Eingabe &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Die Transitionen &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt; setzen sich so zusammen:&lt;br /&gt;
* &amp;lt;math&amp;gt;(a\alpha, aw, z) \vdash (\alpha, w, z)&amp;lt;/math&amp;gt; (Shift- oder Verschiebeschritt)&lt;br /&gt;
* &amp;lt;math&amp;gt;(A\beta, w, z) \vdash (\alpha\beta, w, zi)&amp;lt;/math&amp;gt; (Expansions- oder Ableitungsschritt), wobei die Regel &amp;lt;math&amp;gt;A\rightarrow\alpha&amp;lt;/math&amp;gt; in der Regelmenge &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; enthalten sein muss und &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; die Nummer dieser Regel ist.&lt;br /&gt;
&lt;br /&gt;
== LL(1)-Parser ==&lt;br /&gt;
Dieser Parsertyp verwendet einen Lookahead von einem Zeichen.&lt;br /&gt;
Auf Grund dieser Einschränkung kann einfach ein deterministischer Parser erstellt werden.&lt;br /&gt;
&lt;br /&gt;
Die oben genannten nichtdeterministischen Schritte werden dabei durch den Lookahead determiniert.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel Implementierung in Python ===&lt;br /&gt;
&lt;br /&gt;
In einem Beispiel soll ein LL(1) Parser die folgende einfache Grammatik abbilden:&lt;br /&gt;
&lt;br /&gt;
    S → F&lt;br /&gt;
    S → ( S + F )&lt;br /&gt;
    F → n&lt;br /&gt;
&lt;br /&gt;
Die folgende Python-Implementierung des LL(1)-Parsers zu dieser Grammatik wird auf den Eingabestring &#039;&#039;((n+n)+n)&#039;&#039; angewendet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Parse table&lt;br /&gt;
table = {&#039;@S&#039;: {&#039;n&#039;: 0, &#039;(&#039;: 1},&lt;br /&gt;
         &#039;@F&#039;: {&#039;n&#039;: 2}}&lt;br /&gt;
&lt;br /&gt;
rules = [[&#039;@F&#039;],&lt;br /&gt;
         [&#039;(&#039;, &#039;@S&#039;, &#039;+&#039;, &#039;@F&#039;, &#039;)&#039;],&lt;br /&gt;
         [&#039;n&#039;]]&lt;br /&gt;
&lt;br /&gt;
def syntactic_analysis(string):&lt;br /&gt;
    print(&#039;Syntactic analysis of input string:&#039;, string)&lt;br /&gt;
    stack = [&#039;\n&#039;, &#039;@S&#039;]&lt;br /&gt;
    tokens = list(string) + [&#039;\n&#039;]&lt;br /&gt;
    position = 0&lt;br /&gt;
    while len(stack) &amp;gt; 0:&lt;br /&gt;
        stackvalue = stack.pop()&lt;br /&gt;
        token = tokens[position]&lt;br /&gt;
        if not stackvalue.startswith(&#039;@&#039;):&lt;br /&gt;
            if stackvalue == token:&lt;br /&gt;
                # print(&#039;pop&#039;, repr(stackvalue))&lt;br /&gt;
                position += 1&lt;br /&gt;
                if token == &#039;\n&#039;:&lt;br /&gt;
                    print(&#039;input accepted&#039;)&lt;br /&gt;
                    break&lt;br /&gt;
            else:&lt;br /&gt;
                print(&#039;syntax error at input:&#039;, repr(token))&lt;br /&gt;
                break&lt;br /&gt;
        else:&lt;br /&gt;
            rule = table[stackvalue].get(token, -1)&lt;br /&gt;
            print(&#039;at pos&#039;, position, &#039;found rule&#039;, repr(stackvalue +&lt;br /&gt;
                    &#039; -&amp;gt; &#039; +  &#039; &#039;.join(rules[rule])))&lt;br /&gt;
            for r in reversed(rules[rule]):&lt;br /&gt;
                stack.append(r)&lt;br /&gt;
        # print(&#039;stack:&#039;, repr(&#039;, &#039;.join(reversed(stack))))&lt;br /&gt;
&lt;br /&gt;
syntactic_analysis(&#039;((n+n)+n)&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Ausgabe des Skripts ergibt bei korrekter Syntax direkt den serialisierten Syntax-Baum:&lt;br /&gt;
&lt;br /&gt;
 Syntactic analysis of input string: ((n+n)+n)&lt;br /&gt;
 at pos 0 found rule &#039;@S -&amp;gt; ( @S + @F )&#039;&lt;br /&gt;
 at pos 1 found rule &#039;@S -&amp;gt; ( @S + @F )&#039;&lt;br /&gt;
 at pos 2 found rule &#039;@S -&amp;gt; @F&#039;&lt;br /&gt;
 at pos 2 found rule &#039;@F -&amp;gt; n&#039;&lt;br /&gt;
 at pos 4 found rule &#039;@F -&amp;gt; n&#039;&lt;br /&gt;
 at pos 7 found rule &#039;@F -&amp;gt; n&#039;&lt;br /&gt;
 input accepted&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[LR-Parser]]&lt;br /&gt;
&lt;br /&gt;
== Einzelnachweise ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Compilerbau]]&lt;/div&gt;</summary>
		<author><name>77.21.252.61</name></author>
	</entry>
</feed>