<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=LL-Parser</id>
	<title>LL-Parser - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=LL-Parser"/>
	<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=LL-Parser&amp;action=history"/>
	<updated>2026-05-22T00:58:35Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Wikipedia (Deutsch) – Lokale Kopie</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki-de.moshellshocker.dns64.de/index.php?title=LL-Parser&amp;diff=357324&amp;oldid=prev</id>
		<title>77.21.252.61: /* Beispiel Implementierung in Python */</title>
		<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=LL-Parser&amp;diff=357324&amp;oldid=prev"/>
		<updated>2021-04-06T17:55:49Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Beispiel Implementierung in Python&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Im [[Compilerbau]] ist ein &amp;#039;&amp;#039;&amp;#039;LL-Parser&amp;#039;&amp;#039;&amp;#039; ein Top-Down-[[Parser]], der die Eingabe von &amp;#039;&amp;#039;&amp;#039;L&amp;#039;&amp;#039;&amp;#039;inks nach rechts abarbeitet, um eine [[Linksableitung|&amp;#039;&amp;#039;&amp;#039;L&amp;#039;&amp;#039;&amp;#039;inksableitung]] der Eingabe zu berechnen.&amp;lt;ref&amp;gt;Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman: &amp;#039;&amp;#039;Compilers, Principles, Techniques, and Tools&amp;#039;&amp;#039;. ISBN 0-201-10088-6, S. 191&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein LL-Parser heißt &amp;#039;&amp;#039;&amp;#039;LL(k)-Parser&amp;#039;&amp;#039;&amp;#039;, wenn er während des Parsens &amp;#039;&amp;#039;k&amp;#039;&amp;#039; [[Token (Übersetzerbau)|Tokens]] vorausschauen kann und im Gegensatz zum [[LF-Parser]] den Kellerinhalt benutzt. &amp;#039;&amp;#039;k&amp;#039;&amp;#039; wird dabei als &amp;#039;&amp;#039;[[Lookahead]]&amp;#039;&amp;#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 &amp;#039;&amp;#039;((n+n)+n)&amp;#039;&amp;#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 = {&amp;#039;@S&amp;#039;: {&amp;#039;n&amp;#039;: 0, &amp;#039;(&amp;#039;: 1},&lt;br /&gt;
         &amp;#039;@F&amp;#039;: {&amp;#039;n&amp;#039;: 2}}&lt;br /&gt;
&lt;br /&gt;
rules = [[&amp;#039;@F&amp;#039;],&lt;br /&gt;
         [&amp;#039;(&amp;#039;, &amp;#039;@S&amp;#039;, &amp;#039;+&amp;#039;, &amp;#039;@F&amp;#039;, &amp;#039;)&amp;#039;],&lt;br /&gt;
         [&amp;#039;n&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
def syntactic_analysis(string):&lt;br /&gt;
    print(&amp;#039;Syntactic analysis of input string:&amp;#039;, string)&lt;br /&gt;
    stack = [&amp;#039;\n&amp;#039;, &amp;#039;@S&amp;#039;]&lt;br /&gt;
    tokens = list(string) + [&amp;#039;\n&amp;#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(&amp;#039;@&amp;#039;):&lt;br /&gt;
            if stackvalue == token:&lt;br /&gt;
                # print(&amp;#039;pop&amp;#039;, repr(stackvalue))&lt;br /&gt;
                position += 1&lt;br /&gt;
                if token == &amp;#039;\n&amp;#039;:&lt;br /&gt;
                    print(&amp;#039;input accepted&amp;#039;)&lt;br /&gt;
                    break&lt;br /&gt;
            else:&lt;br /&gt;
                print(&amp;#039;syntax error at input:&amp;#039;, repr(token))&lt;br /&gt;
                break&lt;br /&gt;
        else:&lt;br /&gt;
            rule = table[stackvalue].get(token, -1)&lt;br /&gt;
            print(&amp;#039;at pos&amp;#039;, position, &amp;#039;found rule&amp;#039;, repr(stackvalue +&lt;br /&gt;
                    &amp;#039; -&amp;gt; &amp;#039; +  &amp;#039; &amp;#039;.join(rules[rule])))&lt;br /&gt;
            for r in reversed(rules[rule]):&lt;br /&gt;
                stack.append(r)&lt;br /&gt;
        # print(&amp;#039;stack:&amp;#039;, repr(&amp;#039;, &amp;#039;.join(reversed(stack))))&lt;br /&gt;
&lt;br /&gt;
syntactic_analysis(&amp;#039;((n+n)+n)&amp;#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 &amp;#039;@S -&amp;gt; ( @S + @F )&amp;#039;&lt;br /&gt;
 at pos 1 found rule &amp;#039;@S -&amp;gt; ( @S + @F )&amp;#039;&lt;br /&gt;
 at pos 2 found rule &amp;#039;@S -&amp;gt; @F&amp;#039;&lt;br /&gt;
 at pos 2 found rule &amp;#039;@F -&amp;gt; n&amp;#039;&lt;br /&gt;
 at pos 4 found rule &amp;#039;@F -&amp;gt; n&amp;#039;&lt;br /&gt;
 at pos 7 found rule &amp;#039;@F -&amp;gt; n&amp;#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>