Beispiele, Grammatik und Semantische Probleme der Anfragesprache fuer das CSLIB-System Status: Arbeitsunterlage bei der Entwicklung. KEINE verbindliche Spezifikation! Adressaten: Entwickler der Anfragesprache und Suchmaschine und zukuenftige Anwender der Anfragesprache, welche sich ueber den aktuellen Stand informieren wollen (um eventuell das schlimmste noch zu verhindern:-). Anderuengen: 19.12.95 Grammatik neu angefangen Datentypen fuer attributierten Strukturbaum angefangen 15.12.95 Nullwerte erweitert 13.12.95 Erste Version Anmerkungen, Fragen usw. an pumuckel@cs.tu-berlin.de (Holger Westphal). ============================================================================== Beispiele --------- use 'CSLIB.IFB'. % Importiere Modul fuer IFB-Bestand use 'CSLIB.UB'. % Importiere Modul fuer UB-Bestand use 'CSLIB.UB-IFB'. % Modul, welches UB und IFB vereinheitlicht use 'CSLIB.Berlin'. % Modul, welches Bibliothen in Berlin vereinheitlicht define antwort1 ni D <<- D in dokument(dokumentart('Kongressband')). redefine antwort1 = set of D where D in dokument(dokumentart('Kongressband')). redefine antwort1 = dokument(dokumentart('Kongressband')). cache antwort1. uncache antwort1. set of (autoren: autor(D), titel: titel(D)) where D in dokument, erscheinungsjahr(D) > 1990. set of (autoren: (set of (vorname: vorname(A), nachname: nachname(A)) where A in autor(D)), titel: titel(D)) where D in dokument, titel(D) in ?'*[Dd]atenbank*'. set of (autoren: (list of (nachn: nachname(A), stellung: stellung(A,D)) where A in autor(D) ordered by [(>,stellung)]), titel: titel(D)) where D in dokument, titel(D) in ?'*[Dd]atenbank*'. ranklist of antwort1 ranked by D @ erscheinungsjahr(D) > 1990, wort('Datenbank') in wort(abstract(D)). ranklist of (titel: titel(D), dok: D) where D in antwort1 ranked by X @ erscheinungsjahr(dok(X)) > 1990, wort('Datenbank') in wort(abstract(dok(X))). list of antwort1 ordered by [(>,erscheinungsjahr),(<,erscheinungsmonat)]. list of (titel: titel(D), dok: D) where D in antwort1 ordered by [(>,X @ erscheinungsjahr(dok(X)))]. list of (ti: titel(D), py: erscheinungsjahr(D)) where D in antwort1 ordered by [(>,X @ py(X))]. DML (optional) -------------- for a new person do ( P @ (assert nachname(P) = 'Haller', vorname(P) = 'Klaus')). for a new person do ( P @ (assert nachname(P) = 'Popst', vorname(P) = 'Hans')). for a new dokument do ( D @ (assert titel(D) = 'Katalogisierung nach den RAK-WB', (for a new isbn do I @ (assert nummer(I) = '3-598-10926-2')) in isbn(D), % (a new isbn('3-598-10926-2')) in isbn(D), the person('Klaus','Haller') in autor(D), the person('Hans','Popst') in autor(D))). for the (D where D in dokument, the isbn('3-598-10926') in isbn(D)) do D @ (assert ifbKlassifikation('53q345') in klassifikation(D)). for (set of D where D in dokument, dokumentart(D) = dokumentart('Fakyr')) do D @ (assert titel(D) = cslibEncoding(titel(D))) to assert titel(D as dokument) = T do sqlSetChar(D,`titel,new(T)). to new isbn(I as int) do X @ (X = sqlNewTupleBySerial(`isbn,`id), assert nummer(X) = I). Zeichenfolge, welche ein Wort der Sprache repraesentiert (Reader) ----------------------------------------------------------------- Der Anwender uebergibt die Anfrage als Folge von Zeichen in einem bestimmten Zeichensatz. Jedem Zeichen kann durch eine Adresse eine eindeutige Position in der Zeichenfolge zugeordnet werden. Das Adressierungsschema kann von Anwendung zu Anwendung variieren (z.B. (Zeile,Spalte), (Index)). Zeichen, welche nicht im Zeichensatz des Anwenders darstellbar sind, werden durch eine (mnemotechnische) Ersatzdarstellung referenziert (Adressierung solcher 'komplexen' Zeichen in der Zeichenfolge?), welche aus mehreren Zeichen aus dem Zeichensatz besteht, den der Anwender benutzt. Alle Zeichen und Ersatzdarstellungen werden entsprechend einer Konvertierungsfunktion in die interne Repraesentation des Zeichens, welches sie bedeuten, uebersetzt. Beispiel (der Anwender kann z.B. nur ASCII-Texte eingeben): set of D where D in sch&o:neLiteratur, "M&u:ller" in autorenNachnamen(D) Korrespondierende Zeichenliste: [character(0x73,'s',smallLetter,rowCol(1,1)), ..., character(0xf6,'&o:',smallLetter,rowCol(2,11)), ...] ?-defvariant(characterLocation,[ rowCol(line,column), index(position), noLocation]). ?-defvariant(characterClass,[ smallLetter, capitalLetter, graphic, digit, whiteSpace]). ?-defstruct(character( unicode, cslibEncoding, class -: characterClass, position -: characterLocation)). Probleme: Die Bestimmung der Zeichenklasse (SmallLetter, CapitalLetter, Graphic, ...) fuer den Scanner wird sehr aufwendig (Ist ein 'Lambda' nun ein Graphics oder ein CapitalLetter? Was sind alles White-Spaces?) Regulaerer Teil der Grammatik von QueRist (Scanner) --------------------------------------------------- (Wird angewendet auf Zeichenfolge.) Name --> SmallLetter, OptionalLetterOrDigitOrUnderlineSeq. %Name --> Graphic, OptionalGraphicOrLetterOrDigitSeq. Name --> "'", MetaSinglequotedSeq, "'". VarName --> CapitalLetterOrUnderLine, OptionalLetterOrDigitOrUnderlineSeq. Symbolic --> Graphic, OptionalGraphicOrLetterSeq. %Operator --> NameOrSymbolic(Name),{optable(Name,Type,Asso,Prio)}. % Diese allgemeine Repraesentation von Operatoren verhindert vermutlich % den Einsatz eines Parser-Generators. Deshalb 3 Tokenklassen: PrefixOperator --> NameOrSymbolic(Name),{optable(Name,prefix,Asso,Prio)}. InfixOperator --> NameOrSymbolic(Name),{optable(Name,infix,Asso,Prio)}. PostfixOperator --> NameOrSymbolic(Name),{optable(Name,postfix,Asso,Prio)}. % Die Beachtung der Assoziativitaeten und Prioritaeten wuerde eine % nachtraegliche Analyse und ggf. Transformation des Ableitungsbaumes % notwendig machen. Problem: als Operatoren definierte Namen oder Symbole % werden nur noch als Operatoren erkannt. Um sie gleichzeitig als Namen oder % Symbole verwenden zu koennen, muss es zwei Arten von quotierten % Token geben: Namen UND Symbolics. Dann kann man aber nichts als % Namen verwenden, was auch Graphics enthaelt. StringLiteral --> """", OptionalMetaDoublequotedSeq, """". IntLiteral --> DigitSeq(Literal). FloatLiteral --> DigitSeq,".",DigitSeq,OptionalExponent. ?-defvariant(qrToken,[ name(value,begin,end), varname(value,begin,end), symbolic(value,begin,end), % operator(value,type,associativity,priority,begin,end), s.o. prefixOperator(value,associativity,priority,begin,end), infixOperator(value,associativity,priority,begin,end), postfixOperator(value,associativity,priority,begin,end), stringliteral(value,begin,end), intliteral(value,begin,end), floatliteral(value,begin,end)]). Token --> Name. Token --> VarName. Token --> Symbolic. Token --> Operator. Token --> StringLiteral. Token --> IntLiteral. TokenSeq --> Token, OptionalWhiteSpace, TokenSeq. TokenSeq --> []. Kontextfreier Teil der Grammatik von QueRist (Struktur-Parser) -------------------------------------------------------------- (Wird angewandt auf Ergebnis von TokenSeq = Liste von Token.) TopLevel --> Expression. Expression --> SetOf. Expression --> ListOf. Expression --> [symbolic('(')],Expression,[symbolic(')')]. Expression --> Name. Expression --> Variable. Expression --> Application. %Expression --> PrefixApplication. %Expression --> InfixApplication. %Expression --> PostfixApplication. %Expression --> Concatenation. % fuer Zeichenmasken Expression --> StringLiteral. Expression --> IntLiteral. Expression --> FloatLiteral. Expression --> SetConstruction. Expression --> ListConstruction. Expression --> TupleConstruction. Expression --> WithinEval. SetOf --> [name(set),name(of)],Lambda. ListOf --> [name(list),name(of)],Lambda,[name(ordered),name(by)],SortSpec. Lambda --> VarTuple,[name(where)],Formula. Formula --> [name(exists)],VarTuple1,[name(such),name(that)],Formula. Formula --> [name(for),name(all)],VarTuple1,[name(holds)],Formula. Formula --> Formula1,Disjunctor,Formula. Formula --> Formula1. Formula1 --> Formula2,Konjunctor,Formula1. Formula1 --> Formula2. Formula2 --> Negator,Atom. Formula2 --> Atom. Formula2 --> [symbolic('(')],Formula,[symbolic(')')]. Atom --> Term,[name(in)],ApplicationOrName. % Term Atom --> Term,[name(is)],ApplicationOrName. % Term Term --> Expression. Name --> [name(Name)]. Name --> [name(Name),symbolic(':')],TypExpression. Name --> [name(ModuleName),symbolic('::'),name(Name)]. Name --> [name(ModuleName),symbolic('::'),name(Name),symbolic(':')], TypeExpression. Variable --> [varname(Name)]. Application --> Name,TupleConstruction. StringLiteral --> [stringLiteral(String)]. % Zeichensatz cslibEncoding IntLiteral --> [intLiteral(Int)]. FloatLiteral --> [floatLiteral(Float)]. SetConstruction --> [symbolic('{')],OptionalExpressionList,[symbolic('}')]. ListConstruction --> [symbolic('[')],OptionalExpressionList,[symbolic(']')]. TupleConstruction --> [symbolic('(')],LabeledExpressionList,[symbolic(')')]. OptionalExpressionList --> Expression,ExpressionList1. OptionalExpressionList --> []. ExpressionList1 --> [symbolic(',')],Expression,ExpressionList1. ExpressionList1 --> []. LabeledExpressionList --> LabeledExpression,LabeledExpressionList1. LabeledExpressionList1 --> [symbolic(',')],LabeledExpressionList1. LabeledExpressionList1 --> []. LabeledExpression --> Label,[symbolic(':')],Expression. TypeExpression --> Name. % TypeName ? TypeExpression --> [symbolic('(')],LabeledTypeList,[symbolic(')')]. TypeExpression --> [symbolic('(')],TypeExpression,[symbolic(')')]. WithinEval --> [name(within)],EnvSpec,[name(eval)],Expression. (Nachteil der Realisierung als Backtracking-Parser (PROLOG): keine spezifischen Fehlermeldungen moeglich, ineffizient, keine Kontrolle der Grammatik. Alternative: Yacc-Kompilat erzeugt Strukturbaum.) Attributierte Grammatik von QueRist mit Kontextbedingungen ---------------------------------------------------------- (Ich schlage vor: Trennung von kontextfreier Parsierung und Attributauswertung. Vorteil: Die Erzeugung des Strukturbaumes kann von verschiedenen Quellen aus erfolgen (WWW-Interface, Prolog-Reader, effizienter Yacc-Parser) und die Ueberfuehrung in abstrakte Syntax braucht nur einmal implementiert werden -> Modularitaet. Nachteil: Konsistenzsicherung zwischen den Komponenten.). qrExpression( ptExpression@:setof @ [begin = Begin, end = End, lambda = Lambda], atExpression@:setof @ [begin = Begin, end = End, type = set(T)] ) -->@ !, qr(Lambda, qrExpression@:lambda @ [type = T2] ), check T2 = (T->bool). % check isFunctionType(T2,T,bool) % check isSetType(T1,T) Datentypen fuer attributierten Strukturbaum ------------------------------------------- (Zur Zeit gehoeren die Ableitungen der rechten Seite noch zu den Attributen.) ?-defvariant(queristExpression,[ name(name,object,module,type), variable(name,object,type), integer(value,type), float(value,type), string(value,type), term(value,type), set(expressions,type), list(expressions,type), tuple(components,type), setOf(lambda,type), orderedListOf(lambda,orderspec,type), rankedListOf(lambda,lambda,type), exist(varlist,expression,type), forAll(varlist,expression,type), application(expression,expressionlist,type) ]). Ablauf der Uebersetzung mit den skizzierten Zwischenstufen ---------------------------------------------------------- ?-doQueryFromString(ascii,'&',sset of ...",outStream). doQueryFromString(CharSet,EscapeChar,QueryString,OutStream /*,ErrorStream*/) :- newQueryId(Id), /* setErrorStream(ErrorStream) */ qrRead8bit(CharSet,EscapeChar,indexCharacters,sset of ...",Characters), qrScan(Characters,Tokens), qrParse(Tokens,Structure), % bis hierher durch eine effizientere Implementierung % oder durch beliebiges Frontend ersetzbar, welche(s) Structure liefert qrAttributes(Structure,AttributedStructure,Assertions), % Falls Structure bereits 'Leerstellen' fuer Attribute enthaelt, entfaellt % die Erzeugung von AttributedStructure qrSolveAttributes( /*AttributedStructure,*/ Assertions), % Berechnung der Attribute, Pruefung Kontexbed., Typisierung/Bindung qrIntermediate(AttributedStructure,Intermediate), % Vereinfachung der Struktur % qrGenerateRules(Intermediate,Rules,ResultType), % safe formulas? % qrRewriteRules(Rules,RewrittenRules), % Primitiven einsetzen % qrBuildBlocks(RewrittenRules,BlockRules), % Primitiven zusammenfassen (SQL) % qrSequenceBlocks(BlockRules,SequencedRules), % I/O-Parameter der Blocks % qrGenerateBlockCode(SequencedRules,ExecutableRules), % qrExecuteRules(Id,ExecutableRules,Result), % qrWriteResult(OutStream,Result,ResultType), qrClean(Id). % ... Alte Grammatik -------------- <- <- '.' | '.' | '.' | '.'. <- set(S)> | list((T,rank))> | list(T)> | T>. set(S)> <- set of bool> | set(S)> | set(S)>. list((T,rank))> <- ranklist of set(T)> ranked by relevanceDescription>. list(T)> <- list of set(T)> ordered by list(((S1,S1)->bool,T->S1),...). T> <- the bool> | the set(T)> | T>. bool> <- where bool|Var : S>. T> <- @ T|Var : S>. <- . <- . T> <- '(' T> ')'. (l:T)> <-