⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    {
        Token & token = parseParameter(p);
        if(token.type == Token::ERROR)
            break;

        if(token == Token::INTEGER)
            container->addChild(new Directory(token.value));
        else
            container->addChild(new Directory((string &)token));

        count ++;
        p.getToken(work);
    }while(work.compare(",")==0 && count < max);

    if(count < min)
        ExceptionMessage("Too few parameters [%/%]","僷儔儊乕僞偺悢偑彮側偡偓傑偡 [%/%]") << count << min << throwException;

    p.putBack(work);
    return count;
}

int ParseUnit::parseParameters(Parser & p, Directory * container, const char * paramlist)
{
    Token work;
    int count;
    string list;
    string key;
    string::size_type head,tail;

    list.assign(paramlist);

    count = 0;
    head = 0;
    tail = list.find_first_of(',');
    key = list.substr(head,tail-head);

    do
    {
        if(head == string::npos)
            ExceptionMessage("Too many parameters","僷儔儊乕僞偺悢偑懡偡偓傑偡").throwException();

        Token & token = parseParameter(p);
        if(token.type == Token::ERROR)
            break;

        if(token == Token::INTEGER)
            container->addChild(key,new Directory(token.value));
        else
            container->addChild(key,new Directory((string &)token));

        if(tail != string::npos)
        {
            head = tail + 1;
            tail = list.find_first_of(',',head);
            key = list.substr(head,tail != string::npos ? tail-head : string::npos);
            count ++;
            p.getToken(work);
        }else
            break;
    }while(work.compare(",")==0);

    if(tail != string::npos)
        ExceptionMessage("Too few parameters","僷儔儊乕僞偺悢偑彮側偡偓傑偡").throwException();

    return count;
}

//------

Directory * StaticAPI::last = NULL;

map<std::string, class ParseUnit *> & StaticAPI::container(void)
{
    static map<std::string, class ParseUnit *> _container;
    return _container;
}

Directory * StaticAPI::allocate(Directory & container, const Token & token, const char * id, bool regist)
{
    static unsigned int assignment_count = 0;
    Directory * node;

    if(!(token == Token::IDENTIFIER || token == Token::INTEGER))
        ExceptionMessage("Given token(%) is not suitable for an object identifier.","僆僽僕僃僋僩偺幆暿柤偲偟偰棙梡偱偒側偄帤嬪(%)偑巜掕偝傟傑偟偨") << token << throwException;

    if(regist && (token == Token::INTEGER && token.value <= 0))
        ExceptionMessage("Cannot assign an ID number less or equal to 0.","0埲壓偺ID斣崋傪愝掕偡傞偙偲偼偱偒傑偣傫").throwException();


    node = container.findChild(id);
    if(node != 0)
    {
        Directory::iterator scope;

        scope = node->begin();
        while(scope != node->end())
        {
            if((*scope).first.compare(token) == 0)
                ExceptionMessage("Identifier % is already used.","幆暿柤%偼偡偱偵棙梡偝傟偰偄傑偡") << token << throwException;
            ++ scope;
        }
    }else
        node = container.addChild(id);

    node = node->addChild(token);
    (*node)["#order"] = assignment_count++;

    if(token == Token::IDENTIFIER)
    {
        if(regist)
        {
            Directory * scope = container.openChild("/","identifier",token.c_str(),NULL);
            if(*scope == Directory::INTEGER)
                *node = scope->toInteger();
        }
    }else
        *node = token.value;

    last = node;
    return node;
}

//------

map<std::string, class ParseUnit *> & Directive::container(void)
{
    static map<std::string, class ParseUnit *> _container;
    return _container;
}

//------

ParserComponent::ParserComponent(void) throw() : Component(PARSER)
{}

ParserComponent::~ParserComponent(void) throw()
{}

