【问题标题】:Parser/Lexer/Programming Language Question解析器/词法分析器/编程语言问题
【发布时间】:2011-03-06 08:26:42
【问题描述】:

好的,所以我不擅长所有的术语和东西,但这是我迄今为止创造的:

1:一个逐字符读取源代码文件内容的应用程序。和;

2:确定字符/字符串“x”是标识符、整数还是其他的应用程序。

和 3:另一个应用程序将它们放在一起,并创建另一个文件,该文件基本上包含要发送到我的第四个应用程序的指令,基本上是:

将 Integer oldValue 的值赋给 Integer newValue。

那么,我的第 4 个应用程序接收到这个指令,并“编译”它(好吧,在这种情况下我只想解释它),然后创建一个应用程序:

int newValue = oldValue;

那么,既然我已经完成了解析器等,如何将我的指令翻译成导致实际动作的指令,并生成一个EXE文件,所以当我双击该文件时,它将执行上述行动?

我希望这不会让你感到困惑。

所以,基本上,我想我要问的是:“如何以编程方式从字符串创建一个“事件”,将其保存到文件并生成一个 exe?”

【问题讨论】:

标签: c# .net winforms dom codedom


【解决方案1】:

有几个选项可以从指令列表生成 EXE。所有选项都涉及您将指令转换为不同语言的元素。

【讨论】:

    【解决方案2】:

    这是一个使用我在评论中提供的简单可执行文件创建的真实工作示例:

    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);
            }
        }
    }
    

    您可以按照 cmets 的指示在方法块内发出代码。

    此外,您可以使用LambdaExpression.CompileToMethod Method 代替ILGenerator表达式

    【讨论】:

      【解决方案3】:

      在编译阶段,您最好使用Reflection Emit APIs 发出.NET IL 并生成EXE 和DLL。

      与其深入了解这里的所有内容,我将向您指出以下 MSDN 文章 Create a Language Compiler for the .NET Framework,其中包含可以帮助您的示例代码。

      另一个选项包括生成 C# 代码并使用 CodeDOM 将代码编译为 EXE,这将利用 C# 编译器作为代码生成和最终二进制生成之间的中间步骤。

      【讨论】:

        【解决方案4】:

        最简单的方法可能是让您的程序为某种语言(例如 C)生成源代码并将其输出到您将单独编译的文件。这样可以省去您必须进行代码生成的麻烦,而这可能相当复杂。

        根据任务的复杂性,使用 Yacc(和 Lex)等工具可能更容易。这些允许您指定如何识别您关心的输入部分和语言的语法,以及在识别构造时要输出的内容。您不必为所有 C# 指定语法,只需为您的任务指定您关心的部分即可。

        【讨论】:

        • 非常感谢@templets。我很想使用 Yacc 或 Lex,以避免所有的复杂性,但由于某种原因,它们看起来很复杂,无法弄清楚如何使用 :-S 这就是为什么我只是尝试自己做这一切,但如果你可以的话指出我正确的方向来学习其中之一,那么我将非常感激。
        猜你喜欢
        • 2017-03-03
        • 1970-01-01
        • 2011-01-30
        • 2019-06-07
        • 1970-01-01
        • 1970-01-01
        • 2011-02-03
        • 2013-01-31
        • 1970-01-01
        相关资源
        最近更新 更多