home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 02 / texte / pascomp.4 < prev    next >
Encoding:
Text File  |  1980-01-03  |  21.0 KB  |  502 lines

  1. Pascomp
  2.  
  3. Pascal baut einen Pascal - Compiler
  4.  
  5.  
  6. Teil 5: Die semantische Analyse
  7.         von Johannes Velmans
  8.  
  9.  
  10. Mit   der   semantischen   Analyse   haben  wir  jetzt  nach  der
  11. lexikalischen  und  der  syntaktischen  Analyse  die  letzte  zum
  12. Analyseteil eines Compilers gehörende Arbeitsphase erreicht.
  13.  
  14. Die Aufgabe der semantischen Analyse besteht darin, die statische
  15. Semantik  von  Programmen  zu überprüfen, sowie Informationen für
  16. den  Syntheseteil  des  Compilers (Codeerzeugung und Optimierung)
  17. bereitzustellen.  Wie  wir  bereits  aus  den  bisherigen  Folgen
  18. erfahren  haben,  wird  die Syntax einer Programmiersprache durch
  19. eine   kontextfreie   Grammatik,  die  meistens  in  BNF-Notation
  20. formuliert   wird,   beschrieben.   Die  Syntaxanalyse  überprüft
  21. demzufolge  die  strukturelle  Korrektheit  des  zu übersetzenden
  22. Programms.  Soweit,  so gut. Programmiersprachen besitzen aber in
  23. aller  Regel  die Eigenschaft, nicht kontextfrei zu sein, was dem
  24. einen  oder  anderen  Compilerhersteller  schon  hin  und  wieder
  25. Kopfschmerzen bereitet hat.
  26.  
  27. Für  den Nachweis der Korrektheit eines Programms ist es daher in
  28. keinem  Fall  ausreichend, nur die syntaktische Korrektheit eines
  29. Programms zu untersuchen. Die Korrektheit von Programmen hängt im
  30. weiteren  noch  davon  ab,  ob  die  auftreten  den (angewandten)
  31. Bezeichner  konsistent  mit ihren implizit und explizit gegebenen
  32. Deklarationen und Definitionen benutzt werden. Diese Bedingungen,
  33. die in entsprechenden Regeln "verpackt" werden, bezeichnet man in
  34. der Fachliteratur mit dem Begriff der Kontextbedingungen.
  35.  
  36. Der aufmerksame Leser könnte an dieser Stelle meinen, daß es auch
  37. hier  einen  Formalismus gibt, der die Semantik beschreibt. Einen
  38. derartigen  Formalismus,  wie  es  ihn  bei der lexikalischen und
  39. syntaktischen  Analyse  gab,  existiert  für die Beschreibung der
  40. Semantik  einer  Programmiersprache  aber  leider  nicht. Bis zum
  41. heutigen  Tage  ist  die  Semantik fast aller Programmiersprachen
  42. informell,  das  heißt  in  natürlicher  Sprache  und  in  Worten
  43. definiert.
  44.  
  45. Als  Beispiel  sei  hier an das Problem der zulässigen Feldindex-
  46. Typen aus dem Pascal-Report erinnert. Hier lesen wir:
  47.  
  48.  ...type a=array[t1] of t2
  49.  
  50. wobei a ein neuer Typbezeichner ist. t1 ist der Indextyp, der ein
  51. Scalar-  oder  ein  Unterbereichstyp  sein  kann, wobei die Typen
  52. integer und real keine zugelassenen Indextypen sind...
  53.  
  54. Unterstellt  man  einmal,  daß  solche  Semantikbeschreibungen in
  55. verantwortungsvoller Arbeit erstellt und überpüft wurden, so sind
  56. derartige  informelle Beschreibungen nicht selten mit Fehlern und
  57. Mehrdeutigkeiten übersät oder einfach unvollständig. Ein formaler
  58. Ansatz  zur Semantikbeschreibung hätte dahingegen aufgrund seines
  59. mechanischen  Aufbaus  den  Vorteil,  auf  einfache Art und Weise
  60. einen  Entscheidungsprozess  herbeizuführen,  mit  dem  man  eine
  61. Sprache  als  korrekt  und vollständig identifizieren könnte. Ein
  62. weiterer,  genauso  wichtiger  Aspekt steht in engem Zusammenhang
  63. mit  der  Implementierung  einer  beliebigen  Programmiersprache:
  64. Außer  für  die  semantische  Analyse  bestehen  bereits für alle
  65. weiteren Phasen eines Compilers erzeugende Systeme.
  66.  
  67. Würde  man jetzt noch die Semantik formal definieren, so wäre man
  68. in  der  Lage,  ein  Programm  zu  schreiben,  dessen Eingabe die
  69. Beschreibung   einer   Programmiersprache  darstellt  und  dessen
  70. Ausgabe  ein  Compiler  zu  dieser  Programmiersprache  wäre. Die
  71. einzige  Aufgabe eines Compilerherstellers bestünde dann nur noch
  72. darin, die Eingabe entsprechend formal zu definieren.
  73.  
  74. Die  Beschäftigung  mit  Scanner, Parser, Codeerzeugung usw. wäre
  75. dann  "von  gestern".  Schön wär's. Doch zurück in die Steinzeit.
  76. Alle  in  einer Programmiersprache definierten Kontextbedingungen
  77. faßt man unter dem Begriff der statischen Semantik zusammen.
  78.  
  79. Neben  der  Überprüfung  der  statischen Semantik leitet sich die
  80. Aufgabenstellung  der  semantischen Analyse aus der Notwendigkeit
  81. her, das Programm so aufzuarbeiten, daß die Codeerzeugung und die
  82. Codeoptimierung   möglichst   effizient  arbeiten  können.  Diese
  83. Aufarbeitung   besteht   in   der  Zuordnung  von  Attributen  zu
  84. bestimmten Programmelementen. Solche Elemente können zum Beispiel
  85. Bezeichner  oder  (Teil-)Ausdrücke  sein,  denen als Attribut der
  86. jeweilige Typ zugeordnet wird.
  87.  
  88. Der   Vorteil   dieser  Attributierung  ist,  daß  die  benötigte
  89. Information  direkt  präsent  ist  und  sich  nur  auf  einen eng
  90. begrenzten   Kontext   der  jeweils  bearbeiteten  Programmstelle
  91. beschränkt.   Dies   macht   die   Implementierung  der  Semantik
  92. übersichtlicher und leicht verständlich.
  93.  
  94.  
  95. Was geschieht in der semantischen Analyse?
  96.  
  97. Abbildung 1: Informationsfluß un der semantischen Analyse
  98.  
  99.  
  100.   ───────            ─────────────            ───────────────
  101.  ( Parser)─────────>( semantische )─────────>( Codeerzeugung )
  102.   ───────           (   Analyse   )           ───────────────
  103.                      ──┬───────┬──
  104.                        │       │
  105.                        │       │
  106.                        │       │
  107.                        │       │
  108.                      ──┴───────┴─
  109.                     (   Error    )
  110.                     (            )
  111.                     (  Handler   )
  112.                      ────────────
  113.  
  114.  
  115.  
  116. Bei   Eintritt   in   die   sematische   Analysephase   gilt  die
  117. Voraussetzung,  daß  der zu übersetzende Programmtext syntaktisch
  118. korrekt  ist.  Wie  man  aus  Abbildung  1  erkennt, dient dieser
  119. Analysephase  der  vom  Parser erzeugte Strukturbaum als Eingabe.
  120. Wir  erinnern uns: Den Strukturbaum erhält man, indem man aus dem
  121. Ableitungsbaum semantisch irrelevante Einzelheiten eliminiert. So
  122. enthält  ein  Strukturbaum  keine  notationswichtigen Details wie
  123. Klammern, Semikolons usw.
  124.  
  125. Die  inneren  Knoten  eines  Baumes  stellen  im wesentlichen die
  126. Operatoren (+, -, `, :=, ...) von Ausdrücken und Anweisungen dar.
  127. Die  Blätter  hingegen  sind  die  Operanden dieser Ausdrücke und
  128. Zuweisungen.   Die  konkrete  Aufgabe  der  semantischen  Analyse
  129. besteht  nun  darin,  diesen  Knoten  Attribute  zuzuordnen (Typ,
  130. Grenzen  usw.)  und  deren  Attributwerte  zu bestimmen (Integer,
  131. 1..100  usw.).  Abhängig von der Signifikanz eines Knotens können
  132. mehrere   Attribute  (Attributemengen)  oder  auch  nur  einzelne
  133. Attribute zugeordnet werden. Wir wollen diese Attributzuordnungen
  134. an einem einfachen Beispiel betrachten:
  135.  
  136. Gegeben sei das kurze und fehlerhafte Pascalprogramm:
  137.  
  138. PROGRAM Error;
  139. VAR i, j: INTEGER;
  140.        r: REAL
  141. BEGIN
  142.  i := j + r;
  143. END.
  144.  
  145. Betrachten wir den Teilbaum des Strukturbaums in Abbildung 2, der
  146. die Zuweisung i:=j+r enthält.
  147.  
  148. Abbildung 2: Strukturbaum der Zuweisung i:=j+r
  149.  
  150.  
  151.  
  152.               assign
  153.                 │
  154.                 │
  155.         ┌───────┴──────────────────┐
  156.         │                          │
  157.  
  158.         i                         addop
  159.                                    │
  160.                                    │
  161.                        ┌───────────┴────────────┐
  162.                        │                        │
  163.                        │                        │
  164.  
  165.                        j                         r
  166.  
  167.  
  168.  
  169.  
  170. Nun ordnen wir den Knoten i,j , r , assign und addop ein Attribut
  171. mit dem Namen hasvalue zu, wie in Abbildung 3 dargestellt.
  172.  
  173.  
  174. Abbildung 3: ...und der attributiere Strukturbaum
  175.  
  176.  
  177.               assign (hashvalue = ?)
  178.                 │
  179.                 │
  180.         ┌───────┴──────────────────┐
  181.         │                          │
  182.  
  183.         i (hashvalue = ?)        addop (hashvalue = ?)
  184.                                    │
  185.                                    │
  186.                        ┌───────────┴────────────┐
  187.                        │                        │
  188.                        │                        │
  189.  
  190.                        j  (hashvalue)           r (hashvalue)
  191.  
  192.  
  193.  
  194.  
  195.  
  196. Als nächstes bestimmen wir die Werte dieser Attribute:
  197.  
  198.      i,j  erhalten den Wert Integer ,
  199.       r     erhält den Wert Real    ,
  200.  
  201.  
  202. -addop    :
  203. Laut  Pascalsemantik  ist  Addition  von  Integer  und  Real eine
  204. erlaubte Operation. Der Ergebnistyp ist Real . addop erhält somit
  205. den Attributwert Real zugewiesen.
  206.  
  207. - assign    :
  208. Pascal  läßt  eine  Zuweisung  von  Real  (=  hasvalue(addop)) an
  209. Integer nicht zu. Hier kommt es also zu einem Semantikfehler. Die
  210. Fehlermeldung könnte etwa lauten: "Typeconflict of operands".
  211.  
  212. Den  so mit Attributen "geschmückten" Strukturbaum bezeichnet man
  213. als   attributierten  Strukturbaum,  der  gleichzeitig  auch  die
  214. Ausgabe  der semantischen Analysephase darstellt. Als Hilfsmittel
  215. zur formalen Beschreibung dieser Umformung von einem Strukturbaum
  216. in   einen   attributierten   Strukturbaum  werden  attributierte
  217. baumerzeugende  Systeme  benutzt.  Hierbei werden Zuordnungen von
  218. Attributmengen   zu   Knoten   abstrakter   Strukturbäume  formal
  219. festgelegt  und  Rechenregeln zur Bestimmung der Werte sämtlicher
  220. Attribute spezifiziert.
  221.  
  222. In  solchen Systemen unterscheidet man zwei Arten von Attributen:
  223. Die  "inherited"  (erworbenen)  Attribute  und  die "synthesized"
  224. (abgeleiteten) Attribute. Erworbene Attribute erlauben dabei eine
  225. Berechnung  ihrer Attributwerte ohne eine weitere Betrachtung der
  226. Umgebung   des   Strukturbaumknotens.   Dahingegen   lassen  sich
  227. abgeleitete  Attribute  erst  nach  der Betrachtung der Söhne des
  228. aktuellen  Knotens  berechnen. Weiterhin gilt für ein Attribut A,
  229. daß  es  entweder  ein  erworbenes oder ein abgeleitetes Attribut
  230. ist, aber nie beiden Attributklassen gleichzeitig angehören kann.
  231.  
  232. Die  gesamte  Attributmenge  einer  Programmiersprache setzt sich
  233. also  aus  diesen  beiden  disjunkten Attributmengen zusammen. In
  234. unserem  Beispiel zählen die Attribute der Bezeichner i , j und r
  235. zu  der  Menge  der  erworbenen  Attribute, assign und addop sind
  236. dahingegen  abgeleitete  Attribute.  Um eine möglichst effiziente
  237. Berechnung   der  Attributwerte  durchführen  zu  können,  wurden
  238. zahlreiche Durchlaufstrategien durch den Strukturbaum entwickelt,
  239. deren  Behandlung  den Rahmen dieser Folge sprengen würde. Es sei
  240. an  dieser  Stelle  auf  ein  Buch  von Waite und Goos, "Compiler
  241. Constructions",  aus  dem  Springer-Verlag hingewiesen, das näher
  242. auf diese Problematik eingeht.
  243.  
  244.  
  245. Analyse der statischen Semantik
  246.  
  247. Wie  jeder  "Pascalist"  weiß,  muß  allen  angewandten Auftreten
  248. (applied   occurrence)  eines  Bezeichners  im  Programmtext  ein
  249. definierendes  Auftreten  (defining  occurrence) voranstehen. Das
  250. definierende  Auftreten  eines  Bezeichners  legt bekanntlich die
  251. Bedeutung  des Bezeichners in einem bestimmten Gültigkeitsbereich
  252. (scope)  fest.  Ein  angewandtes  Auftreten  stellt  dabei  einen
  253. entsprechenden  Bezug zu diesem Gültigkeitsbereich dar. Analog zu
  254. jedem  Gültigkeitsbereich  existiert  in  einem Programm in jedem
  255. Punkt  eine  eindeutig bestimmte aktuelle Umgebung (environment),
  256. die  die  Menge  der  an  dieser  Stelle  sichtbaren Definitionen
  257. bezeichnet.  Zu  den  Aufgabenbereichen  der semantischen Analyse
  258. zählt  nun auch die Bestimmung der jeweiligen aktuellen Umgebung.
  259. Dies schließt folgendes mit ein:
  260.  
  261.    - Sämtliche  Definitionen  eines Blocks (Gültigkeitsbereiches)
  262.    müssen auf Eindeutigkeit und Konsistenz hin überprüft werden.
  263.  
  264.    - Zu  jeder Programmiersprache existieren implizite Attribute.
  265.    In  Pascal gehören zum Beispiel die Attribute Integer , Real ,
  266.    Boolean   usw.   dazu.   Da   hier  eine  Definition  vor  der
  267.    entsprechenden  Anwendung  nicht  erforderlich ist, müssen für
  268.    diesen  Regelteil  der  Programmiersprache implizite Attribute
  269.    erzeugt werden.
  270.  
  271.    - Für  jede  Definition eines Bezeichners sind die zugehörigen
  272.    Attributwerte  zu  bestimmen  und  für jeden Eintritt in einen
  273.    neuen Block ist die Umgebung entsprechend zu modifizieren.
  274.  
  275.    -  Realisierung  von  Blockumgebungen  als  Datenstrukturen in
  276.    sogenannten  Displayvektoren.  Der  Displayvektor  spiegelt an
  277.    einer    beliebigen   Stelle   im   Programm   die   statische
  278.    Blockumgebung  wieder.  Jedes  Element  dieses Vektors ist ein
  279.    Zeiger  auf  den  Anfang  der  Bezeichnerdefinitionen in einem
  280.    Block.  Wird  ein  neuer Block betreten, so wird der Index des
  281.    Displayvektors   um   1   inkrementiert   und  auf  den  neuen
  282.    Blockanfang  verwiesen.  Bei Austritt aus einem Block wird der
  283.    Displayvektor  um  1  dekrementiert. Durch eine Rückverfolgung
  284.    der  Blöcke  über  den  Displayvektor  lassen  sich somit sehr
  285.    leicht  alle  im  betrachteten  Block  sichtbaren Definitionen
  286.    ausfindig  machen.  Der  Index  dieses  Vektors  ist dabei die
  287.    aktuelle   Block  schachtelungstiefe  (BST)  der  betrachteten
  288.    Prozedur.  Der  Wert  der  BST  wird in der Codeerzeugung eine
  289.    wichtige  Rolle spielen, wenn es darum geht, die Adresse einer
  290.    Variablen zu bestimmen.
  291.  
  292.  
  293. Eine beispielhafte semantische Programmanalyse
  294.  
  295. Program Minimum;
  296. (*  "Minimum" ist der Bezeichner des Programms. Dieser Bezeichner
  297. ist  im  übrigen  meist  auf einer anderen Ebene als auf der Pro-
  298. grammebene  selbst  definiert,  so daß kein zweiter, globaler Be-
  299. zeichner "Minimum" in den meisten Fällen keine Fehlermeldung her-
  300. vorruft.  Der Programmname wird somit von den wenigsten Compilern
  301. mit übersetzt.*)
  302.  
  303. var i,j :integer;
  304.       r :real
  305.       (*  Einführung neuer globaler Variablen "i","j" und "r" Be-
  306.       nutzung der Standardbezeichner "Integer" und "Real".*)
  307.  
  308. Begin
  309.       (*  In der nachfolgenden aktuellen Umgebung sind die impli-
  310.       ziten  Bezeichner (Integer, Real, Boolean etc.) und die Be-
  311.       zeichner "i", "j", "r" und eventuell "Minimum" definiert.*)
  312.  
  313.  
  314.   i:= 100 * 10 + 1;
  315.       (* korrekte Zuweisung  eines konstanten-Ausdrucks an eine
  316.        Integer-Variable "1"*)
  317.  
  318.  
  319.   r:= 2 * 4.25;
  320.       (*  Die  Berechnung  von  2*4.25  ist korrekt, da an dieser
  321.       Stelle Integer zu real kompatibel ist. Die Konstante 2 wird
  322.       nach  2.0  konvertiert.  Der gesamte Ausdruck erhält so den
  323.       Typ Real und kann anschließend an die Variable "r" zugewie-
  324.       sen werden.*)
  325.  
  326.   j:= i < r;
  327.       (*  Vergleich:  Die  Integerzahl  "i" wird in eine Realzahl
  328.       umgewandelt.  Der  Vergleich  "i < R" ist dann zulässig und
  329.       erhält  den Wert "boolean". Eine Zuweisung an eine Integer-
  330.       zahl  hingegen  ist inkompatibel mit der Definition von "j"
  331.       da  der Ausdruck "i < r" einen Attributwert vom Typ "boole-
  332.       an" hat und eine Zuweisung an eine Integerzahl laut Pascal-
  333.       semantik nicht gestattet ist *)
  334.  
  335. End.
  336.      (*  Ende der aktuellen Umgebung - und hier auch des gesamten
  337.      Programms*)
  338.  
  339.  
  340.  
  341.  
  342. In  der  semantischen  Analyse wird also zu jeder Anwendung eines
  343. Bezeichners  in  der aktuellen Umgebung die zugehörige Definition
  344. bestimmt. Die Anwendung muß dabei immer kompatibel mit der in der
  345. Definition festgelegten Bedeutung des Bezeichners sein. Eine der-
  346. artige  Überprüfung bedingt dabei allerdings, daß auch für nicht-
  347. elementare Teilstrukturen des Programms Attributwert zu bestimmen
  348. sind .
  349.  
  350.  
  351. Operatoridentifikaton
  352.  
  353. Zum  Schluß  der  Analyse der statischen Semantik wollen wir noch
  354. kurz   auf   das  Problem  der  Operatoridentifikation  eingehen.
  355. Operatoren wie +, *, -, / etc. können in Programmiersprachen über
  356. laden   (overloaded)   sein.   Genauer  wird  das  folgendermaßen
  357. definiert:
  358.  
  359. Ein  Operator  in  einer  typisierten  Sprache wird als überladen
  360. bezeichnet,  wenn  verschiedene  Bedeutungen  für diesen Operator
  361. existieren  und  die  geeignete  Bedeutung  nur  aus  dem Typ der
  362. Operanden bestimmt werden kann.
  363.  
  364. Ein  überladener  Operator  repräsentiert  dann  nicht  nur  eine
  365. einzelne  Funktion,  sondern  eine  ganze  Klasse von Funktionen.
  366. Dieses  Konzept wurde bereits in früheren Programmiersprachen wie
  367. ALGOL60    oder    PL=1    gebraucht    und   ist   in   modernen
  368. Programmiersprachen wie ADA sehr stark ausgebaut worden.
  369.  
  370. Auch  in  Pascal, wie könnte es auch anders sein, sind Operatoren
  371. zum  größten  Teil überladen. Die Aufgabe der Operatoridentifika-
  372. tion  besteht nun darin, für jedes Auftreten eines Operators eine
  373. passende  Funktion  auszuwählen.  Die Wahl ist dabei abhängig vom
  374. Typ  der  Operanden,  dem Kontext der Operanden und natürlich dem
  375. Operator  selbst. Am Beispiel des Pascal "*"-Operators (Multipli-
  376. kation) sei dies in Abbildung 4 verdeutlicht.
  377.  
  378.  
  379. Implementierung der semantischen Analyse
  380.  
  381. Bei  dem Vorhaben für unseren Compiler eine geeignete Analysphase
  382. zu  schreiben,  kommt  uns  die gewählte Konstruktion des Parsers
  383. zugute.  Wir erinnern uns: Als Parser-Implementierung wählten wir
  384. das Konzept des "recursive descent" Parsers, bei dem jedem Nicht-
  385. terminal der Zerteilergrammatik eine Prozedur der Implementierung
  386. entsprach.  Der  Aufbau  des  Strukturbaumes entsprach einem Lauf
  387. durch die entsprechenden Teile der Zerteilergrammatik.
  388.  
  389. Um  nun  den  Strukturbaum mit Attributen zu schmücken, reicht es
  390. aus,  in  jeder Prozedur, die einem Nichtterminal entspricht, Va-
  391. riablen  für die benötigten Attribute zu definieren und deren At-
  392. tributwerte  zu berechnen. Erworbene Attribute werden hierbei als
  393. "call  by  value"-Parameter,  abgeleitete  Attribute als "call by
  394. reference"-Parameter  an die aufzurufende Prozedur mit übergeben.
  395. Unser  Parser braucht dann insgesamt nur noch an den entsprechen-
  396. den  Stellen  mit  Attributvariablen erweitert zu werden. Die Be-
  397. rechnung  der Attributwerte kann dann parallel mit dem Parserlauf
  398. erledigt werden.
  399.  
  400. So,  das  war's für diesmal. In der nächsten Folge werden wir uns
  401. mit  dem  Problem  der  Code-Erzeugung  für  die  Zwischensprache
  402. beschäftigen.  Mit der Veröffentlichung der nächsten Ausgabe wird
  403. dann  auch  der  gesamte Compiler mit Interpreter und Quelltexten
  404. aus  der  DATA-Box  zu  haben  sein,  um alles bis dahin Gelernte
  405. "life" mitzuerleben.
  406.  
  407.  
  408.  
  409.   Typ A │   Typ B │     Funktion des Operators
  410. ────────┼─────────┼─────────────────────────────────────────────
  411. integer │ integer │ Integermultiplikation. Ergebnistyp : integer
  412. integer │ real    │ Realmultiplikation. Ergebnistyp : real
  413.    real │ integer │ Realmultiplikation. Ergebnistyp : real
  414.    real │ real    │ Realmultiplikation. Ergebnistyp : real
  415. set of T│ set of T│ Mengendurchschnitt. Ergebnistyp : set of T
  416.  
  417.  
  418. Abb.  4: Überladung (overloading) des Multiplikationsoperators in
  419. Pascal
  420.  
  421.  
  422.  
  423.  
  424. Kurzreferenz Folge 2, 3, 4:
  425.  
  426. - Quellsprache: irgendeine Programmiersprache
  427.  
  428. -  Zielsprache: im allegemeinen die Maschinensprache eines Compu-
  429. ters
  430.  
  431. -  Compiler:  übersetzt Anweisungen der Quellsprache in gleichbe-
  432. deutende Anweisungen der Zielsprache
  433.  
  434. - Pass: Zyklus in der Verarbeitung einer Datei (Eingabe -> Verar-
  435. beitung -> Ausgabe)
  436.  
  437. -  Nicht-Terminale:  Programmgefüge  wie  Prozeduren, Funktionen,
  438. Anweisungsfolgen etc.,
  439.  
  440. -  Terminale:  Worte  (Bezeichner,  Schlüsselwörter etc.), die im
  441. eigentlichen  Programm  vorkommen und Prozeduren, Funktionen etc.
  442. bilden
  443.  
  444. - Grammatik, Syntax: Beschreibt Umfang und Stuktur einer Sprache
  445.  
  446. - Semantik: die Bedeutung von Sprachstukturen
  447.  
  448. - BNF: Backus-Naur Form. Darstellungsform von Grammatiken
  449.  
  450. -  Produktionen:  Ersetzungsregeln, nach den der Syntax genügende
  451. "Sätze" einer Sprache erzeugt werden
  452.  
  453. - Grundsymbol: Bezeichner (Namen von Variablen, Prozeduren etc.),
  454. Literale  (Zeichenketten  wie  "was nun?)", Schlüsselwörter (z.B.
  455. "begin", "end"), Seperatoren (Semikolon, Leerzeichen,...)
  456.  
  457. -  Symbol-Token:  Abbildung eines Grundsymbols auf eine speicher-
  458. platzsparende  und schnelleren Zugriff gewährende Form zur weite-
  459. ren Verarbeitung
  460.  
  461. -  Symbol-Klassen: Bezeichner, ganze Zahlen, Zeichen, Anfangssym-
  462. bol, Endsymbol usw.
  463.  
  464. -  Symbol-Merkmal: identifiziert die Symbole einer Symbol-Klasse,
  465. z.B. der Wert einer ganzen Zahl
  466.  
  467. -  Symbol-Tabelle: nimmt aus dem Quelltext gelesenen Grundsymbole
  468. (Bezeichner, Schlüsselwörter) mit ihren Merkmalen auf
  469.  
  470. -  lexikalische  Analyse:  überprüfung, ob die Bestandteile einer
  471. Anweisung  der  Sprachdefinition entsprechen und ob keine undefi-
  472. nierten Zeichen enthalten sind
  473.  
  474. -  Scanner: Dient zur Erkennung der Grundsymbole und deren Abbil-
  475. dung  auf eine Symbolfolge (Tokenfolge), führt außerdem die lexi-
  476. kalische Analyse durch
  477.  
  478. -  syntaktische Analyse: überprüfung, ob eine Folge von Grundsym-
  479. bolen der Syntax (Grammatik) einer Sprache entspricht
  480.  
  481. -  Parser (Zerteiler): seine Aufgabe ist die syntaktische Analyse
  482. der "Sätze" einer Sprache und die Fehlerbehandlung, wenn der Syn-
  483. tax nicht entsprochen wird. Dabei wird ein "Stukturbaum" erzeugt,
  484. der der semantischen Analyse unter worfen wird
  485.  
  486. -  Keller  (engl. "stack"): eine Datenstruktur, die nach dem "LI-
  487. FO"-Prinzip  arbeitet  ("Last  In,  First Out"). Vergleichbar mit
  488. einem Stapel Blätter, von dem nur das oberste Blatt genommen bzw.
  489. ein neues Blatt nur zuoberst abgelegt werden kann
  490.  
  491. -  Kellerautomat:  Ein  möglicher Ansatz zur einfachen Lösung der
  492. Syntaxanalyse
  493.  
  494. - Zerteilungsverfahren: es gibt verschiedene Verfahren zur Reali-
  495. sierung von Parsern:
  496.     - zielbezogene Zerteilung ("top-down"-Analyse): hier wird der
  497. Stukturbaum von der Wurzel zu den Blättern (Ziel) hin erzeugt )
  498.  
  499.     -  quellbezogene  Zerteilung  ("bottom-up"-Analyse): Der Baum
  500. wird  von  den  Blättern  zur  Wurzel (Quelle) verfolgt. Dies ist
  501. mächtiger als die "top-down"-Analyse, aber auch komplizierter
  502.