5 Stimmen

Parser/Lexer/Programmiersprache Frage

Okay, ich kenne mich mit den ganzen Begriffen und so nicht aus, ABER hier ist das, was ich bis jetzt erstellt habe:

1: Eine Anwendung, die Zeichen für Zeichen den Inhalt einer Quellcodedatei liest. Und;

2: Eine Anwendung, die feststellt, ob das Zeichen/der String "x" ein Bezeichner, eine ganze Zahl oder was auch immer ist.

und 3: Eine weitere Anwendung, die alles zusammenfügt und eine weitere Datei erstellt, die im Wesentlichen Anweisungen enthält, die an meine 4:

Weisen Sie den Wert von Integer oldValue dem Integer newValue zu.

Dann empfängt meine 4. Anwendung diese Anweisung und "kompiliert" sie (in diesem Fall würde ich sagen, dass ich sie nur interpretieren möchte), was dann eine Anwendung erzeugt, die das tut:

int newValue = oldValue;

Da ich also den Parser usw. bereits fertig habe, wie kann ich meine Anweisungen in Anweisungen übersetzen, die zu tatsächlichen Aktionen führen, und eine EXE-Datei erzeugen, so dass sie beim Doppelklick auf die Datei die oben erwähnte Aktion ausführt?

Ich hoffe, das ist nicht zu verwirrend für Sie.

Also, im Grunde, ich denke, was ich frage ist: "Wie kann ich programmgesteuert ein "Ereignis" aus einer Zeichenfolge erstellen, speichern Sie es in eine Datei und eine exe generieren?"

2voto

dtb Punkte 205441

Es gibt mehrere Möglichkeiten, eine EXE aus einer Liste von Anweisungen zu erzeugen. Alle Optionen beinhalten, dass Sie Ihre Anweisungen in Elemente einer anderen Sprache umwandeln.

  • Sie können generieren C#-Quellcode und kompilieren Sie das Ergebnis mit einem C#-Compiler: System.CodeDom

  • Sie können generieren IL-Anweisungen und speichern Sie die resultierende Baugruppe auf der Festplatte: System.Reflection.Emit

  • Sie können bauen Ausdrucksbäume anstatt IL-Anweisungen zu generieren: System.Linq.Ausdrücke

1voto

Jaroslav Jandek Punkte 9303

Dies ist ein echtes Arbeitsbeispiel für die Erstellung einer einfachen ausführbaren Datei unter Verwendung dessen, was ich im Kommentar angegeben habe:

using System;
using System.Reflection;
using System.Reflection.Emit;

namespace AssemblyGenerator
{
    partial class AssemblyGenerator
    {
        static void Main(string[] args)
        {
            string assemblyName = "Sample";
            string exeName = "Sample.exe";

            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(assemblyName), AssemblyBuilderAccess.Save);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(exeName);
            TypeBuilder typeBuilder = moduleBuilder.DefineType(assemblyName, TypeAttributes.Public | TypeAttributes.Class);
            MethodBuilder methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), null);

            assemblyBuilder.SetEntryPoint(methodBuilder, PEFileKinds.ConsoleApplication);

            ILGenerator ilGenerator = methodBuilder.GetILGenerator();
            // BEGIN method IL.
            ilGenerator.EmitWriteLine("This shows on console output.");
            ilGenerator.Emit(OpCodes.Ret);
            // END method IL.

            typeBuilder.CreateType();
            assemblyBuilder.Save(exeName);
        }
    }
}

Sie können Ihren Code innerhalb des Methodenblocks ausgeben, wie in den Kommentaren angegeben.

Sie können auch eine Ausdruck unter Verwendung der LambdaExpression.CompileToMethod Methode anstelle der ILGenerator .

0voto

Chris Taylor Punkte 50950

In der Kompilierungsphase verwenden Sie am besten die Reflection Emit APIs um die .NET IL zu emittieren und EXEs und DLLs zu erzeugen.

Anstatt hier auf alles einzugehen, möchte ich Sie auf den folgenden MSDN-Artikel verweisen Erstellen eines Sprachcompilers für das .NET Framework die einen Beispielcode enthält, der Ihnen auf Ihrem Weg helfen sollte.

Eine weitere Option ist die Generierung von C#-Code und die Verwendung der CodeDOM um den Code zu einer EXE zu kompilieren, würde dies den C#-Compiler als Zwischenschritt zwischen Ihrer Codegenerierung und der endgültigen Binärgenerierung nutzen.

0voto

templets Punkte 161

Am einfachsten ist es wahrscheinlich, wenn Ihr Programm Quellcode für eine Sprache (z. B. C) erzeugt und diesen in eine Datei ausgibt, die Sie dann separat kompilieren. Das erspart Ihnen die Mühe der Codegenerierung, die ziemlich aufwändig sein kann.

Je nach der Komplexität Ihrer Aufgabe kann es einfacher sein, ein Werkzeug wie Yacc (und Lex) zu verwenden. Damit können Sie festlegen, wie die Teile der Eingabe zu identifizieren sind, für die Sie sich interessieren, und eine Grammatik für die Sprache erstellen, und was ausgegeben werden soll, wenn Konstrukte identifiziert werden. Sie müssen nicht für ganz C# eine Grammatik festlegen, sondern nur für die Teile, die Sie für Ihre Aufgabe benötigen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X