【发布时间】:2014-08-30 20:02:51
【问题描述】:
我想知道 C# 中是否有某种机制允许从它在上次调用期间到达的最后一次返回中“恢复”方法。
我需要什么:我有一个抽象语法树 (AST),它是由从源语言设计的解析器创建的。这个抽象语法树是一个“根类”的对象,它具有其他类的字段实例等。我需要做的是创建一个 sequencer,它采用这个抽象语法树,并通过 generator 创建其他语言的指令。指令序列以空值结束。这可以通过生成器方法 next() 来实现,该方法调用一个排序器方法,该方法可以即时计算下一条指令。换句话说,我无法探索整个抽象语法树,生成所有指令并在每次调用next() 时一一返回,但我必须在每次生成器调用时创建它们中的每一个下一个()。
一个例子:为了让你更好地理解问题,我将发布一个伪代码。
static void Main(string[] args)
{Parser parser = new Parser (//constructor stuff);
Sequencer sequencer = new Sequencer(parser.Parse()); //the mehtod Parse() generates the AST
Generator generator = new Generator(sequencer);
Instruction instruction = generator.next();
while(instruction)
{print instruction
instruction = generator.next();
}
}
重要提示:我希望您理解的最重要的事情是 next() 并不总是在某种迭代中被调用,所以我不认为 @ 987654326@ 和迭代器是一个很好的解决方案。
这是因为为了使用迭代器,我最终不得不写类似的东西
foreach(instruction in next())
{//do stuff with instruction}
我不想那样做!
不过,我会让您了解next() 的结构:
Instruction next()
{ return sequencer.generate();}
所以generate():
Instruction generate():
{Insturction instr;
while(I explored the whole AST)
{if(//actual node in the AST is this kind)
instr=//generate this instruction
else if(//actual node in the AST is this other kind)
instr=//generate this other instruction
else and so on....
//if the actual node has some child, then it is new actual node
**yield return** instruction;
}
}
最复杂的部分是我需要具有yield return 行为的东西(所以从我离开的下一个generate() 调用开始,但由于我之前解释的原因而没有使用迭代器。沉迷于此,它在 AST 中移动非常困难,因为我无法明确引用实际节点的父节点(例如作为实际节点副本的字段)。
由于不够,你可以递归调用generate(例如,如果有某种迭代构造函数要翻译)。
如何做到这一点?
【问题讨论】:
-
如果您说出您要解决的问题,那将很容易回答。这看起来像XYProblem。顺便说一句,你问的是所谓的状态机。
-
唯一的问题是你想
yield return (nothing);而不是yield return some_object;吗? -
我同意你的看法,但我不能在这篇文章中发布整个“代码生成器”程序......我应该发布抽象语法树类,也许还有解析器代码.显然,这是不可能的:D
-
我编辑了整个问题,以便更好地理解问题及其限制。我希望它能帮助你(和我:P)
-
@LovaJ。 - 我想误解来自这样一个事实,即您坚持认为
IEnumerator.Current/IEnumerator.MoveNext()对绝对不如单个“next()”方法...如果您真的只需要next()为什么不包装 C# 创建的迭代器使用单一方法的辅助类?不知道您为什么将foreach和IEnumerable视为单个不可分离的概念...
标签: android c# iterator yield-return