Sie sind auf Seite 1von 19

FH Schmalkalden

Dokumentation

FH Schmalkalden Fachbereich Informatik Markus Neviadomski Matrikel-Nr: 200259 +49 561 2876594 mn@ein-kunde.de

Prolog-Parser mit LL1-Grammatik

Softwaredokumentation

Inhaltsverzeichnis
1 Einleitung 2 Abgrenzung der Aufgabe 3 Verwendete Konventionen 4 LL(1)Grammatik 4.1 Denition einer LL(1)-Grammatik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Die entwickelte Grammatik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Nachweise der Grammatik 5.1 FIRST/FOLLOW-Berechnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Implementation 6.1 Der Scanner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Die Syntaxanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Erweiterungsm oglichkeiten A scanner.l B parser.y C Makele 3 3 3 3 3 3 6 6 8 9 9 9 10 13 19

FH Schmalkalden

Einleitung

Der Grundgedanke des Pojektes war, eine Grammatik zu erstellen, die die Programmiersprache Prolog abdeckt, genauer den Dialekt Visual Prolog. Vorgabe war dabei, das die Grammatik in der LL(1)-Form vorliegen soll.

Abgrenzung der Aufgabe

Eine LL(n)-Grammatik geh ort zu den kontextfreien Grammatiken. Diese sind verh altnism aig einfach zu implementieren, decken aber meist nicht den vollen Funktionsumfang ab, der ben otigt wird. So ist nicht m oglich, mit einer solchen Grammatik alle syntaktischen Vorschriften von Programmiersprachen abzudecken. Ein Beispiel w are hier die Deklaration einer Variable vor deren erster Benutzung. Was leistet dann der Parser? Er erkennt die syntaktische Korrektheit einzelner Prolog-Audr ucke und pr uft diese auf Syntaxfehler. Der Parser erkennt nicht die korrekte Verwendung einzelner Ausdr ucke und ihrer Parameter. Dies ist nur mit kontextsensitiven Grammatiken oder u ber umfangreiche Zeichenkettenbehandlung im Parser m oglich. Er erkennt weiterhin nicht, ob Bezeichner korrekt initialisiert wurden. Ausserdem wird jede Regel unabh angig von anderen Regeln gepr uft, dadurch schl agt zum Beispiel die Erkennung von falsch aufgerufenen Regeln fehl. Jede Regel wird komplett f ur sich behandelt, der globale Zusammenhang(Kontext) ist dem Parser unbekannt. Daraus folgt die Erkenntnis, das sich mit den genannten Anforderungen kein Parser realisieren l asst, der Visual-Prolog komplett abdeckt. Am Ende des Dokumentes wird in einem kurzen Ausblick allerdings noch auf Erweiterungsm oglichkeiten eingegangen.

Verwendete Konventionen

In Grammatiken unterscheidet man prinzipiell zwischen Terminalen und Nicht-Terminalen Symbolen. In der g angigen Literatur wird meist f ur Grossschreibung f ur Nicht-Terminale und komplette Kleinschreibung f ur Terminale eingesetzt. Davon weicht diese Dokumentation ab und verwendet es genau umgekehrt, um so identisch zur Syntax der Implementation zu bleiben. Quellcode wird durch die Verwendung des Fonts Courier besonders gekennzeichnet. TERMINAL nicht-terminal #include<stdio.h>

4
4.1

LL(1)Grammatik
Denition einer LL(1)-Grammatik

Die Familie der LL(k)-Grammatiken geh ort zu den kontextfreien Grammatiken. Diese Grammatiken sich durch 2 Dinge deniert. Zum einen d urfen keine linksrekursiven Regeln vorhanden sein und zum anderen sind die Regeln eindeutig. Die Analyse der Eingabe erfolgt dabei von links nach rechts. Desweiteren muss gew ahrleistet sein, dass der n achste Ableitungsschritt durch k Symbole der Eingabe eindeutig bestimmt werden kann. Das bedeutet f ur LL(1)-Grammatiken, dass durch das n achste lookahead-Token bereits eindeutig bestimmt werden kann, welche Produktion angewandt wird.

4.2

Die entwickelte Grammatik