void ParserComponent::parseOption(Directory & container)
{
    if(findOption("h", "help"))
    {
        cerr << Message(
            "Static API parser\n"
            "  -s, --source=filename     : Specify the source file\n"
            "  -idir ,--ignore-directive : Ignore directives\n"
            "  -iapi ,--ignore-api       : Ignore unknown static api\n"
            "  -t, --through             : Get unprocessed APIs through\n"
            "  --print-api               : Show registered static api list\n", 
            "惷揑API僷乕僒\n"
            "  -s, --source=僼傽僀儖柤   : 擖椡僼傽僀儖柤傪巜掕偟傑偡\n"
            "  -idir ,--ignore-directive : 僨傿儗僋僥傿僽偺夝愅傪峴偄傑偣傫\n"
            "  -iapi, --ignore-api       : 搊榐偝傟偰偄側偄API傪柍帇偟傑偡\n"
            "  -t, --through             : 張棟偟側偐偭偨API傪捠夁偝偣傑偡\n"
            "  --print-api               : 搊榐偝傟偰偄傞API偺堦棗傪昞帵偟傑偡\n");
        return;
    }

    if(findOption("-print-api"))
    {
        cerr << Message("List of Registerd Static API\n","惷揑API 堦棗\n");
        StaticAPI::printList();
        return;
    }

    checkOption("idir", "ignore-directive");
    checkOption("iapi", "ignore-api");
    checkOption("t", "through");

    if(checkOption("s","source") || checkOption(DEFAULT_PARAMETER))
        activateComponent();
}

bool ParserComponent::parseStaticAPI(Parser & p, Directory & container, Token token, const string domain)
{
    bool isParseErrorOccured = false;
    map<string, ParseUnit *>::iterator api;
    Directory * node = NULL;

    if(token.type != Token::IDENTIFIER)
        return false;

    StaticAPI::clearLastObject();
    node = container[PARSERESULT].addChild();

    try {
        node->addChild("api",new Directory(token));
        node->addChild("begin",new Directory((long)p.getLogBufferPos(-(int)token.size()-1)));
        if(!domain.empty())
            node->addChild("domain", new Directory(domain));

        api = StaticAPI::container().find(token);
        if(api == StaticAPI::container().end())
        {
            if(ignoreUnknownAPI)
            {
                cerr << Message("%: Unknown static api % was ignored. (skipped)\n","%: 旕搊榐偺API % 偼柍帇偝傟傑偡\n") << p.getStreamLocation() << token;
                do {
                    p.getToken(token);
                }while(token.compare(";") != 0);
                node->addChild("end",new Directory((long)p.getLogBufferPos()));
                (*node) = (long)0;
                return true;
            }
            ExceptionMessage("Static API [%] is not registered in the configurator", "惷揑API[%]偼枹搊榐偱偡") << token << throwException;
        }

        DebugMessage("  StaticAPI [%]\n") << (*api).first;

        p.getToken("(");

        (*api).second->body(token, container, p, domain);

        p.getToken(")");
        p.getToken(";");

        node->addChild("end",new Directory((long)p.getLogBufferPos()));
        (*node) = (long)1;
    }
    catch(Exception & e)
    {
        int offset;
        string work;
        work = p.getStreamLocation() + Message(":[Error] ",":[僄儔乕] ").str() + e.getDetails();
        isParseErrorOccured = true;

        StaticAPI::dropLastObject();
        failCount ++;

        offset = 0;
        token = p.getLastErrorToken();
        while (token != Token::ERROR && token != Token::EOS)
        {
            if( token == ";" )
                break;

                //撉傒弌偟偨僩乕僋儞偑惷揑API偲摨偠柤慜側傜 偒偭偲僙儈僐儘儞朰傟
            api = StaticAPI::container().find(token);
            if(api != StaticAPI::container().end())
            {
                cerr << Message("<The following error must be occured by lack of ';' at the end of previous line>\n","<師偺僄儔乕偼捈慜峴偺';'朰傟偵傛傞壜擻惈偑崅偄偱偡>\n");
                offset = -(int)token.size();
                p.putBack(token);
                break;
            }

            p.getToken(token);
        }

        node->addChild("end",new Directory((long)p.getLogBufferPos(offset)));
        (*node) = (long)0;

        cerr << work << '\n';

        ExceptionMessage("Fatal error on Static API parsing","惷揑API偺峔暥夝愅偵幐攕偟傑偟偨").throwException();
    }

    return true;
}

