Benutzer-Werkzeuge

Webseiten-Werkzeuge


tinypg

Dies ist eine alte Version des Dokuments!


TinyPG

//@TinyPG - a Tiny Parser Generator v1.2
// Mini-Skriptsprache: print, Variablen, while

<% @TinyPG Language="C#" Namespace="MyScript" OutputPath="C:\Users\manuel.zarat\source\repos\ConsoleApp1\ConsoleApp1" %>

// Tokens (Reihenfolge ist wichtig!)

EOF                 -> @"^\s*$";
[Color(255, 0, 0)]  NUMBER      -> @"[0-9]+";
[Color(0, 0, 255)]  PLUSMINUS   -> @"(\+|-)";
[Color(0, 0, 255)]  MULTDIV     -> @"\*|/";
[Color(0, 0, 255)]  BROPEN      -> @"\(";
[Color(0, 0, 255)]  BRCLOSE     -> @"\)";
[Color(0, 0, 255)]  ASSIGN      -> @"=";

// Keywords – MÜSSEN VOR IDENT kommen!
[Color(0, 128, 0)]  PRINT       -> @"print";
[Color(0, 128, 0)]  LET         -> @"let";
[Color(0, 128, 0)]  WHILE       -> @"while";
[Color(0, 128, 0)]  DO          -> @"do";
[Color(0, 128, 0)]  END         -> @"end";

// Bezeichner
[Color(128, 0, 128)] IDENT      -> @"[a-zA-Z_][a-zA-Z0-9_]*";

[Skip] WHITESPACE   -> @"\s+";

// --------- Grammatik ---------

// Ein Programm ist eine Liste von Statements
Start -> StmtList EOF
{
    return $StmtList;
};

// Liste von Statements
StmtList -> (Stmt)*
{
    // WICHTIG: wir laufen direkt über die Kindknoten,
    // damit jedes Stmt genau einmal evaluiert wird.
    foreach (ParseNode node in nodes)
    {
        if (node.Token.Type == TokenType.Stmt)
            node.Eval(tree);
    }
    return null;
};

// Ein Statement kann print, let oder while sein
Stmt -> PrintStmt
      | LetStmt
      | WhileStmt
;

// print-Ausgabe
PrintStmt -> PRINT AddExpr
{
    int value = Convert.ToInt32($AddExpr);
    Console.WriteLine(value);
    return null;
};

// Variablenzuweisung: let x = 3+4
LetStmt -> LET IDENT ASSIGN AddExpr
{
    string name = $IDENT.ToString();
    int value = Convert.ToInt32($AddExpr);

    if (!tree.Variables.ContainsKey(name))
        tree.Variables.Add(name, value);
    else
        tree.Variables[name] = value;

    return null;
};

// while-Schleife: while <expr> do <stmts> end
// Schleife läuft, solange Ausdruck != 0 ist
WhileStmt -> WHILE AddExpr DO StmtList END
{
    while (Convert.ToInt32($AddExpr) != 0)
    {
        // Body neu ausführen
        $StmtList;
    }
    return null;
};

// ---------- Ausdrücke ----------

AddExpr -> MultExpr (PLUSMINUS MultExpr)*
{ 
    int Value = Convert.ToInt32($MultExpr);
    int i = 1;
    while ($MultExpr[i] != null)
    {
        string sign = $PLUSMINUS[i-1].ToString();
        if (sign == "+")
            Value += Convert.ToInt32($MultExpr[i++]);
        else 
            Value -= Convert.ToInt32($MultExpr[i++]);
    }

    return Value; 
};

MultExpr -> Atom (MULTDIV Atom)*
{ 
    int Value = Convert.ToInt32($Atom);
    int i = 1;
    while ($Atom[i] != null)
    {
        string sign = $MULTDIV[i-1].ToString();
        if (sign == "*")
            Value *= Convert.ToInt32($Atom[i++]);
        else 
            Value /= Convert.ToInt32($Atom[i++]);
    }
    return Value; 
};

// Atom: Zahl, Variable oder (Ausdruck)
Atom -> NUMBER | IDENT | BROPEN AddExpr BRCLOSE
{
    if ($NUMBER != null)
        return $NUMBER;

    if ($IDENT != null)
    {
        string name = $IDENT.ToString();
        if (tree.Variables.ContainsKey(name))
            return tree.Variables[name];
        else
            throw new Exception("Undefined variable: " + name);
    }

    // Klammer-Ausdruck
    return $AddExpr; 
};
let x = 13

while x do
    print x
    let x = x - 1
end

print x
tinypg.1765535024.txt.gz · Zuletzt geändert: 2025/12/12 11:23 von jango