C# AST Parser


Abstract Syntax Tree

한마디로 언어에 관계 없는 프로그래밍 언어의 형태를 나타내어 주는 간략한 트리라고 볼 수 있다.

위키


종류

-Cecil : C#의 IL코드를 분석하여 컴파일?하는 방식

-NRefactory : Cecil 오픈 라이브러리를 이용하여 AST 파서를 만들어 제공하는 것으로 요즘 내가 사용하고 있는 오픈소스 라이브러리임.


NRefactory

Github에서 소스파일이나 Library(Dll) 파일을 받을 수 있으며 사용하는 방법은 CodeProject의 예제에 나와있다. (NRefactory_Demo_and_IndexOf-Sample_-_Source)

Method 들의 호출관계(Call Hierarchy)를 구하고 싶어서 사용했으며 예시 코드는 다음과 같다.


이 프로젝트를 진행하면서 고생했던 것은

1. 오픈소스 라이브러리의 존재 유무

오픈소스 라이브러리가 있는 줄 몰랐기 때문에 처음에는 갖은 방법을 생각했었다.

처음 생각했던 것은 직접 Parser를 구현했지만 역시나 컴파일러 수준으로 작성하는 것은 효율적이지 못했고 어려웠다.

두번째로 생각했던 것은 정규표현식으로 함수모양으로 생긴 것들을 찾아내는 것이었으나 주석안에 있는 함수 등등 상당한 문제를 내포하고 있었다 (주석을 지우고 실행하는 것으로 해결)

마지막으로 찾은 것이 바로 AST Parser였다.

2. 오픈소스 라이브러리의 사용 방법

라이브러리마다 다른 사용법을 가지고 작성되었기 때문에 각각의 특성에 맞게 이용하는 것이 중요하다. 하지만 어떤 구성으로 되어있는지 처음에 사용하기도 어려웠기 때문에 Demo를 통해서 분석했다.

메소드는 어떤 타입으로 검사해야되는지(IMethod, MethodDeclaration) 등등 원하는 정보를 찾는 것도 어려웠다.

3. Find References

호출관계를 구하는 과정에서 시간이 오래걸렸다. 초기의 버전에서는 Method의 Call Hierarchy를 구할때마다 재귀적인 방식으로 FindReferences를 이용하여 구했는데 (해당 주소로 이동) 매번 호출하게 되니 거의 3분가량의 시간이 소모되었다. 개선하는 과정에서 Call Hierarchy를 Map으로 저장해두고 필요할때 타고 이동하는 방식을 사용해야겠다고 생각되었다.

4. Hash Collision

Method를 Hashtable에 넣어서 Call Hierarchy를 저장해두는 방식을 택하게 되었는데 어떤 문제인지 모르겠지만 계속 Hash값이 충돌되는 일이 발생되었다. 처음에는 GetHashCode에 문제가 있는 것 같아서 새로운 Hash값을 넣었지만 같은 충돌이 계속발생되었다. 같은 Method를 2번씩 넣기에 .cs이 중복되지 않았으며 Method는 계속 2번씩 호출되고 있었다. 그 이유는 interface를 피하고 class만을 구하는 방법이 잘못된 것이었다. 해결하기 위해 Method의 BodyRegion이 비어있는지 확인하는 것으로 해결했다.

5. Interface

Class의 method만을 가져오려고하는데 계속 Interface까지 가져오기에 함수가 두번씩 나오게 되었다. 이를 처리하기 위해서 Class를 먼저 구하고, 그 class 내부에서 method를 찾는 방식으로 진행했는데 partial class에서 method를 2번씩 가져오는 문제가 발생되었다.


여러가지 삽질끝에 NRefactory Parser를 잘 쓸 수 있게 됐다.

'프로그래밍 > C#' 카테고리의 다른 글

