2011-04-29 6 views
3

나는 상당한 도전에 직면하게 될 것이라고 생각합니다. 가능한 한 많이 여러 언어로 식별자의 이름을 알파로 바꿀 수 있기를 바랍니다. 이를 위해서는 각 언어에 대한 특별한 배려가 필요하며, 코드를 공유하여 수행해야하는 작업량을 최소화하는 방법에 대한 조언을 요청합니다. 이미 여러 언어를 지원하는 통합 구문 분석 또는 추상 구문 프레임 워크와 같은 것이 좋습니다.Alpha는 여러 언어로 이름을 바꿉니다.

def foo(x): 
    def bar(y): 
     return x+y 
    return bar 

y-x 알파 리 네이밍이 xy A를 의미하고 보존 변경 :

예를 들어, 몇 가지 파이썬 코드이다. 그래서 될 것이다 :

def foo(y): 
    def bar(y1): 
     return y+y1 
    return bar 

우리가 코드를 깨는에서 유지하기 위해 y1y의 이름을 변경하는 데 필요한 방법을 참조하십시오? 그래서 이것이 어려운 문제입니다. 예를 들어, 문자열 검색을 수행하고 바꾸는 것보다 프로그램이 범위를 구성하는 요소에 대해 꽤 잘 알고 있어야합니다.

가능한 한 많은 형식 (주석, 간격, 들여 쓰기)을 유지하고자합니다. 그러나 그것은 100 % 필요하지 않습니다, 그것은 단지 좋을 것입니다.

팁이 있습니까?

+1

기본적으로 당신은 본격적인 다국어 파서를 찾고 있습니까? –

+0

가능합니다.나는 이름의 의도와 그들이 말한 것에 대한 정보 만 필요로한다. 언어의 다른 의미는 부적합합니다. 하지만 AFAICT에는 파싱이 필요합니다. – luqui

+0

파서만으로는조차 할 수 없습니다. 각 언어에 대해 익명으로 가져온 범위를 고려해야하는 각 식별자에 대해 범위 분석을 에뮬레이트해야합니다. 어떤 언어가 지원되어야하는지에 제약이 없다면 이것은 사실상 불가능한 작업처럼 들립니다. –

답변

-1

대부분의 언어는 토큰이 문맥에 관계없이 고유 할 것이라는 점을 보증합니다. 순진 첫 번째 방법은 (이 코드의 많은, 많은 조각을 깰 것) 될 것이다 : GNU가 나오지으로,이 PHP에 휴식 것입니다

cp file file.orig 
sed -i 's/\b(newTokenName)\b/TEMPTOKEN/g' file 
sed -i 's/\b(oldTokenName)\b/newTokenName/g' file 

