2014-07-22 1 views
0

ironpython에서 파이썬 코드를 분석 할 수있는 도우미 메소드가 있습니까?IronPython의 코드 체인을 분석하십시오.

def bar(b): 
    return foo(b) 

def foo(f): 
    return filters.delta(f) #This is a reference added to the scope from C# 

x = 1 
bar(x) 

내가 바 같은 스크립트에서 호출하는 방법을 filters.delta 알 필요가이 스크립트 예를 들어 주어 (X)> foo는 (B)> filters.delta (F)

수이 IronPython에서 수행해야합니까, 아니면 스크립트를 직접 파싱해야합니까? 아니고 아주 쉬운 일

배경 정보

FreePIE라고위한 소프트웨어. 그것의 스크립트 가능한 입력 출력 에뮬레이터. 그것은 util 함수 세트를 가지고 있습니다. 이 코드를 고려하십시오.

mouse.deltaX = filters.delta(joystick[0].x) 

그것은 절대 x는 조이스틱이나 게임 패드의 좌표합니다 filers.delta를 사용하여 델타 값을 가져옵니다 상대 x는 델타 값을 얻으려면 마우스의

좌표 설정 사이에 두 개의 샘플을 비교해야 내 소프트웨어 스크립트 실행에서는 util 함수가이를 처리합니다.

[NeedIndexer] 
public double delta(double x, string indexer) 
{ 
    var lastSample = x; 
    if (deltaLastSamples.ContainsKey(indexer)) 
     lastSample = deltaLastSamples[indexer]; 

    deltaLastSamples[indexer] = x; 

    return x - lastSample; 
} 

그러나 마지막 샘플을 저장해야한다는 점을 해결하십시오. 당신이 볼 수 있듯이 마지막 샘플을 담고있는 콜렉션을 색인 할 수있는 문자열을 취한다. 나는 사용자가이 인덱스를 단순하게 처리하도록 요구하고 싶지 않다. 그래서 내가 스크립트를 준비하고 [NeedIndexer] 속성을 가진 모든 메소드를 찾는다. 하나를 찾으면 메서드 인수를 구문 분석하고이를 인덱서로 사용합니다. 그래서 위와 같이 찾고 파이썬 스크립트 joystick[0].x는 고유하므로 코드가 작동이 예에서는

mouse.deltaX = filters.delta(joystick[0].x, "joystick[0].x") 

를 분석 한 후 다음과 같이하지만 사용자가 거기에서 filters.delta를 파이썬 함수를 정의하고 사용하는 경우 그 인덱스 것 모든 샘플에 대해 동일한 변수 이름.

https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.Core/ScriptEngine/Python/PythonScriptParser.cs#L135

는 내가 만드는 희망 스크립트를 구문 분석에 대한 현재의 코드 내가 달성하기 위해 노력하고있는 무슨이 더 명확

나는 제프의 대답

을에 조금 더 감사를받은 업데이트
var engine = IronPython.Hosting.Python.CreateEngine(); 
var script = @"def foo(y): 
    return filters.delta(y) 

def bar(x): 
    return foo(x) 

bar(-5) 
"; 

var ast = @"import ast 
tree = ast.parse(script) 
callback(ast.dump(tree))"; 


var callback = new Action<object>(o => 
{ 
    Console.WriteLine(o); 
}); 


engine.SetSearchPaths(new[] { "pylib" }); 
var scope = engine.CreateScope(); 
scope.SetVariable("script", script); 
scope.SetVariable("callback", callback); 

engine.Execute(ast, scope); 

ast.dump을 사용하여 전체 트리를 문자열로 덤프 할 수 있었지만 어떻게 발견 되었습니까? 재귀 적으로 트리를 반복한다. filters.delta 호출을 찾을 때까지이 작업을 수행 한 다음 백업을 다시 트래버스하고 체인의 각 함수에 인수를 추가해야합니다. ast 모듈에 대한 그물에 대한 많은 정보가 없습니다. 이 사람은 어떻게 이것이 일어날 수 있는지 알고 있습니다. _fields 회원이 ast.parse에 의해 반환되는 개체에 있습니다. 그러나 거기서 나가기 위해 밖으로 찾을 수 없습니다.

+0

호기심,이 질문은 C# 태그와 어떤 관련이 있습니까? – Jsinh

+0

음, IronPython을 모든 .NET 언어에서 사용할 수 있다고 생각합니다. 하지만 C#을 사용합니다. – Anders

+0

반짝임을 지울 수있는 배경 정보를 추가했습니다. – Anders

답변

2

먼저, 어떻게 생각하는지 생각해보십시오. 어떤 해결책이라도 깨지기 쉽고 마 법적 일 것이며 길 아래로 더 많은 문제를 야기 할 수 있습니다. mouse.deltaX = joystick[0].x_filters.delta()과 같은 것이 더 분명해질 것입니다.심지어 x_filters을 생성 할 수 있습니다 (조이스틱 유형의 일부일 필요는 없습니다).

스크립트를 수정하려면 ast 모듈을 사용하여 코드를 구문 분석하고 싶을 것입니다. 당신은 여전히 ​​그 기능을 찾아 천천히 걸어 가야 할 것입니다. 다른 이름으로 묶여있는 함수를 다룰 지 여부 등은 당신에게 달렸습니다. ast 모듈은 심볼의 텍스트 위치도 제공해야하므로, 그 뒤에 특수 코드를 삽입 할 수 있습니다.

sys.settrace을 사용하면 런타임에 엔진을 만들 때 "추적"옵션을 활성화하면 IronPython에서 작동해야 할 수도 있습니다. 그러나 이것은 당신의 목적을 위해 너무 늦게 발동 할 수 있습니다.

+0

이것은 이미 제작 중이므로 너무 늦었습니다. D 가능한 한 비슷하게 보이지 않는 GlovePIE로 시도합니다. 당신의 제안을 볼 것입니다, – Anders

+0

공개 인터페이스를 변경할 수 없기 때문에 솔루션이 아니라 확장 메소드를 대신 사용하는 것이 좋지 않으며 clr.ImportExtensions를 사용하면 'joystick [0] .x.filters'가됩니다.() .delta()' – Anders

+0

그러나 확장 메서드를 사용하면 여전히 마지막 샘플을 색인화하는 데 열쇠를 얻는 것이 어렵습니다. – Anders

관련 문제