[Unity] Android Plugin  (0) 2015.09.29
[Error] ClickOnce error  (0) 2014.11.21
FTP with .NET (C#)  (0) 2014.10.21
by 개발자가 되자! 2015. 11. 3. 15:01

이전에도 앞으로도 계속될 논쟁..

Call by Value와 Call by Reference에 대한 개념을 알고 있다고 가정하고 시작해봅니다.

소스코드의 일부는 http://egloos.zum.com/Dplex/v/4312931 여기서 가져왔습니다.


1. 기본자료형

일단 기본 자료형인 int ... 등의 값은 세가지 모두 Call by Value.


2. Class

2-1. Call by Value

C++의 예제

결과

0082B618:Jindo

003FFAA8:Max

003FFAA8:Fifi

003FFAA8:Rowlf

0082B618:Jindo


값을 복사해서 새로운 Class를 만들기 때문에 마지막 결과가 Jindo가 나옴을 알 수 있습니다.



2-2. Call by Address

설명하기에 앞서 Call by Address라는 단어를 알려드리고 싶어요

Call by Reference는 의미를 보자면 "함수내에서 변수값을 바꾸었더니 함수 밖에서도 값이 변한다." 는 겁니다.

call by value니 call by reference가 맞다느니... 왜 싸우는 걸까요? 


Java는 Call by Reference이라고 말하는 사람은 아래의 첫번째 정의를 보고 있기 때문이고

Call by Value 라고 하는 사람들은 두번째 정의로 보고 있기 때문입니다.


아래의 미묘한 차이점을 확인해주세요

- 변수 안에 저장되어 있던 주소값을 넘기는 것.

- 별명의 개념


쉽게 설명하면

첫번째 정의는 새로운 변수를 생성하여 저장되어있던 주소값 복사하여 담아두는 것을 말하고, 

두번째 정의는 해당 변수 자체의 주소라고 봅니다. 별명을 만든다고나 할까요, 다른 이름이지만 같은 변수를 가리키도록 말이에요.


첫번째 정의를 개념적으로 보았을때 주소값을 통해 Class를 접근하기 때문에 Call by Address 라고 말씀드리고 싶군요. 단어를 새롭게 정의!


Call by Address의 경우에는 아래의 설명을 참고하세요.

위의 사진처럼 함수에서 someDog이라는 주소값을 할당할 수 있는 공간이 생성되고 5000이라는 값이 복사 됩니다. 따라서 pointer 혹은 hash값이 다릅니다.


만약 함수 안에서 새로 인스턴스를 생성한다면 아래의 그림으로 바뀌게 됩니다.

변수 자체가 다르기 때문에 new Dog를 통해 새로운 인스턴스를 생성하게 되면 가리키는 메모리가 다르게 됩니다.


C++의 예제

결과

007BB618:Jindo

007BB618:Max

007BC990:Fifi

007BC990:Rowlf

007BB618:Max


Java의 예제

결과

Dog@659e0bfd : Jindo

Dog@659e0bfd : Max

Dog@2a139a55 : Fifi

Dog@2a139a55 : Rowlf

Dog@659e0bfd : Max


C#의 예제

결과

46104728 : Jindo

46104728 : Max

12289376 : Fifi

12289376 : Rowlf

46104728 : Max


2-3. Call by Reference는 아래의 설명을 참고하세요.

myDog라는 변수가 main 함수 안에 선언되어있으며 주소값은 1000입니다.

new Dog("Jindo");를 하게 되면서 5000이라는 메모리가 할당되고 name 변수에 "Jindo"의 주소값을 갖습니다.

C++의 경우에는 포인터를 통해 값을 넘기면 1000이라는 주소값을 넘깁니다.



만약 함수 안에서 새로 인스턴스를 생성한다면 아래의 그림으로 바뀌게 됩니다.

따라서 함수 안에서 값을 변경하게되면 main의 myDog값에 직접 쓰이게 되는 겁니다.


C++의 예제


결과

005CB618:Jindo

005CB618:Max

005CB618:Fifi

005CB618:Rowlf

005CB618:Rowlf


C#의 예제

결과

0076B618:Jindo
0076B618:Max
0076B618:Fifi
0076B618:Rowlf
0076B618:Rowlf



아래의 예제 결과로 글작성을 마칩니다!


Call by Value

Jindo

Max

Fifi

Rowlf

Jindo


Call by Address

Jindo

Max

Fifi

Rowlf

Max


Call by Reference

Jindo

Max

Fifi

Rowlf

Rowlf


이견이 있으신 분께서는 댓글을..

by 개발자가 되자! 2015. 4. 14. 17:11

FTP

FTP는 보안이 이루어지지 않은 채로 통신이 이루어지는 옛 버전


SFTP

FTP에 Security가 포함되어있다는 뜻으로 3가지 정도의 의미를 갖고있다


1. SFTP (SSL File Transfer Protocol)

FTP와는 완전히 관계가 없는 파일 전송 프로토콜이다, SSL을 이용한다


2. SecureFTP (FTP/SSH)

SSH 연결 위에 일반 FTP로 접속을 하지만 실제 데이터는 암호화 되지 않는다


3. FTPS (or FTP/SSL) implicit & explicit

FTP가 TLS/SSL 보안 연결에서 동작한다. TLS(Transport Layer Security)/SSL(Secure Sockets Layer) 연결을 구성하는데에 따라 'implicit' 또는 'explicit'으로 구분이 된다.


TLS/SSL - Explicit mode

TLS/SSL - Implicit mode

Communication schema:

  1. Client connects to the server.
  2. Client explicitly requests TLS/SSL encryption to be switched on.
  3. Client talks to the server using encrypted channel.
  4. Username + password is sent encrypted.

Communication schema:

  1. Client connects to the server and TLS/SSL encryption is switched on implicitly as soon as the channel is established.
  2. Client talks to the server using encrypted channel.
  3. Username + password is sent encrypted.

ProtocolPlain port
(no encryption)
TLS/SSL Explicit portTLS/SSL Implicit port
FTP2121990
IMAP143143993
SMTP25 or 58725 or 587465
POP3110110995
HTTP80-443




.Net 지원 여부

API support
 
FTP - supported via FtpWebRequest included in .NET
FTPS - implicit - not support by .NET out of the box. You'll need a third party support. 

FTPS - explicit - supported in FtpWebRequest in .NET
SFTP - not support by .NET out of the box. You'll need a third party support.


출처 : http://www.codeproject.com/Questions/544479/C-plussftpplusdownloadplusandplusupload

http://doodoodoo.egloos.com/1377894

'프로그래밍 > C#' 카테고리의 다른 글

[C# Parser] NRefactory  (0) 2015.11.03
[Unity] Android Plugin  (0) 2015.09.29
[Error] ClickOnce error  (0) 2014.11.21
by 개발자가 되자! 2014. 10. 21. 05:08
| 1 |