. \ b를 ([^ a-zA-Z ~ $ -_] [^ a-zA-Z0-9 ~ $ -_]와 같은 일반적인 토큰 일치로 재 작성하면 대부분의 C, Java, PHP 및 Python에서 작동합니다 Perl은 아니고 (토큰 문자에 @와 %를 추가해야합니다.) 그 외에도 추가하려는 언어에 대해 작동하는 플러그인 아키텍처가 필요합니다. 변수 및 함수 명명 규칙이있는 두 언어가 있습니다. 호환되지 않을 것이며 그 시점에서 플러그인에서 점점 더 많은 작업을 수행해야 할 것입니다.

+0

그래, 이렇게하는 것이 가장 쉬운 방법이라고 생각하기 시작했습니다. 비록 그것이 멍청하기는하지만 문자열 안에 대체 할 가능성이 있습니다. (흠, 문자열에 나타나는 함수 나 변수 이름의 가능성은 높습니다. 함수가 "about"일 것입니다.) 렉서 (lexer)는 전체 파서 (parser)보다 접근하기 쉬울 수 있으며,이 기술은 효과적 일 수 있습니다. – luqui

+0

사본 줄을 추가했습니다. 이 시점에서 토큰을 가진 파일 (grep과 동일한 규칙 사용)과 diff 파일 file.orig를 쉘로 감쌀 수 있습니다. 실용적인 사용에서는 빠른 사용과 프로그래머 제어 간의 좋은 조합이 될 것입니다. 이론적으로 "완벽한"솔루션은 GCC의 프론트 엔드를 많이 사용해야합니다. –

+0

@luqui : 예, 가장 쉬운 방법입니다. 거의 모든 "가장 쉬운"솔루션과 마찬가지로, 좋은 솔루션이 아닙니다. –

1

관련 언어에 대해 Xtext 기반 구현을 만들려고 할 수 있습니다 .Xtext 프레임 워크는 교차 언어 이름 바꾸기 리팩터링 그러나 문법에는 각 언어에 대해 적어도 "충분 함"범위 분석을 제공해야합니다.

+0

재미 있고 유망 해 보인다. 잘하면 사람들이 이미 자신이 좋아하는 언어에 대한 문법을 ​​작성했기 때문에 프레임 워크를 찾고 있었기 때문에 이것이 나의 희망입니다. 나는 일식 gui tho를 실행할 필요가 없기를 바란다. 나는 그것을 조사해 볼 것이다. 링크에 감사한다. – luqui

+0

Xtext는 Eclipse 기반 프레임 워크이므로 Eclipse UI를 올바르게 실행할 수 있습니다. 범용 언어를 구현 한 구문 동물원은 현재 사용할 수 없습니다. –

5

수행 할 작업 안전하다, 당신은 각각를 식별자에 대한 코드에 유효

  • 스코프 (예와없는 것들, 댓글의 중간)

    • 모든 식별자를 결정하기 위해 할 수 있어야합니다
    • 텍스트
    • 에 이전에 대한 식별자의 이름을 변경하면 다른 이름을 발생하는 경우를 결정하는 능력을 새로운 식별자를 대체 할 수있는 능력을 정확하게 식별자를 확인하려면

  • 을 그림자 수, 당신은 필요 적어도 랑지 어 - 정확한 렉서. PHP의 식별자는 COBOL의 식별자와 다릅니다.

    유효 범위를 결정하려면 대부분의 "범위"가 이러한 구조로 정의되므로 실제로 프로그램 구조를 결정해야합니다. 이것은 랭 게이지 (langauge) - 정확한 파서가 필요하다는 것을 의미합니다; PHP의 범위는 COBOL의 범위와 다릅니다.

    범위의 유효성을 확인하려면 언어 범위 지정 규칙을 알아야합니다. 당신의 언어는 X가 발견되는 문맥에 따라 식별자 X가 다른 Xes를 참조 할 것이라고 주장 할 수도 있습니다 (다른 인수를 가진 X라는 객체 생성자를 고려하십시오). 이제 명명 규칙에 따라 범위 구조를 탐색 할 수 있어야합니다. 단일 상속, 다중 상속, 오버로딩, 기본 유형 모두는 프로그램의 스코프 모델을 구축하고 각 범위에 식별자와 해당 유형을 삽입 한 다음 해당 식별자에 해당하는 지점에서 상승합니다. 언어 의미에 따라 다양한 범위를 통해 텍스트를 프로그래밍 할 수 있습니다. 심볼 테이블, 상속 링크, AST 및 이들 모두를 탐색 할 수있는 기능이 필요합니다. 이 구조는 PHP와 COBOL과는 다르지만 일반적인 개념을 많이 공유하므로 일반적인 개념을 지원하는 라이브러리가 필요할 것입니다.

    의 이름을으로 변경하면 문자를 수정해야합니다. 백만 줄의 코드에서 을 신중하게으로 지정해야합니다. AST 노드를 수정하는 것은 신중하게 가리키는 한 가지 방법입니다. 실제로 을 모두 수정해야합니다.은 이름이 바뀌는 식별자와 일치하는 식별자입니다. 나무를 넘어 모든 것을 발견하거나 AST에 기록하여 모든 참조가 존재하므로 쉽게 찾을 수 있습니다. 트리를 수정 한 후에는 AST를 수정 한 후 원본 텍스트를 재생성해야합니다. 그것은 많은 기계 장치입니다. 내 SO answer on how to prettyprint ASTs을 보면서 합리적으로 제안해야 할 모든 것들을 보존해야합니다. (AST에서 문자열의 텍스트 위치가 이고 파일 읽기/패치/쓰기를 추적하는 것이 좋습니다.)

    파일을 업데이트하기 전에 천국에 있는지 확인해야합니다 뭔가 숨겨 놨어. 다음 코드를 고려하십시오.

    { local x; 
        x=1; 
        {local y; 
        y=2; 
         {local z; 
         z=y 
         print(x); 
         } 
        } 
    } 
    

    이 코드는 "1"로 인쇄됩니다. 이제 y를 x로 바꾼다. 범위가 잘못되었습니다. 이제 을 바깥 쪽 x로 참조한 print 문은 이름이 바뀐 y가 캡처 한 x를 참조합니다. 이제 코드가 "2"를 인쇄하므로 이름이 바뀌 었습니다. 이것은 이름이 바뀐 변수가 발견 될 수있는 범위 내의 다른 모든 식별자를 검사하여 새로운 이름이 우리가 예상하지 못한 이름을 "캡처"하는지 확인해야한다는 것을 의미합니다. (print 서술문이 z로 인쇄되면 이것은 합법적입니다.)

    이것은 많은 기계류입니다.

    네, 거의 모든 강력한 언어 프런트 엔드뿐만 아니라 거의 모든 것을 포함하는 프레임 워크가 있습니다. DMS Software Reengineering Toolkit을 참조하십시오. AST를 생성하는 구문 분석기, AST에서 텍스트를 다시 생성하는 prettyprinter, 다중 상속에 대한 지원을 포함하는 일반 기호 테이블 관리 도구, AST 방문/수정 도구가 있습니다. AST를 다시 텍스트로 변환하는 사전 인쇄 기계. 이름과 타입 해석을 구현하는 front ends for C, C++, COBOL and Java을 가진다 (예를 들어, 심볼 테이블 엔트리와 심볼 테이블 엔트리 매핑에 대한 식별자 생성). 아직 구현 된 범위 지정을 가지고 있지 않은 다른 많은 언어에 대한 프론트 엔드를 가지고 있습니다.

    이제 Java의 "이름 바꾸기"구현에 대한 연습을 마쳤습니다. (위의 모든 문제는 물론 나타났습니다.) C++ 용으로 시작하려고합니다.

    관련 문제