Jedes Visual-Prolog-Programm besteht auch mehreren Programmteilen, die durch Schl usselw orter voneinander getrennt sind. Dies sind DOMAINS, FACTS, PREDICATES, CLAUSES und GOAL. DOMAINS und FACTS sind dabei als optional zu betrachten. Die entwickelte Grammatik gliedert sich in mehrere Teile, diese sind in der folgenden Tabelle durch Leerzeilen voneinander getrennt. Jeder Teil arbeitet unabh angig von den anderen und deckt einen bestimmten Teil eines Prolog-Programmes ab. Die Regel 1 der Grammatik f ugt diese Teile zusammen und deckt die Reihenfolge ab. Regel 2-8 deckt die Schl usselw orter der Programmteile ab und die M oglichkeit, auf die Teile DOMAINS und FACTS zu verzichten. Die Regeln 9 bis 18 dienen zur Produktion des DOMAIN-Teiles, 19 bis 33 decken den FACTS-Teil ab. Der PREDICATES-Teil wird von Regel 34 bis 47 geparst, 48 bis 86 parsen den

Softwaredokumentation

CLAUSES-Teil. Schlussendlich wird das GOAL durch Regel 87-100 abgedeckt.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

program domain part domain part facts part facts part predicates part clauses part goal part domains domain helper domain helper domain new domain new domain helper new domain helper built in domain domain list op domain list op facts fact helper fact helper fact fact global fact global fact global fact global fact global fact params fact param helper fact param helper fact param fact param name fact param name predicates pred helper pred helper predicate nondeterm nondeterm pred ende pred ende pred params pred param helper pred param helper pred param pred param name pred param name

domain part facts part predicates part clauses part goal part IDENT IDENT IDENT IDENT IDENT

DOMAINS domains FACTS facts PREDICATE predicates CLAUSES clauses GOAL goal

domain domain helper domains new domain REL OPERATOR built in domain SYMBOL new domain helper KOMMA new domain SYMBOL domain list op MATH OPERATOR fact fact helper facts fact global IDENTIFIER KLAMMERAUF fact params KLAMMERZU NONDETERM DETERM SINGLE NOCOPY fact param fact param helper KOMMA fact params SYMBOL fact param name VARIABLE predicate pred helper predicates nondeterm IDENTIFIER KLAMMERAUF pred params KLAMMERZU pred ende NONDETERM ENDZEICHEN pred param pred param helper KOMMA pred params SYMBOL pred param name VARIABLE

FH Schmalkalden

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

clauses clause help clause help clause clause or fact clause or fact clause ext clause ext clause params clause ptail clause ptail clause facts clause fact helper clause fact helper clause fact clause fact clause log op clause log op clause phead clause phead clause list clause listdescr clause listdescr clause listdescr2 clause listdescr2 clause listdescr3 clause listdescr4 clause listdescr4 clause tail clause tail helper clause tail helper clause tail element clause tail element clause math func clause operand clause operation clause operation clause term op clause term op goal goal goal goal goal goal goal goal goal goal goal goal goal goal

clause clause help clauses IDENTIFIER KLAMMERAUF clause or fact clause params KLAMMERZU clause ext ENDZEICHEN clause facts KLAMMERZU ENDZEICHEN TRENNZEICHEN clause tail clause phead clause ptail KOMMA clause params clause fact clause fact helper KOMMA clause facts SYMBOL STRING KOMMA SEMIKOLON VARIABLE clause list LISTOPEN clause listdescr LISTCLOSE clause listdescr2 LISTCLOSE VARIABLE clause listdescr3 UNDERSCORE LISTCUT VARIABLE LISTCUT clause listdescr4 VARIABLE UNDERSCORE clause tail element clause tail helper clause log op clause tail IDENTIFIER KLAMMERAUF clause params KLAMMERZU clause math func clause operand REL OPERATOR clause operand clause term op clause operation MATH OPERATOR clause operand CONSTANT VARIABLE IDENTIFIER KLAMMERAUF goal params KLAMMERZU ENDZEICHEN goal parameter goal ptail KOMMA goal params VARIABLE SYMBOL STRING goal list LISTOPEN goal listdescr LISTCLOSE goal listdescr2 LISTCLOSE goal parameter goal listdescr3 KOMMA goal listdescr2

params ptail ptail parameter parameter parameter parameter list listdescr listdescr listdescr2 listdescr3 listdescr3

Softwaredokumentation

Nachweise der Grammatik

