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

📄 parser.cpp

📁 JAPAN RTOS TOPPERS/JSP kernel 1.4 PreRelease simulation environment JSP kernel Windows simulation
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			if(!unsigned_suffix && (ch == 'u' || ch == 'U'))
			{
				token += static_cast<char>(ch);
				ch = getChar();
			}
		}
	}

	if(minus)
		token.value = - token.value;

	if(ch != -1)
		putBack(static_cast<char>(ch));

	return true;
}


 /*
  *  僆儁儗乕僞(摿庩暥帤偺慻崌偣偐傜側傞僩乕僋儞)偺愗弌偟
  */
bool Parser::getOperator(Token & token, int ch)
{
	const char * work;

		/* ch偑僆儁儗乕僞暥帤偱偁傞偐偳偆偐妋偐傔傞 */
	for(work = Operator;*work != '\x0' && *work != ch;work++);
	if(*work == '\x0')
		return false;

		/* 屻懕偡傞暥帤傕僆儁儗乕僞暥帤偱偁傞偐偳偆偐妋偐傔傞 */
	do {
		token += static_cast<char>(ch);
		ch = getChar();
		for(work = Operator;*work != '\x0' && *work != ch;work++);
	} while(*work != '\x0');

	putBack(ch);
	token.type = Token::OPERATOR;
	return true;
}


 /*
  *  暥帤楍儕僥儔儖 (僟僽儖僋僅乕僩偱妵傜傟偨暥帤)
  *    丒僔儞僌儖僋僅乕僩傕嫋偡傛偆偵偟偨
  *
  *    VisualStudio6.0偱僐儞僷僀儖偟偨応崌丄夵峴偑LF偺僼傽僀儖偵懳偟偰tellg屻偵
  *    get偡傞偲EOF偑曉傞偨傔丄摨張棟傪僐儊儞僩傾僂僩偟偰偍偔丅
  */
bool Parser::getStringLiteral(Token & token, int delimitor)
{
	int ch;
	int prev;

    ch = delimitor;

	token.value = 1;
	token.type = Token::STRINGLITERAL;
    token.assign("");
    token += static_cast<char>(ch);

    while(!current->stream->bad() && !current->stream->eof())
    {
    	prev = ch;
	    ch = getChar();
        token += static_cast<char>(ch);
        token.value ++;

        if(ch == delimitor && prev != '\\')
            return true;
    }

		//偄偭偨傫暵偠偰嵞僆乕僾儞偟偰丄儕僥儔儖奐巒偺 " 偺師偵堏摦
	
	ExceptionMessage(ExceptionMessage::FATAL, "Unterminated string literal appeared.","暵偠傜傟偰偄側偄暥帤儕僥儔儖傪専弌偟傑偟偨").throwException();
    return false;
}


 /*
  *  僩乕僋儞偺愗弌偟
  */
enum Token::tagTokenType Parser::getToken(Token & token, bool allow_space)
{
	int ch;
	const char * work;

