2012-09-27 6 views
0

저는 C++의 초보자이며 수표가 예상대로 작동하도록하려고했습니다. 그러나 거의 모든 테스트에서 사실로 돌아 왔습니다. 단지이 경우 true를 반환하는 가정 것 :태그 유효성을 검사하는 C++ 프로그램

<red> Red blank <dim> I'm now dim and red. </dim> </red> 

그러나 지금 때이뿐만 아니라 true를 돌려 :이

<red> Blah I'm red.<dim> Im dim now </red> </dim> 

나 :

<red> blah <im dim now 

그래서 내가 궁금 해요 내 코드에서 간과 할 부분이 있습니다.

bool is_well_formed(ifstream& ifs, string& error_msg) { 

string fname,line; 
Token tok; 
Lexer lexer; 
tags.insert("blue"); 
tags.insert("red"); 
tags.insert("cyan"); 
tags.insert("white"); 
tags.insert("yellow"); 
tags.insert("magenta"); 
tags.insert("dim"); 
tags.insert("underline"); 
tags.insert("bold"); 

stack<string> tagstack; 
while (getline(ifs, fname)) { 
    // tries to open the file whose name is in string fname 

    if (ifs.fail()) { 
     cerr << "ERROR: Failed to open file " << fname << endl; 
     ifs.clear(); 
    } else { 
     while (getline(ifs, line)) { 
      lexer.set_input(line); 
      while (lexer.has_more_token()) { 
       tok = lexer.next_token(); 
       string tmpTok = tok.value; 
       switch (tok.type) { 
       case TAG: 

        // If it has /, remove/from tmpTok 
       if (tok.value[0] == '/') { 
        // If it's a closing t 
         tmpTok = tmpTok.substr(1,tmpTok.length()-1); 
        } 
        if(tags.find(tmpTok) == tags.end()) { 
        // Check whether the encountered tag is valid 
        error_return("Tag " + tmpTok + " is invalid!"); 
        return false; 
        } else { 
        // Valid Tag encountered 

        tagstack.push(tmpTok); 
        // Check if the tags are formed properly 
          if (tmpTok.find('/')) { 
          // Remove/from tmpTok 
          string closingTag = tmpTok; 
           string openingTag = tagstack.top(); 
           tagstack.pop(); 
        if(closingTag.compare(openingTag) != 0) { 
         error_return(closingTag+"doesn't match" +openingTag); 
         return false; 
         } //else 
            // return true; // if the file is well formed 
       }/**else{ 
        tagstack.push(tmpTok); 
       }*/ 
        }// else end  

        break; 
       case IDENT: 
        // cout << "IDENT: " << tok.value << endl; 
        break; 
       case ERRTOK: 
        error_return("Syntax error on this line\n"); 
        return false; 
        //cout << "Syntax error on this line\n"; 
        break; 
       case ENDTOK: 
        break; 
       } 
      } 
     } 
    } 
} 
return true; // if the file is well-formed 
} 
+0

태그 스택이 너무 짧습니다. 하나 이상의 태그를 볼 수 있도록 함수의 맨 위에 선언해야합니다. 다른 문제가있을 수 있지만 프로그램의 완전한 편집 가능한 텍스트가 없으면 너무 분명하지 않은 것을 찾기가 실제로 불가능합니다. –

답변

1
이 간단한 뭔가를

(및이 - 알고 - 무슨 - 누구 요 - 야 - 수 - XML ​​실제 구문 분석의 기회 의미하지 않기 때문에이 단순해야 함) 몇 가지 다른 수를 그러나 직접적인 문제는 직접적입니다.

stack<string> tagstack 선언을 라인 단위 루프 외부로 옮기는 것이 좋으며, 전체 처리 루프 외부에서 수행하는 것이 더 좋습니다. 스택에 태그를 집어 넣고 선언 된 곳의 else{} 블록의 범위를 끝내 자마자 바로 그 자리에 앉습니다. 그 상태는 사라집니다.

상태 시스템이 좀 더 견고하게 작동하기는하지만 또 다른 문제이므로 태그 스택의 범위를 먼저 수정하십시오.

디버거아래에서 실행해야합니다. 알고있는 모든 전문 C/C++ 엔지니어가 생산 수명의 절반을 소비하기 때문에 익숙해 져야합니다. 그것은 사업과 함께 제공됩니다. 즉, 내가 다시 당신에게 이러한 질문을 신혼 있습니다하지 여기에 대답하지만, 렉서는 반환하지 않을 경우 어떻게됩니까 디버거

  1. 에 다시 조사하는 것이 대한 진정한 복귀했다되고 토큰 유형의 TAG?
  2. 렉서가 TAG 유형의 토큰을 리턴하지만 '/'로 시작하지 않으면 어떻게됩니까?
  3. 렉서가 TAG의 토큰 유형을 반환하고 '/'로 시작하지만 '/'를 잘라내려면 어떻게됩니까?

코드의 한 곳에서 '/'에 대한 토큰의 첫 번째 문자를 확인하는 것처럼 보입니다. 두 줄 이후에 시작 및 끝 요소 마커 ' < '및'> ' 구체적으로 :

if (tok.value[0] == '/') { 
    // If it's a closing t 
    tmpTok = tmpTok.substr(1,tmpTok.length()-1); 
} 

이 두 코드 줄은 닫는 태그와 일치하지 않습니다. 먼저 <>이 제거되었다는 것을 나타내는 선도 '/'가 있는지 확인합니다. 다음 줄에서는 인 것처럼이 여전히 존재하는 것처럼 문자열에서 선두 및 꼬리 문자를 제거합니다. 그러나 그들이 존재하지 않는다면 무엇을 할 수 있습니까? (그렇지 않을 수도 있습니다. 그렇지 않으면 '/'에 대한 수표가 틀렸을 것입니다.) 지금 그것을 보시겠습니까? '/'를 잘라내는 것입니다. 코드 아래로 더 멀리보십시오, 우리는 발견 : '/'에 대한 체크 내부 코드의

if (tmpTok.find('/')) { 
    // Remove/from tmpTok 
    string closingTag = tmpTok; 
    string openingTag = tagstack.top(); 
    tagstack.pop(); 
    if(closingTag.compare(openingTag) != 0) { 
     error_return(closingTag+"doesn't match" +openingTag); 
     return false; 
    } //else 
} 

NONE 당신이 그냥 잘라 때문에 실행하려고하지 않습니다. 따라서 전체 토큰을 추가 토큰을 추가 한 후 모든 토큰 토큰을 추가 한 다음 줄이 없게하고 presto를 반환합니다. 실제로 파일 끝에있는 태그 스택에 LEFT가 있으면 거기에 불균형이 있어야하며 따라서 오류이 있어야합니다. 전체 평가의 일부로 조건부 검사에 넣으면 잘못된 필터링을 보게됩니다.

이제 디버거으로 연결하십시오. 나는이 모든 것을 단지 코드를 열람하는 것으로 발견했다. 실제적으로 을 실행하는 동안 볼 수있는 것들을 상상해보십시오. 실시간으로 변경 사항을 볼 수있는 디버거에서 라인 단위로을 실행합니다.

+0

전체 루프 외부에 있다고 변경했지만 여전히 모든 것을 true로 반환합니다. – user1513323

+0

위의 수정 사항을 참조하십시오. 나머지는 당신에게 달렸습니다. – WhozCraig

관련 문제