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

📄 parser.cpp

📁 JAPAN RTOS TOPPERS/JSP kernel 1.4 PreRelease simulation environment JSP kernel Windows simulation
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if(max == 0)
		max = min;

	do
	{
		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) : Component(PARSER)
{}

ParserComponent::~ParserComponent(void)
{}

void ParserComponent::parseOption(Directory & container)
{
    if(findOption(container, "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(container, 0, "print-api"))
    {
		cerr << Message("List of Registerd Static API\n","惷揑API 堦棗\n");
        StaticAPI::printList();
        return;
    }

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

	checkOption(container, "s", "source");

	if(mergeOption(container, "s", DEFAULT_PARAMETER) != 0 || mergeOption(container, "s", "-source") != 0)
		activateComponent();
}

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

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

	isParseErrorOccured = 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;

		dumpContainerSnapshot(container);
		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);
    Directory * scope;
	string logbuffer;

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

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

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

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

    try{
        do {
            if(scope != 0)
            {
                VerboseMessage("Starting parse with file[%]\n","僼傽僀儖[%]偺帤嬪夝愅傪奐巒偟傑偟偨\n") << scope->toString();
				p.pushStream(*scope);
            }

			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(scope != 0 && (scope = scope->getNext()) != 0);

		if(findOption(container,"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);
}


    //ID抣偺傾僒僀儞儊儞僩
    //  (懠偺応強偐傜傕巊偆偺偱偙偙偵堏摦)
int Common::assignID(Directory & container, const char * category, const char * top, enum tagAssignmentOrder order)
{
	Directory * node;
	Directory * scope;
	Directory * work;
	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 + -