0

我正在尝试制作解析器和解释器或编译器。现在,当我尝试执行测试代码时,它显示的都是空白。我没有解析它还是有什么干扰或什么?有人可以看看并告诉我什么不起作用吗?

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.CodeDom.Compiler;
using Microsoft.CSharp;

namespace Mikebite
{
     class Program
     {
        static void Main(string[] args)
        {
            try
            {
                string code = "";
                compile("function Main {", code);
                compile("x = Hello world!!", code);
                compile("print x", code);
                compile("input x", code);
                compile("} ;", code);

                Console.WriteLine(code);
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.ReadLine();
            }
        }
        static void compile(string line, string code)
        {
            string[] tokens = line.Split(' ');

            for (int i = 0; i < tokens.Length; i++)
            {
                if (tokens[i].Contains("function"))
                {
                    code += ":" + tokens[i+1];
                    i++;
                }
                else if (tokens[i].Contains("="))
                {
                    code += "PUSH " + tokens[i-1] + "\n";
                    code += "PUSH " + tokens[i+1] + "\n";
                    code += "SET\n";
                    i++;
                }
                else if (tokens[i].Contains("exec"))
                {
                    code += "GOTO " + tokens[i+1] + "\n";
                    i++;
                }
                else if (tokens[i].Contains("}"))
                {
                    code += "RTN\n";
                }
                else if (tokens[i].Contains("input"))
                {
                    code += "PUSH " + tokens[i+1] + "\nPUSH NULL\nINPUT\n";
                }
                else if (tokens[i].Contains("print"))
                {
                    code += "PUSH " + tokens[i+1] + "\nPUSH NULL\nPRINT\n";
                }
            }
        }
    }
 }
4

4 回答 4

1

它没有按预期工作,因为即使字符串是引用类型,它实际上也是按值传递的。这意味着每次传入字符串时,都会传入一个空白字符串,并且没有对其进行任何操作。看到这个帖子:

C#字符串引用类型?

您可以通过将其声明为“out”变量来修复它。

static void compile(string line, out string code)

或者更好的是,更改编译以返回字符串。

static string compile(string line, string code)

然后像这样调用它:

code = compile("code bits",code);
于 2013-06-26T14:38:59.213 回答
1

正如 Lasse V. Karlsen 建议的那样,您可以通过code引用传递(使用ref),但最好的解决方案是使用 a,StringBuilder因为它是可变的,这将为您节省数十个无用的string实例化:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            StringBuilder code = new StringBuilder();
            Compile("function Main {", code);
            Compile("x = Hello world!!", code);
            Compile("print x", code);
            Compile("input x", code);
            Compile("} ;", code);

            Console.WriteLine(code);
            Console.ReadLine();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Console.ReadLine();
        }
    }
    static void Compile(string line, StringBuilder code)
    {
        string[] tokens = line.Split(' ');

        for (int i = 0; i < tokens.Length; i++)
        {
            if (tokens[i].Contains("function"))
            {
                code.Append(":")
                    .Append(tokens[i+1]);
                i++;
            }
            else if (tokens[i].Contains("="))
            {

                code.Append("PUSH ")
                    .Append(tokens[i-1])
                    .Append("\n")
                    .Append("PUSH ")
                    .Append(tokens[i+1])
                    .Append("\n")
                    .Append("SET\n");
                i++;
            }
            else if (tokens[i].Contains("exec"))
            {
                code.Append("GOTO ")
                    .Append(tokens[i+1])
                    .Append("\n");
                i++;
            }
            else if (tokens[i].Contains("}"))
            {
                code.Append("RTN\n");
            }
            else if (tokens[i].Contains("input"))
            {
                code.Append("PUSH ")
                    .Append(tokens[i+1])
                    .Append("\nPUSH NULL\nINPUT\n");
            }
            else if (tokens[i].Contains("print"))
            {
                code.Append("PUSH ")
                    .Append(tokens[i+1])
                    .Append("\nPUSH NULL\nPRINT\n");
            }
        }
    }
}
于 2013-06-26T14:41:29.803 回答
0

static void compile(string line, string code)

您将代码作为字符串传递,但没有要求它返回任何数据,但您对该函数的使用清楚地表明您正在尝试在每次调用时更改它。将调用更改为 ref。

static void compile(string line, ref string code)

并用 ref 调用它,例如compile("function Main {", ref code);

于 2013-06-26T14:37:53.743 回答
0

这里的问题是它string是不可变的,并且您没有通过引用传递参数。

您正在向该方法发送一个字符串变量,但该方法不能更改变量的内容,它只能更改它可以访问的参数,其功能非常类似于局部变量。

因此,无论该compile方法对code参数做什么,都不会改变code主方法中变量的内容。

要解决此问题,请通过添加关键字将参数更改为按引用传递参数:ref

static void compile(string line, ref string code)

调用它:

compile("function Main {", ref code);

观察:

  • 您在输出中的“:Main”程序标签后忘记了换行符
  • PUSH x并且PUSH Hello不区分变量或文字(在这种情况下为字符串),您可能想要解决此问题,通常通过添加引号,即。PUSH "Hello"
于 2013-06-26T14:38:58.047 回答