📄 parser.cpp
字号:
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 + -