std.lfd_factory
Vorgesehene Widget-Factory für LFD-Formulare: Sie soll den von std.lfd_parser gelieferten Syntaxbaum in echte Bedienelemente übersetzen (laut Quellkommentar über libqtlyx.so).
→ std.lfd_parser · Standard Library · std.qt5_core
Alle Beispiele dieser Seite sind mit lyxc 1.0.21A übersetzt und ausgeführt; die gezeigten Ausgaben sind echte Programmausgaben.
Diese Unit ist eine leere Hülle — sie erzeugt keine Widgets. Jede Funktion übersetzt, keine tut etwas:createWidgetundcreateLayoutgeben unter allen Umständen0zurück,renderFormebenso, und die Setter meldenfalse, weil ihre erste Prüfung (wid == 0) immer zutrifft. Es gibt keineextern fn-Deklaration und keinelink-Klausel;libqtlyx.sowird nirgends gebunden.
Zweiter Befund: Die Fallunterscheidungen im Quelltext (if (widgetType == "Button")) vergleichen beipchardie Adressen, nicht den Inhalt — sie träfen also selbst dann nicht zu, wenn darunter etwas läge. Für Textvergleiche istStrEqualszuständig.
Wer heute ein LFD-Formular anzeigen will, geht den Weg unten: mitstd.lfd_parserparsen und den Baum selbst durchlaufen.
Der belegte Stand
import std.lfd_factory;
import std.string;
fn main(): int64 {
var w: int64 := createWidget("Button"c, 0);
PrintLn(StrConcat("createWidget(Button): ", IntToStr(w)));
PrintLn(StrConcat("setWidgetProperty: ", IntToStr(setWidgetProperty(w, "Text"c, "OK"c) as int64)));
var l: int64 := createLayout("Vertical"c);
PrintLn(StrConcat("createLayout(Vertical): ", IntToStr(l)));
PrintLn(StrConcat("addWidgetToLayout: ", IntToStr(addWidgetToLayout(l, w) as int64)));
return 0;
}
createWidget(Button): 0
setWidgetProperty: 0
createLayout(Vertical): 0
addWidgetToLayout: 0
Zum Adressvergleich, der die Verzweigungen der Unit wirkungslos macht:
import std.string;
fn main(): int64 {
var a: pchar := "Button"c;
var b: pchar := "Button"c;
PrintLn(StrConcat("a == b (Adressvergleich): ", IntToStr((a == b) as int64)));
PrintLn(StrConcat("StrEquals(a, b): ", IntToStr(StrEquals(a, b))));
return 0;
}
a == b (Adressvergleich): 0
StrEquals(a, b): 1
Was die Schnittstelle vorsieht
Die Signaturen beschreiben ein vollständiges Modell — sie sind der Bauplan, nach dem eine spätere Umsetzung arbeiten müsste.
| Signatur | Vorgesehene Aufgabe | Heutiger Rückgabewert |
|---|---|---|
createWidget(widgetType: pchar, parent: int64): int64 | Bedienelement des genannten Typs unter parent anlegen | immer 0 |
setWidgetProperty(wid, propertyName: pchar, value: pchar): bool | Texteigenschaft setzen | immer false |
setWidgetIntProperty(wid, propertyName: pchar, value: int64): bool | Zahleneigenschaft setzen | immer false |
createLayout(layoutType: pchar): int64 | Anordnung anlegen | immer 0 |
addWidgetToLayout(lay: int64, wid: int64): bool | Element in eine Anordnung hängen | immer false |
setLayoutOnWidget(wid: int64, lay: int64): bool | Anordnung an einem Element setzen | immer false |
bindEvent(wid, eventName: pchar, handler: pchar): bool | Ereignisbehandler verbinden | immer false |
renderForm(parser: int64): int64 | Fertigen Syntaxbaum in ein Fenster übersetzen | immer 0 |
parseAndRender(lfdSource: pchar): int64 | Quelltext parsen und anzeigen | immer 0 |
Die im Quelltext aufgezählten Werte — sie zeigen, welchen Umfang die Factory abdecken soll:
| Kategorie | Vorgesehene Werte |
|---|---|
| Widget-Typen | Button, Label, Input, Checkbox, RadioButton, ComboBox, SpinBox, Slider |
| Texteigenschaften | Text, Enabled, Visible, ToolTip, Placeholder |
| Zahleneigenschaften | Width, Height, Value, Min, Max |
| Anordnungen | Vertical, Horizontal, Grid |
| Ereignisse | OnClick, OnChange |
parseAndRender ist die einzige Funktion mit echtem Inhalt: Sie ruft LFDParserNew und LFDValidate aus std.lfd_parser und gibt bei einem Fehler die Meldung aus — danach landet sie in renderForm und damit bei 0.
Der Parser dagegen arbeitet.std.lfd_parserhat einen vollständigen Lexer und baut einen begehbaren Syntaxbaum. Alles, was auf dieser Seite fehlt, betrifft nur den Schritt vom Baum zum sichtbaren Fenster.
Der Weg, der heute funktioniert
Statt renderForm schreibt man den Durchlauf selbst. Der Baum ist klein: Knotentyp abfragen, Kinder zählen, absteigen. Was am Ende erzeugt wird — Qt-Fenster, Terminaloberfläche oder wie hier eine Textbeschreibung — entscheidet die eigene Funktion.
import std.lfd_parser;
import std.string;
// Eigener Renderer: statt Qt-Widgets erzeugt er eine Textbeschreibung.
// Genau diese Rolle hätte std.lfd_factory - solange sie leer ist, schreibt
// man den Durchlauf selbst.
fn Einzug(t: int64): pchar {
var s: pchar := "";
var i: int64 := 0;
while (i < t) { s := StrConcat(s, " "); i := i + 1; }
return s;
}
fn Rendere(node: int64, tiefe: int64): void {
var typ: int64 := LFDGetNodeType(node);
var kinder: int64 := LFDGetNodeChildCount(node);
if (typ == LFD_TK_FORM) { PrintLn(StrConcat(Einzug(tiefe), "Fenster")); }
if (typ == LFD_TK_VERTICAL) { PrintLn(StrConcat(Einzug(tiefe), "senkrechte Box")); }
if (typ == LFD_TK_HORIZONTAL) { PrintLn(StrConcat(Einzug(tiefe), "waagerechte Box")); }
if (typ == LFD_TK_LABEL) { PrintLn(StrConcat(Einzug(tiefe), "Beschriftung")); }
if (typ == LFD_TK_INPUT) { PrintLn(StrConcat(Einzug(tiefe), "Eingabefeld")); }
if (typ == LFD_TK_BUTTON) { PrintLn(StrConcat(Einzug(tiefe), "Schaltflaeche")); }
if (typ == LFD_NODE_PROPERTY) {
PrintLn(StrConcat(StrConcat(Einzug(tiefe), "Eigenschaft = "), IntToStr(LFDGetNodeIntVal(node))));
}
var i: int64 := 0;
while (i < kinder) { Rendere(LFDGetNodeChild(node, i), tiefe + 1); i := i + 1; }
}
fn main(): int64 {
var quelle: pchar := "form { vertical { label \"Benutzer\" { } input \"\" { width: 200 } button \"Anmelden\" { width: 100 height: 30 } } }"c;
var root: int64 := LFDParseString(quelle);
if (root < 0) { PrintLn("Parse-Fehler"); return 1; }
Rendere(root, 0);
return 0;
}
Fenster
senkrechte Box
Beschriftung
Eingabefeld
Eigenschaft = 200
Schaltflaeche
Eigenschaft = 100
Eigenschaft = 30
Die tatsächlich geparste Syntax ist klein geschrieben und kennt keine Namen. Der Entwurf inlfd-ebnf.mdbeschreibtForm Anmeldung "Login" { Layout Vertical { … } }— der Parser erwartet dagegenform { vertical { button "OK" { width: 100 } } }. Großgeschriebene Schlüsselwörter und Bezeichner zwischen Typ und Titel führen zu-1. Wer sich an der Grammatikdatei orientiert, bekommt Parse-Fehler; maßgeblich ist heute der Parser.
Die Zuordnung Knotentyp → Bedeutung steht in std.lfd_parser: LFD_TK_FORM (0), LFD_TK_VERTICAL (2), LFD_TK_BUTTON (6), LFD_TK_LABEL (7), LFD_TK_INPUT (8) und so fort; Eigenschaftsknoten tragen LFD_NODE_PROPERTY (101), ihren Zahlwert liefert LFDGetNodeIntVal.
Wenn ein echtes Fenster gebraucht wird
| Weg | Wofür |
|---|---|
| std.qt5.app / std.qt5_core | Qt-Oberflächen direkt aus Lyx — der Weg, den die Factory eines Tages abkürzen soll |
| std.tui | Terminaloberflächen ohne Grafiksystem |
eigener Durchlauf über std.lfd_parser | Formularbeschreibung in beliebige Ziele übersetzen — auch in HTML, JSON oder eine Prüfausgabe |
Der Umweg über den Parser hat einen Vorteil: Die Formularbeschreibung bleibt frei von Zielsystem-Details, und derselbe Baum lässt sich für Tests in Text ausgeben und im Betrieb in Widgets übersetzen.
Offene Punkte
- Keine Bindung an
libqtlyx.so— es fehlt dieextern fn-Deklaration samtlink-Klausel (Pflicht seit lyxc 1.0.17C, #1179). - Die Fallunterscheidungen müssen von
==aufStrEqualsumgestellt werden, sonst greifen sie auch nach einer Umsetzung nicht. renderFormbekommt einenparser-Zeiger, benutzt ihn aber nicht; ein echter Durchlauf müssteLFDGetNodeChild/LFDGetNodeTypeverwenden — wie im Beispiel oben.- Die Widget-Liste der Factory (8 Typen) ist kleiner als die des Parsers (17 Typen, bis
TabWidget,Splitter,WebView); die Grammatikdatei nennt noch mehr. @descriptionder Unit lautet „LFD binary file writer„ — das beschreibt eine andere Aufgabe als der Code (Widget-Factory).
Weiterführend: std.lfd_parser — Lexer, Syntaxbaum, Fehlerbehandlung · Standard Library
Quelle: std/lfd_factory.lyx (82 Zeilen) · Autor: Andreas Röne · Copyright: 2024–2025 Andreas Röne
Letzte Aktualisierung: 2026-08-13 — Seite gegen std/lfd_factory.lyx neu geschrieben. Die alte Einleitung beschrieb einen „LFD-Binärformat-Erzeuger, der typisierte Felder serialisiert“ — die Unit ist eine Widget-Factory, und zwar eine leere: alle Rückgabewerte sind 0 bzw. false, nachgemessen mit lyxc 1.0.21A. Ergänzt: Beleg dazu, der Adressvergleich-Befund bei pchar, die vorgesehenen Typ-/Eigenschafts-/Ereignislisten, ein lauffähiger eigener Renderer über std.lfd_parser, die Abweichung zwischen lfd-ebnf.md und der geparsten Syntax sowie die offenen Punkte für eine Umsetzung.
Codebeispiele geprüft: gegen lyxc 1.2.5C übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die pub fn-Signaturen in aurum/std gehalten, 0 Abweichungen).
