📄 parser.cpp
字号:
/* * TOPPERS/JSP Kernel * Toyohashi Open Platform for Embedded Real-Time Systems/ * Just Standard Profile Kernel * * Copyright (C) 2000-2002 by Embedded and Real-Time Systems Laboratory * Toyohashi Univ. of Technology, JAPAN * * 惧淡螟侯涪荚は·Free Software Foundation によって给山されている * GNU General Public License の Version 2 に淡揭されている掘凤か·笆 * 布の(1)×(4)の掘凤を塔たす眷圭に嘎り·塑ソフトウェア∈塑ソフトウェ * アを猖恃したものを崔むˉ笆布票じ∷を蝗脱ˇ剩澜ˇ猖恃ˇ浩芹邵∈笆布· * 网脱と钙ぶ∷することを痰浸で钓满するˉ * (1) 塑ソフトウェアをソ〖スコ〖ドの妨で网脱する眷圭には·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年が·そのままの妨でソ〖 * スコ〖ド面に崔まれていることˉ * (2) 塑ソフトウェアを浩网脱材墙なバイナリコ〖ド∈リロケ〖タブルオブ * ジェクトファイルやライブラリなど∷の妨で网脱する眷圭には·网脱 * に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯涪山绩· * この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (3) 塑ソフトウェアを浩网脱稍材墙なバイナリコ〖ドの妨または怠达に寥 * み哈んだ妨で网脱する眷圭には·肌のいずれかの掘凤を塔たすことˉ * (a) 网脱に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (b) 网脱の妨轮を·侍に年める数恕によって·惧淡螟侯涪荚に鼠桂する * ことˉ * (4) 塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じるいかなる禄 * 巢からも·惧淡螟侯涪荚を倘勒することˉ * * 塑ソフトウェアは·痰瘦沮で捏丁されているものであるˉ惧淡螟侯涪荚は· * 塑ソフトウェアに簇して·その努脱材墙拉も崔めて·いかなる瘦沮も乖わ * ないˉまた·塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じたい * かなる禄巢に簇しても·その勒扦を砷わないˉ * * @(#) $Id: parser.cpp,v 1.15 2002/04/11 08:07:53 takayuki Exp $ */// $Header: /home/CVS/configurator/parser.cpp,v 1.15 2002/04/11 08:07:53 takayuki Exp $#include "parser.h"using namespace std;Token & Token::trim(void){ string::iterator scope; scope = begin(); while(*scope == ' ' || *scope == '\t' || *scope == '\r' || *scope == '\n') scope ++; erase(begin(), scope); if(!empty()) { scope = end(); do { scope --; } while(*scope == ' ' || *scope == '\t' || *scope == '\r' || *scope == '\n'); scope ++; erase(scope, end()); } return *this;}Token & Token::chopLiteral(void){ if(type != STRINGLITERAL) return *this; string::iterator scope; //エラ〖借妄のために润撬蝉借妄をする string src(*this); string work; if(src[0] != '"' || src[src.length()-1] != '"') return *this; src = src.substr(1, src.length()-2); scope = src.begin(); while(scope != src.end()) { if(*scope == '\\') { //リテラルの琐萨が\で姜わることはないのでチェックしない scope++; switch(*scope) { case '"': work += '"'; break; case 't': work += '\t'; break; case 'r': work += '\r'; break; case 'n': work += '\n'; break; case 'b': work += '\b'; break; case '\\': work += '\\'; break; default: Exception("Illegal escape sequence [\\%c]","エスケ〖プシ〖ケンス[\\%c]は稍赖です").format(*scope); } }else work += *scope; scope ++; } type = STRING; assign(work); value = this->length(); return *this;}const char * Parser::Punctuator = ",;(){}";const char * Parser::Operator = "+-*/&|%^~!?[]=:.#";Token Parser::lastErrorToken;inline int Parser::getChar(void){ int work = current->stream->get(); if(work == '\n') current->line ++; return work;}inline void Parser::putBack(int ch){ if(ch == '\n') current->line --; current->stream->putback(ch);}Parser::~Parser(void){ list<tagFile *>::iterator scope; if(current != 0) fileStack.push_front(current); scope = fileStack.begin(); while(scope != fileStack.end()) { if((*scope)->stream != 0 && (*scope)->stream != &cin) delete (*scope)->stream; delete (*scope); scope ++; } fileStack.clear(); TokenStack.clear();}bool Parser::getIdentifier(Token & token,int ch){ token.value = 0; do { token.value ++; token += static_cast<char>(ch); ch = getChar(); } while( (ch >='a' && ch <= 'z') || (ch >='A' && ch <= 'Z') || (ch == '_') || (ch >= '0' && ch <= '9') ); if(ch != -1) putBack(static_cast<char>(ch)); token.type = Token::IDENTIFIER; return true;}bool Parser::getWhitespace(Token & token, int ch, bool allow_space){ int prev; token.type = Token::SPACE; switch(ch) { case '/': ch = getChar(); switch(ch) { case '*': token += "/*"; prev = '\x0'; while( ((ch = getChar()) != '/') || (prev!='*')) { token += static_cast<char>(ch); prev = ch; } token += static_cast<char>(ch); break; case '/': token += '/'; do { token += static_cast<char>(ch); } while( (ch = getChar()) != '\n' ); break; default: putBack(ch); return false; } break; case '#': { Token directive; map<string, ParseUnit *>::iterator scope; do { token += static_cast<char>(ch); ch = getChar(); } while(ch == ' ' || ch == '\t'); if(ch >= '0' && ch <= '9') { directive.assign("line"); this->putBack(ch); }else { putBack(ch); getToken(directive); token += directive; } if(directive.compare("line") == 0) { Token token; getToken(token, Token::INTEGER); setCurrentLine(token.value -1); getToken(token, Token::STRINGLITERAL); token.chopLiteral(); setStreamIdentifier(token); }else { if(directive.compare("pragma") == 0) { getToken(directive); token += " "; token += directive; if((scope = Directive::container.find(directive)) != Directive::container.end()) { (*scope).second->body(directive, *Container, *this, string("")); if(!TokenStack.empty()) { do { token = TokenStack.front(); TokenStack.pop_front(); } while(!TokenStack.empty() && !allow_space && token.type == Token::SPACE); return true; } }else { do { token += static_cast<char>(ch); ch = getChar(); } while(ch != '\n'); putBack(ch); } }else { if(directive.compare("include") == 0) { cerr << Message("Configurator found 'include' directive at ","#includeディレクティブを券斧しました ") << getStreamLocation() << endl << Message("Kernel configuration file must be preprocessed by cpp"," カ〖ネル菇喇ファイルはCプリプロセッサを奶册させる涩妥があります") << endl; Exception("Illegal kernel configuration file","稍赖なカ〖ネル菇喇ファイル"); } } } break; } case ' ': case '\t': case '\n': case '\r': do { token += static_cast<char>(ch); ch = getChar(); } while((ch == ' ') || (ch == '\n') || (ch == '\r') || (ch == '\t')); putBack(static_cast<char>(ch)); break; } return true;}bool Parser::getInteger(Token & token, int ch){ bool minus = false; if(ch == '-') { minus = true; ch = getChar(); if(ch < '0' || ch >'9') { putBack(static_cast<char>(ch)); return false; } token += "-"; } token.type = Token::INTEGER; token.value = 0; if(ch == '0') { token += static_cast<char>(ch); ch = getChar(); if(ch == 'x' || ch == 'X') { token += static_cast<char>(ch); ch = getChar(); while((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) { token += static_cast<char>(ch); if((ch -= '0') >= 10) { ch = ch + '0' - 'A' + 10; if(ch >= 16) ch = ch - ('a' - 'A'); } token.value = token.value * 16 + ch; ch = getChar(); } }else { while(ch >= '0' && ch <= '7') { token += static_cast<char>(ch); token.value = token.value * 8 + ch - '0'; ch = getChar(); } } }else { do { token += static_cast<char>(ch); token.value = token.value * 10 + ch - '0'; ch = getChar(); } while(ch >= '0' && ch <= '9'); } 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; 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;}bool Parser::getStringLiteral(Token & token, int ch){ int prev; int position; int prev_line; prev_line = current->line; position = current->stream->tellg(); 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 == '"' && prev != '\\') return true; } //いったん誓じて浩オ〖プンして、リテラル倡幌の " の肌に败瓢 current->line = prev_line; current->stream->seekg(position); current->stream->clear(); Exception("Unterminated string literal appeared.","誓じられていない矢机リテラルを浮叫しました"); return false;}enum Token::tagTokenType Parser::getToken(Token & token, bool allow_space){ static bool isHeadofLine = true; 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; if(fileStack.empty()) { token.assign("<End of stream>"); return (token.type = Token::EOS); } 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 == '"' ) if(getStringLiteral(token,ch)) return Token::STRINGLITERAL; //Operator if(getOperator(token,ch))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -