Я хочу знать, есть ли какой-то механизм в C#, который позволяет «возобновить» метод из последнего возвращения, которое оно достигло во время последнего вызова.Как возобновить метод с момента последнего возврата?
ЧТО Я НУЖДАЮ: У меня есть абстрактное синтаксическое дерево (AST), которое создается парсером, разработанным на языке оригинала. Это абстрактное синтаксическое дерево является объектом «корневого класса», который имеет в качестве полей экземпляры других классов и т. Д. Мне нужно создать секвенсор, который принимает это абстрактное дерево синтаксиса и через генератор создает инструкции на другом языке. Последовательность инструкций завершается нулем. Это возможно с помощью метода генератора 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()
не всегда вызывается внутри какой-то итерации , так что я не думаю, что foreach
и итераторы являются хорошим решение.
Это потому, что для того, чтобы использовать iterotors я наконец-то, чтобы написать что-то вроде
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()
, но без использования итератора по причинам, которые я объяснял ранее. В зависимости от этого, очень сложно перемещаться внутри АСТ, так как я не могу имеют явную ссылку родителя фактического узла (например, поле, которое является копией фактического узла).
Поскольку этого недостаточно, вы можете рекурсивно позвонить по номеру generate
(например, если для перевода есть какой-то итерационный конструктор).
Как достичь этого?
Было бы легко ответить, если вы скажете, что проблема, которую вы пытаетесь решить. Это выглядит как [XYProblem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Кстати, что вы просите, называется state machine. –
Единственная проблема, с которой вы хотите "return return (ничего);" вместо 'yield return some_object;'? –
Я согласен с вами, но я не могу опубликовать всю программу «генератор кода» в этом сообщении ... в зависимости от того, что я должен опубликовать классы абстрактного синтаксического дерева и, возможно, код Parser. Очевидно, это невозможно: D – TwistAndShutter