Inhaltsverzeichnis

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: createWidget und createLayout geben unter allen Umständen 0 zurück, renderForm ebenso, und die Setter melden false, weil ihre erste Prüfung (wid == 0) immer zutrifft. Es gibt keine extern fn-Deklaration und keine link-Klausel; libqtlyx.so wird nirgends gebunden.

Zweiter Befund: Die Fallunterscheidungen im Quelltext (if (widgetType == "Button")) vergleichen bei pchar die Adressen, nicht den Inhalt — sie träfen also selbst dann nicht zu, wenn darunter etwas läge. Für Textvergleiche ist StrEquals zuständig.

Wer heute ein LFD-Formular anzeigen will, geht den Weg unten: mit std.lfd_parser parsen 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_parser hat 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 in lfd-ebnf.md beschreibt Form Anmeldung "Login" { Layout Vertical { … } } — der Parser erwartet dagegen form { 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


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).