Der Nachweis der Grammatik erfolgt in 2 Schritten. Als erstes muss die LL(1)-Eigenschaft der Grammatik nachgewiesen werden, dies erfolgt durch Berechnung der First/Follow-Mengen der einzelnen Regeln. Uber die First-Menge ermittelt man die Menge der Terminalen Symbole einer Regel, die durch das erste Regelelement repr asentiert werden. Dadurch kann der Nachweis erbracht werden, das alle Produktionen eines Symbols unterschiedlichen Terminalen beginnen. Damit ist die Eindeutigkeit der LL(1) nachgewiesen. Follow bestimmt die Menge aller Symbole, welche auf eine Produktion folgen k onnen, dies ist die Entescheidungsmenge, falls eine Alternative auf eine Regel in einer -Produktion m undet. Der zweite Schritt des Korrektheitsnachweis der Grammatik f uhrt Regeltests mit der Implementierung aus. Hier kann festgestellt werden, ob die Grammatik tats achlich Visual-Prolog-Regeln abdeckt und Fehler erkennt. Hierbei kam ein imagin ares Prolog-Programm zum Einsatz, welches nacheinander g angige Fehlerquellen enthielt. Getestet wurde auf Korrektheit eine Regelkopfes, Regelkopf und Regelschwanz, alle Formen einer Liste, mathematische Ausdr ucke und auf vergessene Klammern. Ausserdem wurden noch Tests bez uglich fehlerhafter Komma/Endzeichensetzung durchgef uhrt.

5.1
1

FIRST/FOLLOW-Berechnung
F IRST (domain part) F OLLOW (domain part) = {IDEN T DOM AIN S } F IRST (f acts part) F OLLOW (f acts part){IDEN T DOM AIN S, IDEN T F ACT S } F IRST (predicate part) = {IDEN T DOM AIN S, IDEN T F ACT S, IDEN T P REDICAT E } F OLLOW (domain part) = F IRST (f acts part) F OLLOW (f acts part) = {IDEN T F ACT S } F IRST (predicate part) = {IDEN T F ACT S, IDEN T P REDICAT E } F IRST (domain part) = {IDEN T DOM AIN S } F OLLOW (f acts part) = F IRST (P REDICAT E P ART ) = {IDEN T P REDICAT E } F IRST (f acts part) = {IDEN T F ACT S } F IRST (predicates part) = {IDEN T P REDICAT E } F IRST (clauses part) = {IDEN T CLAU SES } F IRST (goal part) = {IDEN T GOAL} F IRST (domains) = F IRST (domain) = F IRST (new domain) = {SY M BOL} F OLLOW (domain helper) = F OLLOW (domains) = F OLLOW (domain part) = F IRST (f acts part) F OLLOW (f acts part) = {IDEN T F ACT S } F IRST (predicate part) = {IDEN T F ACT S, IDEN T P REDICAT E } F IRST (domain helper) = {KOM M A} F IRST (domain) = {SY M BOL} F IRST (new domain) = {SY M BOL} F OLLOW (new domain helper) = F OLLOW (new domain) = {REL OP ERAT OR} F IRST (new domain helper) = {KOM M A} F IRST (built in domain) = SY M BOL F OLLOW (domain list op) = F IRST (new domain) F OLLOW (domain helper) = {SY M BOL} F OLLOW (domains) = {SY M BOL} F OLLOW (domain part) = {SY M BOL} F IRST (f acts part) F OLLOW (f acts part) = {SY M BOL, IDEN T F ACT S } F IRST (predicate part) = {SY M BOL, IDEN T F ACT S, IDEN T P REDICAT E } F IRST (domain list op) = {M AT H OP ERAT OR} F IRST (f acts) = F IRST (f act) = F IRST (f act global) F OLLOW (f act global) = {N ON DET ERM, DET ERM, SIN GLE, N OCOP Y, IDEN T IF IER} F OLLOW (f act helper) = F OLLOW (f acts) = F OLLOW (f actsp art) = {IDEN T P REDICAT E } F IRST (f act helper) = F IRST (f acts) = F IRST (f act global) F OLLOW (f act global) = {N ON DET ERM, DET ERM, SIN GLE, N OCOP Y, IDEN T IF IER} F IRST (f act) = F IRST (f act global) F OLLOW (f act global) = {N ON DET ERM, DET ERM, SIN GLE, N OCOP Y, IDEN T IF IER} F OLLOW (f act global) = {IDEN T IF IER}

2 3 4 5 6 7 8 9 10

