Лексический анализатор HTML в С++, как распечатать результаты

Я надеюсь, что кто-то может помочь мне снова с этой проблемой. Я создаю лексический анализатор HTML на С++. По словам учителя, у меня должно быть 3 файла. один заголовок и 2 основных .cpp, и он должен иметь возможность читать файл Это мой файл try.txt

<<<<<Hello there <H1 style=”BOLD”>header!!</H1> 
<<
<< =

Это мой заголовок

#ifndef tokens_h
#define tokens_h
#include <string>
#include <iostream>

            enum tokens {TEXT, LANGLE = 60, RANGLE = 62, SLASH = 47, ID, EQ = 61, QSTRING = 34, OTHER, END};

/* TEXT    = 0
   LANGLE  = 60
   RANGLE  = 62
   SLASH   = 47
   ID      = 48
   EQ      = 61
   QSTRING = 34
   OTHER   = 36
   END     = 36

*/
            int getToken(std::istream *br, std::string a);

#endif

Это мой main.cpp

#include <iostream>
#include <fstream>
#include <vector>
#include "tokens.h"


using namespace std;

int main(int argc, char *argv[])
{
    //defineTokens();
    istream *br;
    ifstream infile;
    string output;
    int a;
    vector<int> count;
    int langle = 0;

            string line;
    if(argc == 1){
        while(cin.good() ){     //Get continous input
                br = &cin;

           getline(cin,line);
           getToken(br,line);
       }
    }
    else if(argc != 2){
        return 1;
    }else{
        infile.open(argv[1]);
        if( infile.is_open()){
            br = &infile;
            while(!infile.eof()){
            getline(infile,output);
        getToken(br,output);
            }
        }

        else{
            cout << argv[1] << "Can't Be Opened" << endl;
            return 1;
        }
    }
}

а это мой файл tokens.cpp, где я печатаю результаты

#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <map>
#include <utility>
#include "tokens.h"



using namespace std;

void compar(int ch)
{
    vector<int> text;
    vector<int> langle;
    //string langle;
    vector<int> rangle;
    vector<int> slash;
    vector<int> id;
    vector<int> eq;
    vector<int> qstring;
    vector<int> other;
    map <string, int> result;
    int c=0;
    int d=0;
    int sum;
    string r;

    switch(ch){
        case 60:static int countlangle = 0;
                countlangle ++;
                result["LANGLE"]= countlangle; 
                cout << "LANGLE: " << result["LANGLE"] << " ";
                break;

        case 62:static int countrangle = 0;
                countrangle ++;
                result["RANGLE"]= countrangle; 
                cout << "RANGLE: " << result["RANGLE"] << " ";
                break;

        case 47:static int countslash = 0;
                countslash ++;
                result["SLASH"]= countslash; 
                cout << "SLASH: " << result["SLASH"] << " ";
                break;      

        case 61:static int counteq = 0;
                counteq ++;
                result["EQ"]= counteq; 
                cout << "EQ: " << result["EQ"] << " ";
                break;                                      

        case 34:static int countqstring = 0;
                countqstring ++;
                result["QSTRING"]= countqstring; 
                cout << "QSTRING: " << result["QSTRING"] << " ";
                break;  
    }


}
int getToken(istream *br, string a)
{

    int b;
    string d = "no";
    string f = "no";
    string r;
    vector<char> st;
    vector<string> trial;
    vector<int> countr;
    vector<int> countl;
    vector<char> quotes;
    string ans;
    int x=0;

    r = a;
    cout << a[27];


     int found;
            found = a.find('\"');
                        cout << found<<"XXxxxxxX";  


        for(int i = 0; i< a.length();i++){  //read entire string
        if(a[i] == '<'){
            // cout << LANGLE << " "; 
            d="yes";
            x +=1;
            countr.push_back(LANGLE);
            //cout << count.size();
            //cout << x;
            compar(LANGLE);
            b =LANGLE;

    //    return LANGLE;
        }
        else if(a[i]== '>' && d == "yes"){
            f = "yes";
            b = RANGLE;  //assing to the int variable the value from the enum header
            compar(RANGLE);

        }
        else if(a[i]== '/' && d == "yes"){
            compar(SLASH);

        }
        else if(a[i] == '=' && d == "yes"){
            compar(EQ);

        }
        else if(a[found] == '\"' && d == "yes"){

           //   for(int k =0;k < quotes.size();k++)
            //cout << r[found] <<"XXX"; 
            compar(QSTRING);

        }   

        }
    return 0;
}

