. 분석기 수정

BeginPrint 함수는 인쇄용 GetLine 함수로 문서 전체를 정렬한 후 그 결과를 pi->pLine에 저장한다. 그래서 문법 분석기들도 화면상의 정렬 결과인 pLine을 기준으로 문서를 분석하지 말고 pi->pLine을 기준으로 정렬해야 한다. 이를 위해 인쇄용 문법 분석기를 따로 만들 필요까지는 없고 기존의 분석기 함수에 인수를 하나 더 추가하여 상황에 따라 화면용, 인쇄용 분석을 하도록 수정하면 된다.

 

struct Ae_PrintInfo;

class CParse

{

     ....

     void ParseLines(CApiEdit &ae,int nLine,Ae_PrintInfo *pi=NULL);

     virtual void ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi)=0;

};

 

class CParseNull : public CParse

{

     ....

     void ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi);

};

 

class CParseCpp : public CParse

{

     ....

     void ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi);

};

 

class CParseHtml : public CParse

{

     ....

     void ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi);

};

 

class CParseSql : public CParse

{

     ....

     void ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi);

};

 

분석기 객체에서 pLine을 참조하는 함수는 한 줄을 분석하는 ParseLine이다. 그러나 이 함수는 ApiEdit에 의해 직접 호출되지 않고 ParseLines 함수를 통해 간접적으로 호출되기 때문에 ParseLines 함수부터 수정해야 한다.

ParseLines 함수에 Ae_PrintInfo 구조체의 포인터 pi를 추가했다. 이 인수의 디폴트값을 NULL로 설정했으며 이 경우 화면용 정렬 결과인 pLine을 참고하도록 함으로써 ApiEdit의 편집코드들은 수정하지 않아도 되도록 하였다. Ae_PrintInfo ApiEdit.h에 작성되어 있으므로 CParse가 이 구조체를 인식하기 위해서 전방 선언이 필요하다. ParseLine 함수도 pi를 전달받도록 하되 디폴트 인수는 정의하지 않아도 된다. ParseLines는 전달받은 pi를 각 분석기의 ParseLine 함수로 전달하도록 수정한다.

 

void CParse::ParseLines(CApiEdit &ae,int nLine,Ae_PrintInfo *pi)

{

     ....

     for (i=l;i<=nLine;i++) {

          ParseLine(ae,i,pi);

     }

}

 

분석기의 ParseLine 함수는 pi값에 따라 참고할 정렬정보를 바꾼다. 대표적으로 C/C++ 분석기의 ParseLine 함수를 수정해보자.

 

void CParseCpp::ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi)

{

     ....

    tagLine *tLine;

 

    if (pi) {

        tLine=pi->pLine;

    } else {

        tLine=ae.pLine;

    }

     ....

    s=tLine[nLine].Start;

    e=tLine[nLine].End;

     idpos=s;

 

     switch(Context) {

     case CPP_CON_LINECOMMENT:

        if (tLine[nLine].nLine != 0) {

              MakeParseInfo(nLine,nUnit,s,CPP_STYLE_COMMENT);

              goto EndParse;

          } else {

              MakeParseInfo(nLine,nUnit,s,CPP_STYLE_NORMAL);

              Context=CPP_CON_NORMAL;

              break;

          }

     }

 

참조해야 할 pLine pi에 따라 달라지므로 tagLine형의 포인터 tLine을 선언하였다. pi NULL이면 지금까지 해 오던 방식대로 tLine ae.pLine을 대입하여 화면용 정렬 결과를 참조하며 pi가 전달되었으면 인쇄중으로 판단하고 tLine pi->pLine을 대입하여 인쇄용 정렬 결과를 참조하도록 한다. 무조건 ae.pLine만 참조했으나 pi의 값에 따라 화면용 또는 인쇄용을 선택적으로 참조할 수 있도록 수정했다. 소스의 ae.pLine은 모두 tLine으로 바꾸어 준다.

나머지 분석기들도 동일한 방법으로 ParseLine 함수를 수정하면 된다. 참조할 배열의 포인터만 바꾸는 것이므로 수정 사항이 그리 많지도 않다.

 

void CParseNull::ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi)

{

     int nUnit=0;

    tagLine *tLine;

 

    if (pi) {

        tLine=pi->pLine;

    } else {

        tLine=ae.pLine;

    }

 

    MakeParseInfo(nLine,nUnit,tLine[nLine].Start,0);

}

 

void CParseHtml::ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi)

{

     ....

    tagLine *tLine;

 

    if (pi) {

        tLine=pi->pLine;

    } else {

        tLine=ae.pLine;

    }

     ....

    s=tLine[nLine].Start;

    e=tLine[nLine].End;

     idpos=s;

 

     switch(Context) {

     ....

     case HTML_CON_PHPLINECOM:

        if (tLine[nLine].nLine != 0) {

              MakeParseInfo(nLine,nUnit,s,HTML_STYLE_PHPCOMMENT);

              goto EndParse;

          } else {

              MakeParseInfo(nLine,nUnit,s,HTML_STYLE_PHP);

              Context=HTML_CON_PHP;

              break;

          }

          break;

     case HTML_CON_ASPLINECOM:

        if (tLine[nLine].nLine != 0) {

     ....

 

void CParseSql::ParseLine(CApiEdit &ae,int nLine,Ae_PrintInfo *pi)

{

     ....

    tagLine *tLine;

 

    if (pi) {

        tLine=pi->pLine;

    } else {

        tLine=ae.pLine;

    }

     ....

    s=tLine[nLine].Start;

    e=tLine[nLine].End;

     idpos=s;

 

     switch(Context) {

     ....

     case SQL_CON_LINECOMMENT:

        if (tLine[nLine].nLine != 0) {

              MakeParseInfo(nLine,nUnit,s,SQL_STYLE_COMMENT);

              goto EndParse;

          } else {

              MakeParseInfo(nLine,nUnit,s,SQL_STYLE_NORMAL);

              Context=SQL_CON_NORMAL;

              break;

          }

     }

 

이렇게만 해두면 분석기는 주어진 정렬 결과를 참조하여 문서를 분석할 것이다. 인쇄 루틴에서는 인쇄용 분석기의 pInfo대로 출력하면 된다.