如何返回一行代码并恢复调用堆栈?

时间:2012-03-17 03:22:53

标签: c# parsing

asked a question earlier,但我不认为我对我希望的那种答案足够清楚,所以让我提供一个更具体的例子:

class Program
{
    private static bool State;

    static void Main(string[] args)
    {
        State = false;
        Console.WriteLine(And());
        Console.ReadLine();
    }

    static bool And()
    {
        return Or() && C();
    }

    static bool Or()
    {
        return A() || AB();
    }

    static bool C()
    {
        return State;
    }

    static bool A()
    {
        return true;
    }

    static bool AB()
    {
        State = true;
        return true;
    }
}

该程序的流程如下:

  1. 和()被称为
  2. 和()调用Or()
  3. 或()调用A()
  4. A()返回true
  5. Flow返回Or(),返回true(延迟评估)
  6. Flow返回And(),And()调用C()
  7. C()返回false
  8. Flow返回And(),返回false
  9. 现在如果Or()没有执行延迟评估(我将||更改为|),程序将返回true。但是,我不希望执行AB(),除非整个解析的结果失败(And()返回false)。

    所以我想做的是,在Or()函数中的某个地方,将当前状态保存在堆栈上(静态变量),这样如果And()返回false,我可以弹出一个项目堆叠并尝试替代方案。

    我如何在C#中实现这一目标?

2 个答案:

答案 0 :(得分:2)

问题与||无关运营商。问题是你忘了在失败的Parse上回溯。如果Parse返回false,则需要将i和任何其他状态变量恢复为其原始值,以便下一个解析器可以尝试。 C#不是一门追求目标的语言。如果你想要回溯,你必须自己做。 (或转换为带有回溯的语言,如Prolog。)

答案 1 :(得分:1)

让我感到非常琐碎 - 只需重新安排电话:

static void Main(string[] args)
{
    State = false;
    Console.WriteLine(Or());
    Console.ReadLine();
}

static bool Or()
{
    return A() && C() || AB() && C();
}

或者我错过了什么?也许C()有副作用,不应该被调用两次?

编辑:现在我明白你要做什么了。帮自己一个忙。通过ANTLR聆听您获得的建议,获取GPPG副本或(可能更简单)ANTLRWorks。它是所以,所以比试图手动滚动解析器更容易,更容易出错,并且最后仍然得到C#。