为什么只显示空白?为什么不解析正确?

时间:2013-06-26 14:34:31

标签: c# parsing interpreter visual-c#-express-2010

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

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 个答案:

答案 0 :(得分:1)

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

C# string reference type?

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

static void compile(string line, out string code)

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

static string compile(string line, string code)

然后像这样调用它:

code = compile("code bits",code);

答案 1 :(得分:1)

正如Lasse V. Karlsen建议的那样,您可以通过引用传递code(使用ref),但最好的解决方案是使用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");
            }
        }
    }
}

答案 2 :(得分:0)

static void compile(string line, string code)

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

static void compile(string line, ref string code)

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

答案 3 :(得分:0)

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

您正在向该方法发送一个字符串变量,但该方法无法更改该变量的内容,它只能更改它有权访问的参数,其功能与局部变量非常相似。

因此,无论compile方法对code参数的作用是什么,都不会更改main方法中code变量的内容。

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

static void compile(string line, ref string code)

要打电话:

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

观察:

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