11 12 13 14 15 16 17

18 19 20 21 22 23

FH Schmalkalden

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

F IRST (f act global) = {N ON DET ERM } F IRST (f act global) = {DET ERM } F IRST (f act global) = {SIN GLE } F IRST (f act global) = {N OCOP Y } F IRST (f act params) = F IRST (f act param) = {SY M BOL} F OLLOW (f act param helper) = F OLLOW (f act params) = {KLAM M ERZU } F IRST (f act param helper) = {KOM M A} F IRST (f act param) = {SY M BOL} F OLLOW (f act param name) = F OLLOW (f act param) = F IRST (f act param helper) F OLLOW (f act param helper) = {KOM M A, KLAM M ERZU } F IRST (f act param name) = {V ARIABLE } F IRST (predicates) = F IRST (predicate) = F IRST (nondeterm) F OLLOW (nondeterm) = {N ON DET ERM, IDEN T IF IER} F OLLOW (pred helper) = F OLLOW (predicates) = F OLLOW (predicates part) = {IDEN T CLAU SES } F IRST (pred helper) = F IRST (predicates) = F IRST (predicate) = F IRST (nondeterm) F OLLOW (nondeterm) = {N ON DET ERM, IDEN T IF IER} F IRST (predicate) = F IRST (nondeterm) = {N ON DET ERM } F OLLOW (nondeterm) = {IN DEN T IF IER} F IRST (nondeterm) = {N ON DET ERM } F OLLOW (pred ende) = F OLLOW (predicate) = F IRST (pred helper) F OLLOW (pred helper) = {IDEN T IF IER, N ON DET ERM, IDEN T CLAU SES } F IRST (pred ende) = {EN DZEICHEN } F IRST (pred params) = F IRST (pred param) = {SY M BOL} F OLLOW (pred param helper) = F OLLOW (pred params) = {KLAM M ERZU } F IRST (pred param helper) = {KOM M A} F IRST (pred param) = {SY M BOL} F OLLOW (pred param name) = F OLLOW (pred param) = F IRST (pred param helper) F OLLOW (pred param helper) = {KOM M A, KLAM M ERZU } F IRST (pred param name) = {V ARIABLE } F IRST (clauses) = F IRST (clause) = {IDEN T IF IER} F OLLOW (clause help) = F OLLOW (clauses) = F OLLOW (clauses part) = {IDEN T GOAL} F IRST (clause help) = IDEN T IF IER F IRST (clause) = {IDEN T IF IER} F IRST (clause or f act) = F IRST (clause params) = F IRST (clause phead) = {V ARIABLE } F IRST (clause list) = {V ARIABLE, LIST OP EN } F IRST (clause or f act) = f irst(clause f acts) = F IRST (clause f act) = {SY M BOL, ST RIN G} F OLLOW (clause ext) = {EN DZEICHEN } F IRST (clause ext) = {T REN N ZEICHEN } F IRST (clause params) = F IRST (clause phead) = {V ARIABLE } F IRST (clause list) = {V ARIABLE, LIST OP EN } F OLLOW (clause ptail) = F OLLOW (clause params) = {KLAM M ERZU } F IRST (clause ptail) = {KOM M A} F IRST (clause f acts) = f irst(clause f act) = {SY M BOL, ST RIN G} F OLLOW (clause f act helper) = F OLLOW (clause f acts) = {KLAM M ERZU } F IRST (clause f act helper) = {KOM M A} F IRST (clause f act) = {SY M BOL} F IRST (clause f act) = {ST RIN G} F IRST (clause log op) = {KOM M A} F IRST (clause log op) = {SEM IKOLON } F IRST (clause phead) = {V ARIABLE } F IRST (clause phead) = F IRST (clause list) = {LIST OP EN } F IRST (clause list) = {LIST OP EN }

Softwaredokumentation

69 70 71 72 73 74 75 76

77 78 79 80 81 82 83

84 85 86 87 88 89 90 91 92 93 94 95 96 97