/*
 *  張棟偱偒側偐偭偨API傪昗弨弌椡偵揻偒弌偡
 */
void ParserComponent::throughConfigurationFile(string & log, Directory & container)
{
    Directory *        node;
    string::size_type  pos;
    string::size_type  begin;
    string::size_type  end;

    pos = 0;
    end = 0;

    node = container[PARSERESULT].getFirstChild();
    while(node != NULL)
    {
        begin = static_cast<string::size_type>((*node)["begin"].toInteger());
        end   = static_cast<string::size_type>((*node)["end"].toInteger());

        if(pos < begin)
            cout << log.substr(pos, begin - pos);

        if(node->toInteger() == 0)
        {
            cout << log.substr(begin, end - begin);
        }else
        {
            for(pos = begin; pos < end; ++pos)
                if( log.at(pos) == '\n' )
                    cout << '\n';
        }
        node = node->getNext();
    }

    if(end < log.size())
        cout << log.substr(end);

    ExceptionMessage("","").throwException();
}


void ParserComponent::body(Directory & container)
{
    Token token;
    Parser p(container);
    string logbuffer;
    OptionParameter::OptionItem item;
    unsigned int itemcount = 0;

    failCount = 0;
    
        //idir僆僾僔儑儞偺張棟
    if(findOption("idir","ignore-directive"))
        p.disable(Parser::DIRECTIVE);

    ignoreUnknownAPI = findOption("iapi", "ignore-api");

    if(findOption("t","through"))
    {
        p.setLogBuffer(&logbuffer);
        ignoreUnknownAPI = true;
    }

        //擖椡僜乕僗
    item = getOption("s", "source");
    item.mergeItem(getOption(DEFAULT_PARAMETER));
    if(item.countParameter() == 0)
    {
        p.pushStdStream(Message("Standard Input","昗弨擖椡").str());
        VerboseMessage("Starting parse with standard input\n","昗弨擖椡偐傜偺帤嬪夝愅傪奐巒偟傑偟偨\n");
    }

    try{
        do {
            if(item.hasParameter())
            {
                VerboseMessage("Starting parse with file[%]\n","僼傽僀儖[%]偺帤嬪夝愅傪奐巒偟傑偟偨\n") << item[itemcount];
                p.pushStream(item[itemcount]);
            }

            this->parse(p, container);

            if(p.getToken(token) != Token::EOS)
                ExceptionMessage("Buffer has remaining tokens, parsing is not yet finished", "僷乕僗偑拞抐偝傟傑偟偨").throwException();

            if(failCount != 0)
                ExceptionMessage("Total % failures found in this configuration.","%屄偺忈奞偑偁傝傑偡") << failCount << throwException;

            VerboseMessage("Parse finished\n","帤嬪夝愅偼惓忢偵廔椆偟傑偟偨\n");

        } while(++itemcount < item.countParameter());

        if(findOption("t","through"))
            throughConfigurationFile(logbuffer,container);

        container[PARSERESULT].erase();
    }
    catch(Exception & e)
    {
        string work;

        work = p.getStreamLocation() + Message(":[Error] ",":[僄儔乕] ").str() + e.getDetails();
        ExceptionMessage(work.c_str()).throwException();
    }
}

    // 僆僾僔儑儞僲乕僪偐傜妱晅曽朄傪庢摼偡傞
enum Common::tagAssignmentOrder Common::parseOrder(Directory * node)
{
    Directory * scope;
    int         i;

        //妱摉僷儔儊乕僞夝愅
    i = FCFS;
    if(node != 0)
    {
        scope = node->getFirstChild();
        while(scope != 0)
        {
            string param = scope->toString();
            if(param.compare("alphabetic") == 0 || param.compare("ALPHABETIC") == 0)
                i = (i & 0xf0) | ALPHABETIC;
            else if(param.compare("fcfs") == 0 || param.compare("FCFS") == 0)
                i = (i & 0xf0) | FCFS;
            else if(param.compare("reverse") == 0 || param.compare("REVERSE") == 0)
                i |= REVERSE;

            scope = scope->getNext();
        }
    }