	do {
		token.erase();
		token.type = Token::ERROR;
		token.value = 0;

			//僩乕僋儞僗僞僢僋偐傜愗傝弌偡
		if(!TokenStack.empty())
		{
			do {
				token = TokenStack.front();
				TokenStack.pop_front();
			} while(!TokenStack.empty() && !allow_space && token.type == Token::SPACE);

			if(!allow_space && token.type != Token::SPACE)
				return token.type;
		}

			//僗僩儕乕儉偐傜愗傝弌偡
		if(current == NULL || current->stream == NULL || current->stream->bad())
		{
			token.assign("<End of stream>");
			return (token.type = Token::EOS);
		}

			//僇儗儞僩偺僗僩儕乕儉偑嬻偵側偭偨
		if(current->stream->eof())
		{
				//僼傽僀儖僗僞僢僋偐傜師偺僗僩儕乕儉傪庢傞
			if(!fileStack.empty())
			{
				if(current->stream != &cin)
					delete current->stream;
				delete current;
				
				current = *fileStack.begin();
				fileStack.pop_front();
			}else
			{
				token.assign("<End of stream>");
				return (token.type = Token::EOS);
			}
		}

		ch = getChar();

			//First(whitespaces) is [ \n\t\r/#]
		if( (ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\r') || (ch == '/') || (isHeadofLine && ch == '#'))
		{
			if(ch == '\n')
				isHeadofLine = true;

			if(getWhitespace(token, ch, allow_space))
				if((token == Token::SPACE && allow_space) || !(token == Token::SPACE || token == Token::ERROR))
					return token.type;

			continue;
		}else
			break;
	}while(true);

    isHeadofLine = false;

    token.line = current->line;

		//First(identifier) is [a-zA-Z_]
	if(	(ch >='a' && ch <= 'z') || (ch >='A' && ch <= 'Z') || (ch == '_') )
		if(getIdentifier(token, ch))
			return Token::IDENTIFIER;

		//First(integer) is [\-0-9]
	if( (ch >='0' && ch <='9') || (ch == '-') )
		if(getInteger(token,ch))
			return Token::INTEGER;

		//First(string) is ["']
	if( ch == '"' || ch == '\'')
		if(getStringLiteral(token,ch))
			return Token::STRINGLITERAL;

		//Operator
	if(getOperator(token,ch))
		return Token::OPERATOR;

		//Punctuator
	work = Punctuator;
	while(*work != '\x0')
		if( *(work++) == ch )
		{
			token += static_cast<char>(ch);
			return (token.type = Token::PUNCTUATOR);
		}

	token += static_cast<char>(ch);
	token.type = Token::UNKNOWN;
	return Token::UNKNOWN;
}


 /*
  *  僩乕僋儞梡 僗僩儕乕儉僆儁儗乕僞 (庡偵僥僗僩栚揑)
  */
ostream & operator << (ostream & out, Token & src)
{
	switch(src.type)
	{
	case Token::IDENTIFIER:
		out << "<IDENTIFIER:["; break;
	case Token::INTEGER:
		out << "<INTEGER:["; break;
	case Token::STRINGLITERAL:
		out << "<STRINGLITERAL:["; break;
	case Token::STRING:
		out << "<STRING:["; break;
	case Token::OPERATOR:
		out << "<OPERATOR:["; break;
	case Token::PUNCTUATOR:
		out << "<PUNCTUATOR:["; break;
	case Token::RESERVEDWORD:
		out << "<RESERVEDWORD:["; break;
	case Token::SPECIAL:
		out << "<SPECIAL:["; break;
	case Token::SPACE:
		out << "<SPACE:["; break;
	case Token::UNKNOWN:
		out << "<UNKNOWN>"; return out;
	case Token::ERROR:
		out << "<ERROR>"; return out;
	default:
		out << "<???:[";
	}

	return out << static_cast<string &>(src) << "]("<<src.value<<")>";
}


 /*
  *  梊栺岅偺愗弌偟(偲偄偆傛傝傕妋擣)
  */
void Parser::getToken(const char * term, const char * second, ...)
{
    Token token;
	va_list vl;

    if(term == NULL)
        ExceptionMessage("Internal: GetToken received an empty string as reserved word.","撪晹僄儔乕: GetToken偵嬻暥帤楍偑搉偝傟傑偟偨").throwException();

	va_start(vl, second);
	vl = (char *)vl - sizeof(const char *);

	do {
		getToken(token, false);
		if(token.compare(term) != 0)
		{
			lastErrorToken = token;
			ExceptionMessage("Token [%] should be replaced by [%]","帤嬪[%]偼[%]偱偁傞傋偒偱偡") << token << term << throwException;
		}
		term = va_arg(vl, const char *);
	}while(term != 0);
}

string Parser::getStreamLocation(void)
{
	list<tagFile *>::iterator scope;

	string location;
	char buffer[16];

	if(current == 0)
		return string("");

	::sprintf(buffer, ":%d", current->line);
	location += current->identifier;
	location += buffer;

	if(!fileStack.empty())
	{
		location += " (included at ";

		scope = fileStack.begin();
		while(scope != fileStack.end())
		{
			::sprintf(buffer, ":%d, ", (*scope)->line);
			location += (*scope)->identifier;
			location += buffer;

			++ scope;

		}

		location.erase(location.size()-2);
		location += ")";
	}

	return location;
}

void Parser::pushStream(const std::string & filename, std::string strid)
{
	fstream * fin;

	if(current != 0)
		fileStack.push_front(current);
		
	fin = new fstream(filename.c_str(),ios::in);

	if(fin->is_open())
	{
		if(strid.size() == 0)
			strid = filename;

		current = new tagFile;
		current->stream     = fin;
		current->identifier = strid;
		current->line       = 1;
	}else
	{		
		ExceptionMessage("File operatation failure : [%]","僼傽僀儖憖嶌偵幐攕偟傑偟偨 [%]") << filename << throwException;
		delete fin;
	}
}

void Parser::pushStdStream(std::string strid)
{
	stringstream * work = new stringstream;
	char buffer[1024];
	int  count;

		//昗弨擖椡偺忣曬傪偡傋偰庢傝崬傓 (僄儔乕懳張梡偵 seekg/tellg 傪巊偄偨偄)
	do {
		cin.read(buffer, 1024);
		count = cin.gcount();
		work->write(buffer, count);
	} while(count != 0);

	if(current != 0)
		fileStack.push_front(current);

	current = new tagFile;
	current->stream     = work;
	current->identifier = strid;
	current->line       = 1;
}

string * Parser::setLogBuffer(string * buffer)
{
	string * old = LogBuffer;
	LogBuffer = buffer;
	PutBackCount = 0;
	return old;
}

streampos Parser::getLogBufferPos(int offset)
{
	streampos pos;
	
	pos = 0;
	if(LogBuffer != 0)
		pos = LogBuffer->size();
	pos += static_cast<streampos>(offset - PutBackCount);
	return pos;
}

void Parser::doPreProcess(const char * cmd)
{
	string         tempfilename;
	char           buffer[1024];
	int            count;
	fstream        tempfile;
	string         work;
	stringstream * stream;

	if(current == NULL || current->stream == NULL)
		ExceptionMessage("No stream specified for processing","張棟懳徾偲側傞僗僩儕乕儉偑愝掕偝傟偰偄傑偣傫").throwException();


		/* 崱偺僗僩儕乕儉偺撪梕傪偡傋偰僥儞億儔儕偵彂偒弌偡 */

	strcpy(buffer,"cfgXXXXXX");
	mktemp(buffer);

	tempfilename.assign(buffer);
	tempfile.open(tempfilename.c_str(),ios::out);

	if(!tempfile.is_open())
		ExceptionMessage("Failed to open a temporary file","僥儞億儔儕僼傽僀儖偺嶌惉偵幐攕偟傑偟偨").throwException();

	do {
		current->stream->read(buffer, 1024);
		count = current->stream->gcount();
		tempfile.write(buffer, count);
	} while(count != 0);
	tempfile.close();


		/* 僗僩儕乕儉嵎偟懼偊 */

	preprocessname = tempfilename;
	originalname   = current->identifier;

	if(current->stream != &cin)
		delete current->stream;
	stream = new stringstream;
	current->stream = stream;


		/* 僾儕僾儘僙僢僒偺婲摦 & 弌椡偺庢傝崬傒 */

	work  = string(cmd) + " " + tempfilename;
	VerboseMessage(" Start the external preprocessor [%]\n"," 奜晹僾儘僌儔儉傪婲摦偟傑偡 [%]\n") << work;

	FILE * pipe = popen(work.c_str(),"r");
	while(feof(pipe) == 0)
		stream->put((char)fgetc(pipe));

	pclose(pipe);
	remove(tempfilename.c_str());
	isHeadofLine = true;
}



ParseUnit::ParseUnit(void * _container, const char * name)
{
	map<string, ParseUnit *> * container;
    string work(name);
	string apiname;
	string::size_type i,j;

	i = 0;
	container = reinterpret_cast<map<string, ParseUnit *> *>(_container);
	
	do {
		j = work.find_first_of(',', i);
		apiname = work.substr(i, j-i);

		if(container->find(apiname) != container->end())
	        ExceptionMessage("Multiple registration of [%]\n","[%]偑廳暋偟偰搊榐偝傟傛偆偲偟偰偄傑偡") << apiname << throwException;
	    (*container)[apiname] = this;
		i = j + 1;
	}while(j != string::npos);
}

void ParseUnit::printList(void * _container)
{
    int i;
	map<string, ParseUnit *> * container;
    map<string, ParseUnit *>::iterator scope;

	container = reinterpret_cast<map<string, ParseUnit *> *>(_container);
    if(container->empty())
    {
        cerr << "  " << Message("None of element registed\n", "搊榐偝傟偰偄傞梫慺偼偁傝傑偣傫\n");
        return;
    }

    i = 0;
    scope = container->begin();
    while(scope != container->end())
    {
        cerr << '[' << (*scope).first << "] ";

        if(i++ >= 6)
        {
            i = 0;
            cerr << '\n';
        }

        ++ scope;
    }

    if(i != 0)
        cerr << '\n';
}

Token & ParseUnit::parseParameter(Parser & p)
{
	static Token result;
	Token token;
	int nest = 0;

	result.type = Token::ERROR;
	result.value = 0;
	result.assign("");

	do
	{
		p.getToken(token);
		if(token == Token::PUNCTUATOR)
		{
			if(token.compare("(") == 0)
				nest ++;
			else if(token.compare(")") == 0)
				nest --;
			else if(nest == 0)
				break;
			if(nest < 0)
				ExceptionMessage("')' appeared before '('.","懳墳偟側偄暵偠妵屖偑偁傝傑偡").throwException();
		}

		if(result == Token::ERROR)
			result = token;
		else
		{
			result.type = Token::STRING;
			result += ' ';
			result += token;
		}

	}while(true);

	p.putBack(token);
	result.trim();
	return result;
}

int ParseUnit::parseParameters(Parser & p, Directory * container, int min, int max)
{
	Token work;
	int count = 0;

⌨️ 快捷键说明

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