F IRST (clause listdescr) = {LIST CLOSE } F IRST (clause listdescr) = F IRST (clause listdescr2) = {V ARIABLE, U N DERSCORE } F IRST (clause listdescr2) = {V ARIABLE } F IRST (clause listdescr2) = {U N DERSCORE } F IRST (clause listdescr3) = {LIST CU T } F IRST (clause listdescr4) = {V ARIABLE } F IRST (clause listdescr4) = {U N DERSCORE } F IRST (clause tail) = F IRST (clause tail element) = {IDEN T IF IER} F IRST (clause math f unc) = {IDEN T IF IER} F IRST (clause operand) = {IDEN T IF IER} F IRST (clause term op) = {IDEN T IF IER, CON ST AN T, V ARIABLE } F OLLOW (clause tail helper) = F OLLOW (clause tail) = F OLLOW (clause ext) = {EN DZEICHEN } F IRST (clause tail helper) = F IRST (clause log op) = {KOM M A, SEM IKOLON } F IRST (clause tail element) = {IDEN T IF IER} F IRST (clause tail element) = F IRST (clause math f unc) = F IRST (clause operand) = F IRST (clause term op) = {CON ST AN T, V ARIABLE } F IRST (clause math f unc) = F IRST (clause operand) = F IRST (clause term op) = {CON ST AN T, V ARIABLE } F IRST (clause operand) = F IRST (clause term op) = {CON ST AN T, V ARIABLE } F OLLOW (clause operation) = F OLLOW (clause operand) = {REL OP ERAT OR} F OLLOW (clause math f unc) = {REL OP ERAT OR} F OLLOW (clause tail element) = {REL OP ERAT OR} F IRST (clause tail helper) F OLLOW (clause tail helper) = {REL OP ERAT OR, KOM M A, SEM IKOLON, EN DZEICHEN } F IRST (clause operation) = {M AT H OP ERAT OR} F IRST (clause term op) = {CON ST AN T } F IRST (clause term op) = {V ARIABLE } F IRST (goal) = {IDEN T IF IER} F IRST (goal params) = F IRST (goal parameter) = {V ARIABLE, SY M BOL, ST RIN G} F IRST (goal list) = {V ARIABLE, SY M BOL, ST RIN G, LIST OP EN } F OLLOW (goal ptail) = F OLLOW (goal params) = {KLAM M ERZU } F IRST (goal ptail) = {KOM M A} F IRST (goal parameter) = {V ARIABLE } F IRST (goal parameter) = {SY M BOL} F IRST (goal parameter) = {ST RIN G} F IRST (goal parameter) = F IRST (goal list) = {LIST OP EN } F IRST (goal list) = {LIST OP EN } F IRST (goal listdescr) = {LIST CLOSE } F IRST (goal listdescr) = F IRST (goal listdescr2) = F IRST (goal parameter) = {V ARIABLE, SY M BOL, ST RIN G} F IRST (goal list) = {V ARIABLE, SY M BOL, ST RIN G, LIST OP EN } F IRST (goal listdescr2) = F IRST (goal parameter) = {V ARIABLE, SY M BOL, ST RIN G} F IRST (goal list) = {V ARIABLE, SY M BOL, ST RIN G, LIST OP EN } F OLLOW (goal listdescr3) = F OLLOW (goal listdescr2) = {LIST CLOSE } F IRST (goal listdescr3) = {KOM M A}

98 99 100

Implementation

Der Parser wurde mit ex2.5.31 und bison 1.875 auf einem Debian-Unstable-System(x86-64) implementiert. Als Compiler kam der gcc 3.4.4 zum Einsatz. Da yacc eigentlich LALR-Parser generiert, k onnte die gestellte Aufgabe auch mit einer Grammatik abgedeckt werden, welche um einige Nicht-terminale Symbole reduziert ist. Eine solche Grammatik w urde aber nicht mehr den Bedingungen einer LL(1)Grammatik gehorchen. Auf einem Debian-Stable-System(i686) mit ex und bison mit dem gcc 3.3 traten einige Schwierigkeiten auf. Dort wurde anscheinend nicht korrekt gelinkt, so das der Parser keine Fehler erkannte und eine Eingabedatei trotz Fehler als korrekt klassizierte. Eine Ursache f ur das Problem

FH Schmalkalden

konnte aus Zeitgr unden nicht ermittelt werden. Die Quellen und das Makele nden sich im Anhang an dieses Dokument.

6.1

Der Scanner