    return static_cast<enum tagAssignmentOrder>(i);
}

    // 僆僾僔儑儞僲乕僪偐傜妱晅曽朄傪庢摼偡傞
enum Common::tagAssignmentOrder Common::parseOrder(OptionParameter::OptionItem item)
{
    Directory node;
    unsigned int i;

    for(i=0;i<item.countParameter();++i)
        node.addChild(item[i]);

    return parseOrder(&node);
}

    //ID抣偺傾僒僀儞儊儞僩
    //  (懠偺応強偐傜傕巊偆偺偱偙偙偵堏摦)
int Common::assignID(Directory & container, const char * category, const char * top, enum tagAssignmentOrder order)
{
    Directory * node  = 0;
    Directory * scope = 0;
    Directory * work  = 0;
    set<int> idpool;
    map<int, Directory *> sorter;
    map<int, Directory *>::iterator p_sorter;
    int i;

        //壓弨旛
    node = container.findChild(top,category,NULL);
    if(node == 0)
        return 0;

    for(i=1;i< (signed int) node->size() + 32; i++)
        idpool.insert(i);

        //妱晅弴偺寛掕偲丆妱摉嵪傒ID偺嶍彍
    i = 0;
    scope = node->getFirstChild();
    while(scope != 0)
    {
        if( *scope == Directory::INTEGER )
            idpool.erase(*scope);
        else
        {
                //廳暋柤徧偺懚嵼僠僃僢僋
            work = container.openChild("/","identifier",scope->getKey().c_str(),NULL);
            if( *work == Directory::INTEGER)
            {
                VerboseMessage("Assigning the same ID (%) since the name (%[%]) is duplicated\n","ID斣崋(%)傪堎庬摨柤偺僆僽僕僃僋僩(%[%])偵妱傝摉偰傑偡丏\n") << work->toInteger() << scope->getKey() << category;
                idpool.erase(*scope = work->toInteger());
            } else
            {
                    //妱摉曽朄偵廬偭偰妱摉岓曗偵捛壛
                switch(order)
                {
                case ALPHABETIC:
                    sorter[i++] = scope;
                    break;
                case REVERSE_ALPHABETIC:
                    sorter[i--] = scope;
                    break;
                case FCFS:
                default:
                    sorter[scope->openChild("#order")->toInteger()] = scope;
                    break;
                case REVERSE_FCFS:
                    sorter[-scope->openChild("#order")->toInteger()] = scope;
                    break;
                }
            }
        }
        scope = scope->getNext();
    }

        //ID妱摉
    p_sorter = sorter.begin();
    while(p_sorter != sorter.end())
    {
        scope = (*p_sorter).second;
        if( !(*scope == Directory::INTEGER) )
        {
            i = *(idpool.begin());
            idpool.erase(idpool.begin());

            work = container.openChild("/","identifier",scope->getKey().c_str(),NULL);
            *work = i;
            *scope = i;
        }
        ++ p_sorter;
    }

        //妱摉昞嶌惉
    if(node->size() != 0 && VerboseMessage::getVerbose())
    {
        VerboseMessage("Object ID assignment list [%]\n","僆僽僕僃僋僩ID妱晅昞 [%]\n") << category;

        sorter.clear();
        scope = node->getFirstChild();
        while(scope != 0)
        {
            sorter[scope->toInteger()] = scope;
            scope = scope->getNext();
        }

        p_sorter = sorter.begin();
        while(p_sorter != sorter.end())
        {
            VerboseMessage("  % : %\n") << setw(3) << (*p_sorter).first << (*p_sorter).second->getKey();
            ++ p_sorter;
        }
    }

        //懨摉惈偺敾掕
    if((signed)node->size()+1 != *(idpool.begin()))
        ExceptionMessage("Discontinuous % ID assignment occured","晄楢懕側僆僽僕僃僋僩ID(%)") << category << throwException;

    return node->size();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -