Doch so ungefähr. Mit den Tokens und Tranchieren sehe ich genauso.
Dann müssen die Tokens eben gruppiert, umsortiert und in LotusScript konvertiert werden.
Ich möchte Formelsprachencode reinkopieren und unten kommt Skriptcode raus.
Wenn ich an bestehenden Notes-Datenbanken arbeite, kommt es des öfteren vor, dass ich Formelsprachen-Code durch Skriptcode ersetzen zu müssen. Ich glaub Glombi hat sich einmal ähnlich ausgedrückt.
Ich hab nix gegen Formelsprache. Es ist einfach nur so, dass es Sinn macht, um eine Anwendung zu "konsolidieren", d.h. halbherzig implementierte Features rausschmeissen oder User-fähig zu machen. Es kommt dann oft vor, dass ich Skriptcode brauche. Z.B. ein Fall wo ein Feld des öfteren die 32-K (oder whatever) Grenze überschreitet. Dieses Feld wird leider von ca. 9 verschiedenen Skripten in Formelsprache oder LotusScript gefüllt (nicht übertrieben). Ich möchte das Feld ab einer bestimmten Größe auf 2 oder mehr Felder aufteilen (Adressen, Adressen_1, etc.). Dafür muss ich aber den Prozess managen und dafür möchte ich erstmal allen Code, der dieses Feld füllt oder verändert in Skript umwandeln.
Ein anderer Fall für diesen Formelsprache-zu-Skcript-Prozess ist RichText-Handling. Das wurde früher oft mit Formelsprache gemacht. Aber seid Domino6 gibt es da offenbar stabil funktionierende Klassen. Dort wäre ich mit Skript auch flexibler.
Ziel ist es so ein (ein bischen anonymisiertes) Skript einzugeben:
_A := @DbLookup("Notes":"NOCACHE";"":"";"($aaa)";"AToc";"ATitle");
_Application:=@If(@IsError(_A); @Failure("Fehler Meldung !"); _A);
_B := @DbLookup("Notes":"NOCACHE";"":"";"($AVIEW)";"ADOC";"Admin");
_Server := @Name([Abbreviate];@Subset(@DbName;1));
_DB := @ReplaceSubstring( _B;"@CurrentServer";_Server);
_DbView := "($Server)";
_DbKey := _Application + "@CurrentServer";
_Res:= @DbLookup("": "NoCache"; "":_DB; _DbView; _DbKey; 2);
_Server1 := @Subset(@DbName;1);
_Fields := @ReplaceSubstring( _Res;"@CurrentServer";_Server1);
_SerienbrDB := @Left(@Right(_Fields;"||aDB#"); "||");
_DataFormulare := @DbLookup("": "NoCache"; "": _DB; "(aView)"; "A DB" ; "DataBerichte");
@If(@IsError(_DataFormulare) | _DataFormulare = "";@Do(
@Prompt([OK];"Fehler";"a meldung.");
@Return("")
);
"");
_EleFormular := @Sum(@DbLookup("": "NoCache"; "": _DB; "(aView)"; "AnDB" ; 2));
@If(_EleFormular > 1; @Do(
@Prompt([OK];"Fehler";"kind of meldung.");
@Return(""));
"");
_SerienFormulare := @Explode(@Left(@Right(_DataFormulare;"||BerichteFormulare#"); "||"); "$");
_a1 := @Left(@Right(_DataFormulare;"||Name1#"); "||");
_a2 := @Left(@Right(_DataFormulare;"||Name2#"); "||");
_SerienFormulare3 := @Explode(@Left(@Right(_DataFormulare;"||BerichteFormulare3#"); "||"); "$");
_Maske_1 := _Maske_1;
_Maske_2 := _Maske_2;
_Aktionen := _SerienFormulare3;
_antwort := @If( @Elements( _Aktionen ) = 1; _Aktionen; @Prompt([OKCANCELLIST] : [NoSort] ; "Ausführen von" ; "Bitte wählen sie ..." ; @Subset(_Aktionen ;1) ; _Aktionen ) ) ;
@If(_antwort = _a1;
@Do(
@Set("_Maske_1";@Left(@Right(_DataFormulare;"||Maske1#"); "||"));
@PostedCommand([FileOpenDatabase]; "" : _SomeDB ; "(Mainnavigator)" ; "" ; "" ; "");
@PostedCommand([Compose]; "" : _SomeDB ; _Maske_1)
);
_antwort = _a2;
@Do(
@Set("_Maske_2";@Left(@Right(_DataFormulare;"||Maske2#"); "||"));
@PostedCommand([FileOpenDatabase]; "" : _SomeDB ; "(Mainnavigator)" ; "" ; "" ; "");
@PostedCommand([Compose]; "" : _SomeDB ; _Maske_2)
);
"")
Und daraus LotusScript Code erzeugen.
Oder zumindest Teile davon übersetzen. Der Rest bleibt in Formelsprache stehen. Da ich das sowieso übertragen muß. Wäre zumindest eine Arbeitserleichterung.
Ich find das eine interessante Aufgabe.
Axel
Sehe ich nicht so. Das sind spezielle Commands mit einem gemeinsamen Command Interface.
Class CommandDBLookupSingle implements CommandLotusScriptGenerator {
// die alle mit set und get
StringBuffer tempDoc;
StringBuffer dbVariable;
StringBuffer vwVariable;
StringBuffer docKeyVariable;
StringBuffer fieldVariable;
StringBuffer resValue;
// in Interface definiert
public StringBuffer execute() {
StringBuffer retVal = new StringBuffer(60);
retVal = tempDoc.append("=").append(dbVariable).append(".getDocumentByKey(").append(docKeyVariable).append()).append("\n")
.append(resValue).append("=").append(tempDoc).append("getItemValue(").append(fieldVariable).append(")").append("(0)");
}
}
Ziemlich naiv. Aber so die Richtung. Für jeden Formelsprachenbefehl muss man natürlich mehrere Command-Objekte erstellen.
Axel
Ich habe nun in einer Art Vorverarbeitungsschritt Code, das einlaufende Formelsprachescript wie folgt verarbeitet:
- Es wird zerschnitten und in eine ArrayListe geschrieben (dynamischer Array). Die Regel ist, dass
bei ; getrennt wird, wenn dieses ; nicht
- innerhalb eines Stringliterals oder
- in einer Klammer steht.
Zusätzlich wird noch aller Whitespace ausserhalb von StringLiteralen entfernt und
alles ausserhalb von Stringliteralen toLowerCase gesetzt.
Um den Unit-Test zu zitieren:
AUS
input=_A := @DbLookup("Notes":"NOCACHE";"":"";"($aaa)";"AToc";"ATitle");
_Application := @If( @IsError(_A);@Failure("Fehler Meldung !");_A);
WIRD
res=[_a:=@dblookup("Notes":"NOCACHE";"":"";"($aaa)";"AToc";"ATitle");, _application:=@if(@iserror(_a);@failure("Fehler Meldung !");_a);]
Man beachte den Whitespace und das toLowerCase Zeugs.
Das kann natürlich nur ein vorbereitender, normalisierender Schritt sein.
Als nächstes geht es darum die einzelnen Formeln, Commands und Variablenzuweisungen sinnvoll in einen Objektbaum zu bringen, der das ganze verarbeitbar macht. Das ist der eigentlich schwierige Teil der Herausforderung und ich arbeite arbeitet daran.
Im Namen von hilarious overengineering werde ich später noch das Filterzeugs hin zu Observer-Pattern refaktorieren. Ist aber erstmal nicht notwendig.
Melde das dann.
Verwendete Libraries: JDK1.4.1, junit
Axel
gerade an der Stelle, wo Du jetzt offensichtlich bist, vergiss bitte auch derartige Konstrukte nicht:
- @Do
- @ For
- @While
- @Return (vor allem, wenn dessen Folge ein Formelabbruch ist)
Was machst Du mit FrontEnd-Elementen (@Prompt, @Commands usw.) ?
Das sind Spezialfälle von oben b) FormelToken (hier eine Menge konkrete Klassen)
Es geht mir ja nun erst einmal darum den FormelCode in eine Art Baum zu konvertieren. Das geht auch mit den obigen Befehlen.
Gleiches gilt für @Prompt. @Commands sehe ich - wie oben angemerkt - als eigenen Subtyp von Token mit mehreren konkreten Unterklassen. Pro Command eins. Die kann man auch im Baum darstellen und mit LotusScript Code darstellen.
Sobald das mit dem Baum einigermassen läuft, kann ich ein Diagramm posten, der die Idee vielleicht ein bischen deutlicher ist.
Könntest Du in irgendeiner Form die Diskussion auch programmierspachenunabhängig publizieren ?
Die Diskussion ist in einem ziemlich hohen Grade programmiersprachenunabhängig. Ich verwende nur ziemlich viel GoF Pattern-Sprache, weil ich das eben in mein Denken über Programmierprobleme integriert habe. Dies schlägt sich natürlich auch im Code wieder (von wegen Mitarbeit). Thomas, vermutlich Jens und vielleicht der eine oder andere Student können es vielleicht so nachvollziehen. Auf der anderen Seite bietet es mir die Möglichkeit, meine Ideen kurz auszudrücken und das ist was ich will. Mit langatmigen Erklärungen ohne aus meiner Sicht effiziente GoF Pattern Fachbegriffe würde der Text sehr lang und mißverständlich werden. Und zwar einfach, weil das eine komplexe Aufgabe ist.
GoF sind keine spezifischen Java Ideen, sondern sie sind programmiersprachenunabhängig mit Delphi und C++-Beispielen entwickelt worden finden auch in anderen Programmiersprachen starkes Interesse.
Google-Links:
http://www.google.de/search?hl=de&q=C%23+Gof&btnG=Google-Suche&meta=
http://farm.tucows.com/blog/Languages/Python/_archives/2005/3/28/485818.html
Ich erwarte zum momentanen Zeitpunkt keine großartige Mitarbeit. Sobald ich das äußere Framework fetgezurrt habe, kann es klarer werden. Ich verwende Java, da es mir effizient für diese Aufgabe erscheint. Ich bin tagsüber auch in Notes4 basierten Projekten involviert. Ich hoffe, dass das Framework einen so festen Rahmen vorgibt, dass auch Leute ohne großartige Java-Kenntnisse einen Beitrag leisten könnnen, falls sie Interesse haben. Nur ist das jetzt eben das grundlegende Framework und das find ich selbst relativ heavy.
Wenn das Framework fertig ist, kann ich das aus der Rückschau auch einfacher ohne GoF-Sprache erklären. Nur aus der Vorschau - wenn man selbst noch eine Menge Unklarheiten hat - ist es schwierig.
Gruß Axel
@Sort(list; [CUSTOMSORT]; @ToNumber(@Trim(@Rightback($A; " - "))) > @ToNumber(@Trim(@RightBack($B; " - "))))
Diese Formel sortiert die folgende Liste
Billy Ray -- 10
Johnnie Lightning -- 37
Elvis Cantebury -- 9
Chief Wiggum -- 13
Angela King -- 6
Mary Ford -- 27
in dieser Reihenfolge:
Angela King -- 6
Elvis Cantebury -- 9
Billy Ray -- 10
Chief Wiggum -- 13
Mary Ford -- 27
Johnnie Lightning -- 37
da wird bestimmt interessanter Skriptcode draus ;D
Quelle: http://advisorupdate.info/Articles.nsf/nl/16642