Der Scanner hat die Aufgabe, den Eingabetext auf bekannte Muster hin zu analysieren und f uhrt dadurch schon eine erste Pr ufung durch. Findet der Scanner nun ein Muster, welches i.d.R. als regul arer Ausdruck angegeben wird, so gibt er ein Token an den Parser zur Weiterverarbeitung. Um Visual-Prolog-Regeln zu erkennen, sind die in folgender Tabelle aufgef uhrten Muster notwendig. In der zweiten Spalte sind auch die zugeh origen Token gelistet, welche in der hier vorliegenden Realisierung zum Einsatz kommen. RegExp \n \%.+\n ([d|D][o|O][m|M][a|A][i|I][n|N][s|S]) ([f|F][a|A][c|C][t|T][s|S]) ([p|P][r|R][e|E][d|D][i|I][c|C][a|A][t|T][e|E][s|S]) ([c|C][l|L][a|A][u|U][s|S][e|E][s|S]) ([g|G][o|O][a|A][l|L]) ([n|N][o|O][n|N][d|D][e|E][t|T][e|E][r|R][m|M]) ([d|D][e|E][t|T][e|E][r|R][m|M]) ([n|N][o|O][c|C][o|O][p|P][y|Y]) ([s|S][i|I][n|N][g|G][l|L][e|E]) [a-z][a-zA-Z]*/\( IDENTIFIER [A-Z][a-zA-Z]* [a-zA-Z] , \; \( \) \[ \] \| :[<|>|<>|<=|>=|=] [0-9]+ \[a-zA-Z]+\ [\+|-|\*|\/] \. Token

IDENT DOMAINS IDENT FACTS IDENT PREDICATE IDENT CLAUSES IDENT GOAL NONDETERM DETERM NOCOPY SINGLE VARIABLE SYMBOL KOMMA SEMIKOLON KLAMMERAUF KLAMMERZU LISTOPEN LISTCLOSE LISTCUT UNDERSCORE TRENNZEICHEN REL OPERATOR CONSTANT STRING MATH OPERATOR ENDZEICHEN

6.2

Die Syntaxanalyse

Das Yacc-Programm als eigentliches Herzst uck des Parsers implementiert die oben angegebene Grammatik und stellt damit die eigentliche Funktion zur Syntaxpr ufung zur Verf ugung. Zur besseren Ausgabe des Fehlers gibt es noch eine selbstimplementierte yyerror-Routine, diese gibt die ungef ahre Stelle des Fehlers und die Zeilennummer aus. Diese ist allerdings in der vorliegenden Version auskommentiert, da bison damit anscheinend nicht der ISO-yacc Implementierung der Schnittstelle folgt.

Erweiterungsmo glichkeiten

Die vorliegende L osungsm oglichkeit bietet noch ein weites Potential zum Ausbau, das allerdings den gesteckten Zielrahmen bei weitem u urde. Folgende Erweiterungen und Verbesserungen berschreiten w w aren denkbar:

10

Softwaredokumentation

Bei gefundenem Fehler kein Programmabbruch, Sammeln des Fehlers und Anzeigen einer Liste aller gefundenen Fehler nach Programmende. Erkennung und Pr ufen aller Schl usselw orter aus Bibliotheken, welche mit Visual-Prolog geliefert werden.

scanner.l

%{ #include <stdio.h> int actLine = 1; %} letter [a-zA-Z] smallCaps [a-z] bigLetters [A-Z] numbers [0-9] %% \n { actLine++; printf("\n%d : ",actLine); /* return(NEWLINE); */ }; "%".+\n { actLine++; printf("KOMMENTAR ENTFERNT \n%d :", actLine); }; ([p|P][r|R][e|E][d|D][i|I][c|C][a|A][t|T][e|E][s|S]) { printf("KEYWORD %s ", yytext); return(IDENT_PREDICATE); }; ([n|N][o|O][n|N][d|D][e|E][t|T][e|E][r|R][m|M]) { printf("KEYWORD %s ", yytext); return(NONDETERM); } ([d|D][e|E][t|T][e|E][r|R][m|M]) { printf("KEYWORD %s ", yytext); return(DETERM); }; ([n|N][o|O][c|C][o|O][p|P][y|Y]) { printf("KEYWORD %s ", yytext); return(NOCOPY); }; ([s|S][i|I][n|N][g|G][l|L][e|E]) { printf("KEYWORD %s ", yytext);

FH Schmalkalden

11

return(SINGLE); }; ([c|C][l|L][a|A][u|U][s|S][e|E][s|S]) { printf("KEYWORD %s ", yytext); return(IDENT_CLAUSES); }; ([g|G][o|O][a|A][l|L]) { printf("KEYWORD %s ", yytext); return(IDENT_GOAL); }; ([d|D][o|O][m|M][a|A][i|I][n|N][s|S]) { printf("KEYWORD %s ", yytext); return(IDENT_DOMAINS); }; ([f|F][a|A][c|C][t|T][s|S]) { printf("KEYWORD1 %s ", yytext); return(IDENT_FACTS); };

{smallCaps}{letter}*/\( { printf("IDENTIFIER %s ",yytext); return(IDENTIFIER); }; {bigLetters}{letter}* { printf("VARIABLE %s ",yytext); return(VARIABLE); }; {letter}+ { printf("SYMBOL %s ", yytext); return(SYMBOL); }; "," { printf("KOMMA %s ",yytext); return(KOMMA); }; ";" { printf("SEMIKOLON %s ", yytext); return(SEMIKOLON); }; "(" { printf("KLAMMERAUF %s ",yytext); return(KLAMMERAUF); }; ")" {

12

Softwaredokumentation

printf("KLAMMERZU %s ",yytext); return(KLAMMERZU); }; "[" { printf("LISTOPEN %s ",yytext); return(LISTOPEN); }; "]" { printf("LISTCLOSE %s ",yytext); return(LISTCLOSE); }; "|" { printf("LISTCUT %s ",yytext); return(LISTCUT); }; "_" { printf("UNDERSCORE %s ",yytext); return(UNDERSCORE); }; ":-" { //yyless(0); //BEGIN CLAUSE_TAIL; printf("TRENNZEICHEN %s ",yytext); return(TRENNZEICHEN); }; [<|>|<>|<=|>=|=] { printf("REL_OPERATOR %s ",yytext); return(REL_OPERATOR); }; [0-9]+ { printf("CONSTANT %s ",yytext); return(CONSTANT); }; [\+|-|\*|\/] { printf("MATH_OPERATOR %s ",yytext); return(MATH_OPERATOR); };

"." { printf("ENDZEICHEN %s ",yytext); return(ENDZEICHEN); }; \"{letter}+\" { printf("STRING %s ", yytext); return(STRING); };

FH Schmalkalden

13

. ; %% int yywrap() { //fclose(fpointer); printf("\n<<OK>>\n"); return(1); }

parser.y

%token IDENTIFIER KLAMMERAUF KLAMMERZU ENDZEICHEN KOMMA TRENNZEICHEN LISTOPEN LISTCLOSE VARIABLE UNDERSCORE LISTCUT REL_OPERATOR MATH_OPERATOR CONSTANT STRING IDENT_PREDICATE IDENT_CLAUSES IDENT_GOAL NONDETERM SEMIKOLON SYMBOL IDENT_DOMAINS IDENT_FACTS DETERM NOCOPY SINGLE %start program %% /* * Einleitungsblock, konstruiert komplettes Prolog-Programm * aus den Teilen DOMAINS, PREDICATES, CLAUSES, GOAL */ program ; : domain_part facts_part predicates_part clauses_part goal_part

/* DOMAINS und FACTS Teil sind alternativ */ domain_part : /*leer*/ | IDENT_DOMAINS domains ; facts_part : /*leer*/ | IDENT_FACTS facts ; predicates_part : IDENT_PREDICATE predicates ; clauses_part : IDENT_CLAUSES clauses ; goal_part : IDENT_GOAL goal ; /* * Ende Einleitungsblock */

14

Softwaredokumentation

/* * parse-Regeln f ur DOMAINS-Part */ domains : domain domain_helper ; domain_helper : /*leer*/ | domains ; domain : new_domain REL_OPERATOR built_in_domain ; new_domain : SYMBOL new_domain_helper ; new_domain_helper : /*leer*/ | KOMMA new_domain ; built_in_domain : SYMBOL domain_list_op ; domain_list_op : /*leer*/ | MATH_OPERATOR ; /* * Ende Parser f ur DOMAINS */ /* * Parser-Teil fuer FACTS */ facts : fact fact_helper ; fact_helper : /*leer*/ | facts ; fact : fact_global IDENTIFIER KLAMMERAUF fact_params KLAMMERZU ; fact_global : /*leer*/ | NONDETERM | DETERM | SINGLE | NOCOPY ; fact_params : fact_param fact_param_helper ; fact_param_helper : /*leer*/

FH Schmalkalden

15

| KOMMA fact_params ; fact_param : SYMBOL fact_param_name ; fact_param_name : /*leer*/ | VARIABLE ; /* * Ende Parser-Teil FACTS */ /* * parse-rules for PREDICATES-section */ predicates : predicate pred_helper ; pred_helper : /*empty*/ | predicates ; predicate : nondeterm IDENTIFIER KLAMMERAUF pred_params KLAMMERZU pred_ende ; nondeterm : /*leer*/ | NONDETERM ; pred_ende : /**/ | ENDZEICHEN ; pred_params : pred_param pred_param_helper ; pred_param_helper : /**/ | KOMMA pred_params ; pred_param : SYMBOL pred_param_name ; pred_param_name : /**/ | VARIABLE ; /* * Ende des Parsers fuer PREDICATES */ /* * parse-rules for CLAUSES-section

16

Softwaredokumentation

*/ clauses ; : clause clause_help

clause_help : /*empty*/ | clauses ; /* * Grunds atzlicher Aufbau einer Regel im Clause-Teil */ clause ; : IDENTIFIER KLAMMERAUF clause_or_fact

clause_or_fact : clause_params KLAMMERZU clause_ext ENDZEICHEN | clause_facts KLAMMERZU ENDZEICHEN ; clause_ext : /*leer*/ | TRENNZEICHEN clause_tail ;

/* * Parameterteil der clauses parsen */ clause_params : clause_phead clause_ptail ; /**/ clause_ptail : /*leer*/ | KOMMA clause_params ; clause_facts : clause_fact clause_fact_helper ; clause_fact_helper : /*leer*/ | KOMMA clause_facts ; clause_fact : SYMBOL | STRING ; clause_log_op : KOMMA | SEMIKOLON ; /**/ clause_phead : VARIABLE | clause_list ;

FH Schmalkalden

17

/* * Syntax einer Liste parsen */ clause_list : LISTOPEN clause_listdescr ; clause_listdescr : LISTCLOSE | clause_listdescr2 LISTCLOSE ; /**/ clause_listdescr2 : VARIABLE clause_listdescr3 | UNDERSCORE LISTCUT VARIABLE ; clause_listdescr3 : LISTCUT clause_listdescr4 ; clause_listdescr4 : VARIABLE | UNDERSCORE ; /* * parsing the part after :- from a clause */ clause_tail : clause_tail_element clause_tail_helper ; /**/ clause_tail_helper : /*empty*/ | clause_log_op clause_tail ; /* * jeder Teil einer Klausel ab dem :- Operator kann entweder wieder ein * Praedikat mit entsprechenden Parametern sein, oder ist ein arithmetischer * oder logischer Ausdruck */ clause_tail_element : IDENTIFIER KLAMMERAUF clause_params KLAMMERZU | clause_math_func ; /**/ clause_math_func : clause_operand REL_OPERATOR clause_operand ; /**/ clause_operand ;

: clause_term_op clause_operation

/**/ clause_operation: /*epsilon*/ | MATH_OPERATOR clause_operand ;

18

Softwaredokumentation

clause_term_op | VARIABLE ;

: CONSTANT

/* * here ends the parsing from CLAUSES-section */ /* * Begin Parser fuer GOAL-Teil */ goal ; /* * Parameterteil Goals parsen */ goal_params : goal_parameter goal_ptail ; /**/ goal_ptail : /*leer*/ | KOMMA goal_params ; /**/ goal_parameter : VARIABLE | SYMBOL | STRING | goal_list ; /* * Syntax einer Liste von GOAL parsen */ goal_list : LISTOPEN goal_listdescr ; goal_listdescr : LISTCLOSE | goal_listdescr2 LISTCLOSE ; /**/ goal_listdescr2 : goal_parameter goal_listdescr3 ; goal_listdescr3 : /*empty*/ | KOMMA goal_listdescr2 ; /* * Ende Parser Goal-Teil */ : IDENTIFIER KLAMMERAUF goal_params KLAMMERZU ENDZEICHEN

FH Schmalkalden

19

%% #include "lex.yy.c" /*void yyerror(char *s) { printf("\nSyntax Error in Line %d near Symbol \"%s\"\n", actLine, yytext); }*/

Makele

# # Makefile # all: projekt projekt: lex scanner.l yacc parser.y cc -o parser y.tab.c -ly -ll clean: rm parser rm *.c