2012-03-17 2 views
0

나에게 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. 라고 그리고 (이) 전화를 걸거나()
  3. 또는()가()
  4. 을 (호출)가 true
  5. 를 반환됩니다
  6. 흐름) (true를 반환 또는(), (게으른 평가)
  7. 흐름 (로 복귀(), 그리고) C()를 호출
  8. C()가 false
  9. 흐름에 반환하고 반환에 반환 , 이는

것은 지금이 아니면()가 게으른 평가 (나는 |||로 변경) 수행하지 않은 프로그램이 true를 돌려줍니다 경우 false를 반환합니다. 그러나 전체 구문 분석의 결과가 실패하지 않는 한 AB()가 실행되는 것을 원하지 않습니다. And()는 false를 반환합니다.

그래서 내가 뭘하고 싶은지, Or() 함수에, And()가 false를 반환하면 스택에서 항목을 팝 할 수 있도록 스택 (정적 변수)에 현재 상태를 저장합니다. 대안을 시도하십시오.

어떻게하면 C#에서이 작업을 수행 할 수 있습니까?

+0

개인적으로 GPPG와 같은 것을 사용하고 있습니다. – leppie

+0

이것은 C#에서는 불가능합니다. cpu 호출 스택을 캡처하여 나중에 복원 할 수는 없습니다. –

+0

@leppie : Gardens Point Parser Generator? 나는 그것을 들여다 볼 것이다. 그러나 나는 여전히 이것을 학습 운동으로하고 싶다. – mpen

답변

1

그것은 상당히 trivial- 그냥 통화 재 배열로서 저를 친다 :

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

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

을 아니면 내가 뭔가를 놓친 거지? 어쩌면 C()에는 두 번 호출해서는 안되는 부작용이 있습니까?

편집 : 이제 당신이하려는 일을 이해합니다. 너 스스로 부탁해라. 얻은 제안을 듣거나 GPPG 사본을 얻거나 ANTLR (아마도 훨씬 간단합니다)을 ANTLRWorks과 함께 사용하십시오. 입니다. 따라서 파서를 손으로 돌리는 것보다 훨씬 쉽고 오류가 발생하기 쉽고, 결국 C#을 얻습니다.

+0

'C()'는 두 번 호출 할 수 있습니다. 그것은 있어야 할 것입니다; 역 추적을하고'AB()'를 호출해야하는지 결정하기 위해 한번 호출해야합니다. 여기에 손으로하는 것은 쉽지 않지만 ... 이런 함수 호출을 재 배열하는 프로그래밍 방식이 있습니까? – mpen

+0

프로그래밍 방식으로 주어진 * 입력 및 출력으로 * 무엇입니까? 표현 트리? 대표단 체인? 일부 연결 작업? 나는 이것이 당신이 염두에두고있는 몇 가지 구체적인 유스 케이스를 가지고 있으며 질문을하는 데 너무 추상적으로 만들려고 시도하는이 질문으로 당신이 겪고있는 문제라고 생각합니다. 위와 같이 구체적인 실행 가능한 프로그램을 제공 할 수 있다면 문제를 근사하지 않고 실제로 발생하는 문제를 재현 할 수 있습니다. –

+0

좋아요, 전체 프로그램을 게시하고 지금까지 가지고있는 내용을 게시 할 것입니다. 그러나 사람들이 너무 많은 코드를 게시하면 사람들은 겁 먹는 경향이 있습니다. – mpen

2

문제는 || 운영자. 문제는 실패한 Parse로 되돌아가는 것을 잊었다는 것입니다. Parse가 false를 반환하면 i 및 다른 상태 변수를 원래 값으로 복원하여 다음 파서가 시도 할 수있게해야합니다. C#은 목표 추구 언어가 아닙니다. 역 추적을 원하면 직접해야합니다. (또는 Prolog와 같은 역 추적 기능이있는 언어로 전환하십시오.)

+0

나는 잊지 않았다. 나는 내가 되돌아 갈 필요가있다는 것을 안다, 나는 단지 * 어떻게 되돌아 갈 것인지 모른다. 'i'를 복원하는 것은 쉽습니다. 나머지 국가는 까다 롭습니다. – mpen

+0

나는 45 분 동안 당신의 프로그램이 어떻게 작동하는지 배우고 그것을 디버깅하는데 보냈다. 실패한 구문 분석에서'i'를 복원하면 프로그램이 정상적으로 작동합니다. 'literal'의 정의가 열린 중괄호를 포함하기 때문에 문자 10 이후 파싱을 올바르게 중단합니다. –

+0

수정 사항을 게시 할 수 있습니까? 오히려 다른 옵션 것보다, 리터럴을 '하고 포기 : item''의 정의가 먼저'kvp'을 시도라고 때문에, 첫 번째 문자 번번이해야하고, 그것은 찾을 수 없습니다를' . 그 부분이 효과가 있었다고하더라도 ...'e' 앞에있는 단어가 이미'dict'에 의해 읽혀져 있었기 때문에'literal'은 여는 중괄호를 제외해야한다고 생각하지 않았습니다 ... – mpen

관련 문제