2017-12-15 50 views
0

어떻게 컴파일러는 명시 적 파스 트리를 구성하지 않고 할 수 있습니까? 명시 적 구문 분석 트리 구축의 이점과 단점은 무엇입니까?컴파일러 건축 : 명시 구문 분석 나무

은 그 컴파일러는 구문 분석하는 동안 그와 관련된 의미를 SDT를 사용하여 실행하여 명시 적 파스 트리없이 건설 할 수 있습니다 알고 있습니다. 하지만 명시 적 구문 분석 트리 구축의 이점과 단점을 알고 싶습니다.

답변

0

임 그래서 나와 함께 paitient하시기 바랍니다 멍청한 놈 ... 들으 약간의 ...

가 이

그러나 귀하의 질문에, (구문 분석 트리없이) 재귀 괜찮은 편집에 대답 만이 수행 할 수 있습니다 가장 간단한 경우는 전방 참조 및 기호가 선언의 포인트에서만 유효하고 전체 범위가 아닌 경우입니다.

는 분명히 실 거예요 자바 같은 언어와 함께 작동합니다. theres 전방 참조, 그럼 적어도 두 패스가 필요하고 세 가지 패스 theres 자바 (또는 당신이 3 미만으로 그것을 어떻게 다음 우리에게 계몽을 수행하는 방법을 알고있는 경우에 위에 overloaded 기능 위에 필요한 경우) . 이를 위해 파스 트리를 만듭니다.

간단한 구문 분석 트리 노드는 다음과 같이 보일 수 있습니다 (면책 조항 :이 실제 코드가 아닙니다).

package compiler; 
import java.util.ArrayList; 
import scanner.Token; 
import scanner.TokenSet; 

class Production 
{ 
    Token leading;  // the first token in the production 
    int productionID; // a unique integer that identifies the production 
    ArrayList<Production> childNodes; // duh 
    Production mother; // mother node (may be null) 

    public Production (Token leading, int productionID) 
    { 
     this.leading  = leading; 
     this.productionID = productionID; 
     childNodes  = new ArrayList<Production>(); 
    } 

    public void append (Production child) // add a new child node 
    { 
     child nodes.add(child); 
     child.mother = this; 
    } 

    public abstract void build1 (TokenSet follow, TokenSet anchor); // implements pass 1 
    public abstract void build2 .... 

}

그러나 훨씬 더 강력한 접근 방식은 각 제품에 대한 새로운 서브 클래스를 파생시키고 필드 변수로 자식 노드를 선언하는 것입니다. 그런 다음 productionID를 제거하고 대신 instanceof 검사를 사용할 수 있습니다. 심볼을 정의하는 노드의 주어진 하위 클래스에 심볼 인터페이스를 구현하고 노드를 심볼 테이블에 직접 삽입 할 수도 있습니다. 중첩 된 스코프를 정의하는 프로덕션도 고유 한 심볼 테이블을 가질 수 있습니다 (여기서는 그렇게하지 않을 것입니다). 요점은 이런 방식으로 통사론과 의미 론적 분석이 모두 파스 트리 구조와 심지어 최종 번역에 통합 될 수 있다는 것입니다. 유일한 아래쪽은 그 끔찍한 자바 인터페이스입니다 : LOL : 당신이 그런 식으로 할 경우

// i wont bother with imports since this isnt real code 

class DefinitionModule extends Production 
{ 
    Identifier name; 

    ArrayList<ImportClause> importClauses; 
    ArrayList<ExportClause> exportClauses; 
    ArrayList<Production> itemList; // CONST-,TYPE-, & VAR- declarators & function headers 

    public DefinitionModule() // no more productionID 
    { 
     super(lastTokenRead()); // always sits on DEFINITION 
     importClauses = new ArrayList<ImportClause>; 

    } 


    // build() 
    // 
    // DefinitionModule ::= DEFINITION MODULE Identifier ";" {ImportClause}{ExportClause}{HeaderItem} END Identifier 
    // 
    // where HeaderItem ::= ConstDeclarator | TypeDeclarator | VarDeclator | ProcedureHeader. 
    // Identifier, ImportClause, & ExportClause below are all derived from 
    // Production, above 



    public void build (TokenSet follow, TokenSet anchor) 
    { 
     Scanner.getToken(); // skip the DEFINITION 
     Scanner.expectToken(Token.ID_MODULE); // make sure MODULE is there & then skip it 
     name = name.build(new TokenSet(Token.ID_SEMICOLON)); 
     expectToken(Token.ID_SEMICOLON); 
     while (lastTokenRead()==Token.ID_IMPORT || lastTokenRead()==Token.ID_FROM) 
     { 
     ImportClause IC = new ImportClause(lastTokenRead()); 
     importClauses.add(IC.build(new TokenSet(Token.ID_SEMICOLON)); 
     Scanner.expectToken(Token.ID_SEMICOLON); 
     } 

     while (lastTokenRead()==Token.ID_EXPORT) 
     { 
     ExportClause XC = new ExportClause(lastTokenRead()); 
     exportClauses.add(XC.build(new TokenSet(Token.ID_SEMICOLON)); 
     Scanner.expectToken(Token.ID_SEMICOLON); 
     } 

     // etc, etc, etc 
    } 
} 

이 컴파일러는 주위에 자신을 구축 할 것입니다, 우리는 모듈라 2 헤더 파일을 선언 할 수 예를 들어

컴파일러의 전통적인 패스가 아닌 언어의 기능.

행운을 빕니다 ...