확실히. Program Transformation Tools (PTS)을 확인하십시오. 이러한 도구는 문법을 정의하고, 해당 문법을 사용하여 원본 텍스트를 AST로 구문 분석하고, AST를 텍스트로 미리 미리 인쇄 할 수있는 방법을 제공합니다. 더욱 중요한 것은 동일한 문법을 사용하여 변형을 직접 표현할 수있는 (또는 재 작성 세트의 관점에서 복합 변형을 표현할 수있는) 변형 규칙 소스 변환을 읽는 것입니다. 이러한 변형은 표현 된 패턴을 사용하여 AST와 일치시키고 AST를 수정합니다. 이러한 변환은 구조 기반이므로 레이아웃이나 공백으로 혼동하지 않습니다.
rule rule_name(pattern_variables)
: pattern_syntax_category -> replacement_syntax_category
= metaquote pattern_text_in_specified_language metaquote
=> metaquote replacement_text_in_specified_language metaquote
if condition_over_bound_pattern_variables;
: 예를 들어
, 우리 DMS 소프트웨어 재 설계 Toolkit은 당신이 볼 경우, 일반적인 형식을 가지고, 그에 의해 대체 양식
에서 규칙을 작성할 수 - 규칙은 규칙을 소개하는 구문이며
- 규칙 이름은 r ULE 이름이 다른 규칙과
- pattern_variables를 구별하기 쌍 N의 목록이다 : 패턴 변수 명의 C N 및 문법 카테고리 N 만족해야 C,
- pattern_syntax_category는 pattern_text 만족해야 문법 카테고리
- replacement_syntax_category 01,238이고은 replacement_text이 만족해야하는 구문 범주입니다. 보통, 그리고 여기에 주어진 모든 예에서, 은 과 동일합니다. pattern_syntax_category; 다시 쓰기 규칙을 사용하여 언어 간을 변환 할 때 언어의 구문 범주가 다르기 때문에 이러한 규칙은 종종 다릅니다.
- metaquote는 작성된 "패턴 변수를 포함하는, 소스 언어의 잘 형성 단편 인 패턴 또는 여분의 언어 구문
- pattern_text_in_specified_language와는 룰 언어 구문 seperates 문자 N 인 \ n; 패턴 일치는 패턴 변수를 하위 트리에 바인딩합니다. \ n이 패턴에서 두 번 나타나면 두 인스턴스는 동일해야합니다.
- replacement_text_in_specified_language은 대상 언어의 잘 형성된 부분입니다. 대리자로 대체 됨 lacement 바운드 패턴은 조건을
- condition_over_bound_pattern_variables 도입 구문은
- 경우 변수 값에 의해 치환 된 치환 어떤 패턴 변수 패턴 매치가 발견 된 후, 패턴 변수가 만족해야하는 제약이있다. 이것은 만족해야만하는 상황을 점검하는 데 자주 사용됩니다.
DMS는 쓸 수 및 (OP의 예를 몇 가지 포함) 다음 예제 변환이 적용됩니다 :
default domain Java~v8; -- specify v8 dialect of Java to manipulate
rule reduce_strength_squared(e: term):
:product -> product
= "\e^2 " ==> "\e * \e "
if no_side_effects(e);
rule optimize_divide_by_self(e: term):
:product -> product
= " \e/\e " => " 1 " if is_not_zero(e);
rule accumulate_string(n: IDENTIFIER, a: expression, b: left_hand_side)
: statement -> statement
= "for (String \s: \a) { \b.add(\s); }"
=> "\b.addAll(\a);";
rule eliminate_useless_if(x: expression, s: statement)
: statement -> statement
= "if (\x) \s; else \s; " -- generalizes OP's example
=> "\s;";
rule left_factor_ternary(x: expression; t: left_hand_side; a: expression; b:expression)
: statement -> statement
= "if (\x) { \t = \a;} else {\t = \b;} "
=> "\t = \x ? \a : \b ";
rule convert_to_diamond(T1: qualified_path, T2: qualified_path,
C: qualified_path,
i: IDENTIFIER, a: arglist)
:statement -> statement
= "\T1<\T2> \i = new \C<\T2>(\a);"
=> "\T1<\T2> \i = new \C<>(\a);"
rule merge_multi_catch(b:body, i1: IDENTIFIER, e1: qualified_path,
i2: IDENTIFIER, eh: body )
:statement -> statement
= "try { \b }
catch (\i1: \e1) { \eh }
catch (\i2: \e1) { \eh }";
=> "try { \b }
catch (\i1, \i2: \e1) { \eh }";
더 복잡한 변환이 멀리 떨어져 그 프로그램의 일부에 영향을주는 것을 포함하여, 가능을 소스 파일 경계를 넘어서조차도. 여기에는 대개 몇 가지 추가 메타 프로그래밍 (여기서는 설명하지 않음)이 필요하며 상황에 따라 식별자 (예 : 식별자가 올바른 유형 등)가 추가로 필요합니다. [DMS에는이를 지원하는 Java의 전체 기호 테이블이 있습니다.]
다른 PTS도 비슷한 방식으로 규칙을 표현할 수 있습니다. 대부분의 사람들은 심볼 테이블이나 타입과 같은 더 깊은 의미 론적 사실에 대한 지원을 제공하지 않는다.하지만 주장은 당신이 직접 프로그래밍 할 수 있다는 것이다. 경험에 의하면이 작품은 작품 인이며 실제 옳기를 원합니다. (누구가 나쁜 정보에 작동하고 있기 때문에 그들의 전이가 부호를 손상하기 원하는가?).
질문이 주제와 관련이 없습니다. * (x)가 true를 반환하는 경우 Stack Overflow * – meskobalazs
에 대해 책, 도구, 소프트웨어 라이브러리, 자습서 또는 기타 오프 사이트 리소스를 권장하거나 찾도록 요청하는 질문이 있습니다. → x를 반환; ??? –
@Ira 좋은 지적, 그건 엉 오류 :) 편집 – Marcin