Учитель хочет, чтобы программа печатала только окончательное значение каждого случая. Однако, когда я печатаю, я получаю это

LANGLE: 1 ID: 1 EQ: 1 ID: 2 RANGLE: 1 ID: 3 LANGLE: 2 SLASH: 1 RANGLE: 2 LANGLE: 3 ID: 4 RANGLE: 3 LANGLE: 4 LANGLE: 5 LANGLE: 6 ID: 5 RANGLE: 4 LANGLE: 7 LANGLE: 8 EQ: 2 

Есть ли способ получить что-то подобное?

LANGLE = 8
RANGLE = 4
EQ = 2
SLASH = 1
ID = 4

заранее спасибо


person elctronyc    schedule 19.10.2014    source источник


Ответы (1)


Вы вызываете функцию compar() несколько раз и выводите текущее количество токенов при каждом вызове. Это даст вам каждое промежуточное значение количества каждого токена.

Попробуйте изменить функцию compar(), чтобы она увеличивала только счетчики. НЕ печатайте в нем значения. Как только все содержимое будет проанализировано, напечатайте пары значений токена, перебирая карту.

person Sinstein    schedule 19.10.2014
comment
Я пытался печатать после переключения, но получаю 11111122233345666788. Должен ли я печатать в другом месте? Как это сделать? Благодарность - person elctronyc; 19.10.2014
comment
Печать его вне коммутатора не решит проблему, так как он печатается каждый раз, когда вызывается compar(). Напечатайте значения в конце цикла, который считывает строки, т. е. напечатайте непосредственно перед концом основной функции. Поймите, что вам нужен подсчет после того, как все строки будут проанализированы. Итак, где бы ни заканчивался весь синтаксический анализ, распечатайте список. - person Sinstein; 19.10.2014
comment
Я просто чувствую себя таким глупым прямо сейчас, потому что я не могу понять это. Я думаю, что брошу программирование, уеду высоко в горы и останусь там навсегда. Спасибо за попытку помочь мне. - person elctronyc; 20.10.2014
comment
@electronyc Я могу понять ваше разочарование, но я думаю, что вы недалеки от того, чтобы понять это. Давайте пробежимся по вашему коду один раз. Что делает main.cpp? Он извлекает содержимое всего файла, а затем передает его tokens.cpp или только строку за строкой? - person Sinstein; 20.10.2014
comment
Он читается построчно, но я получил настоящий бумер от профессора. он сказал, что это по электронной почте getToken должен читать. второй аргумент getToken - это то, что передается обратно ИЗ getToken, а не то, что передается. Я получал каждую строку и передавал их через getToken. У меня нет времени модифицировать свою программу, поэтому я действительно сдаюсь. Думаю, мне предстоит пройти долгий путь, прежде чем я стану хорошим программистом. Спасибо за помощь - person elctronyc; 20.10.2014
comment
@elctronyc Это относится ко всем нам. Если бы это было не так, у нас не было бы этого огромного сообщества людей, пытающихся помочь друг другу :). Я понимаю, что это было поручение, но это не причина не выполнять его сразу после установленного срока. Вернитесь к проблеме. - person Sinstein; 20.10.2014
comment
Спасибо, что сказали мне продолжать. Срок выполнения был перенесен на пятницу и остался до 7 часов утра, и я смог решить большую часть того, что меня беспокоило. Я не дочитал все из-за нехватки времени и потому, что я не мог понять, как что-то читать, но со временем я разберусь. Спасибо еще раз - person elctronyc; 26.10.2014