📄 parser.cpp
字号:
/*
* TOPPERS/JSP Kernel
* Toyohashi Open Platform for Embedded Real-Time Systems/
* Just Standard Profile Kernel
*
* Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
* Toyohashi Univ. of Technology, JAPAN
*
* 忋婰挊嶌尃幰偼丆埲壓偺 (1)乣(4) 偺忦審偐丆Free Software Foundation
* 偵傛偭偰岞昞偝傟偰偄傞 GNU General Public License 偺 Version 2 偵婰
* 弎偝傟偰偄傞忦審傪枮偨偡応崌偵尷傝丆杮僜僼僩僂僃傾乮杮僜僼僩僂僃傾
* 傪夵曄偟偨傕偺傪娷傓丏埲壓摨偠乯傪巊梡丒暋惢丒夵曄丒嵞攝晍乮埲壓丆
* 棙梡偲屇傇乯偡傞偙偲傪柍彏偱嫋戻偡傞丏
* (1) 杮僜僼僩僂僃傾傪僜乕僗僐乕僪偺宍偱棙梡偡傞応崌偵偼丆忋婰偺挊嶌
* 尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕偑丆偦偺傑傑偺宍偱僜乕
* 僗僐乕僪拞偵娷傑傟偰偄傞偙偲丏
* (2) 杮僜僼僩僂僃傾傪丆儔僀僽儔儕宍幃側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒傞宍偱嵞攝晍偡傞応崌偵偼丆嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡
* 幰儅僯儏傾儖側偳乯偵丆忋婰偺挊嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰
* 偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (3) 杮僜僼僩僂僃傾傪丆婡婍偵慻傒崬傓側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒側偄宍偱嵞攝晍偡傞応崌偵偼丆師偺偄偢傟偐偺忦審傪枮偨偡偙
* 偲丏
* (a) 嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡幰儅僯儏傾儖側偳乯偵丆忋婰偺挊
* 嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (b) 嵞攝晍偺宍懺傪丆暿偵掕傔傞曽朄偵傛偭偰丆TOPPERS僾儘僕僃僋僩偵
* 曬崘偡傞偙偲丏
* (4) 杮僜僼僩僂僃傾偺棙梡偵傛傝捈愙揑傑偨偼娫愙揑偵惗偠傞偄偐側傞懝
* 奞偐傜傕丆忋婰挊嶌尃幰偍傛傃TOPPERS僾儘僕僃僋僩傪柶愑偡傞偙偲丏
*
* 杮僜僼僩僂僃傾偼丆柍曐徹偱採嫙偝傟偰偄傞傕偺偱偁傞丏忋婰挊嶌尃幰偍
* 傛傃TOPPERS僾儘僕僃僋僩偼丆杮僜僼僩僂僃傾偵娭偟偰丆偦偺揔梡壜擻惈傕
* 娷傔偰丆偄偐側傞曐徹傕峴傢側偄丏傑偨丆杮僜僼僩僂僃傾偺棙梡偵傛傝捈
* 愙揑傑偨偼娫愙揑偵惗偠偨偄偐側傞懝奞偵娭偟偰傕丆偦偺愑擟傪晧傢側偄丏
*
* @(#) $Id: parser.cpp,v 1.12 2003/06/30 12:50:32 takayuki Exp $
*/
// $Header: /home/CVS/configurator/base/parser.cpp,v 1.12 2003/06/30 12:50:32 takayuki Exp $
#include "base/defs.h"
#include "base/parser.h"
#include <sstream>
#include <set>
#include <map>
#include <iomanip>
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:
ExceptionMessage("Illegal escape sequence [\\%]","僄僗働乕僾僔乕働儞僗[\\%]偼晄惓偱偡") << *scope << throwException;
}
}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 ++;
/* 僗僩儕乕儉儘僌偺偨傔偺張棟 */
if(PutBackCount == 0)
{
if(LogBuffer != 0 && isenabled(LOGGING))
*LogBuffer += static_cast<char>(work);
}else
PutBackCount --; //偡偱偵撉傒崬傫偱偄傞
return work;
}
/*
* 庢傝弌偟偡偓偨暥帤傪僗僩儕乕儉偵曉偡
*/
inline void Parser::putBack(int ch)
{
/* 峴斣崋偺偨傔偺張棟 */
if(ch == '\n')
current->line --;
/* 僗僩儕乕儉儘僌偺偨傔偺張棟 */
PutBackCount ++;
current->stream->putback(ch);
}
/*
* Parser僋儔僗偺僨僗僩儔僋僞
*/
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();
}
/*
* 幆暿巕偺愗弌偟 (幆暿巕 = [a-zA-Z_][0-9a-zA-Z_]*)
*/
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::parseDirectives(Token & token, int ch, bool allow_space)
{
Token directive;
map<string, ParseUnit *>::iterator scope;
//嬻敀撉傒旘偽偟
do {
token += static_cast<char>(ch);
ch = getChar();
} while(ch == ' ' || ch == '\t');
if(ch >= '0' && ch <= '9')
{
//GNU-cpp line僨傿儗僋僥傿僽 懳嶔
directive.assign("line");
this->putBack(ch);
}else
{
//僨傿儗僋僥傿僽偺撉傒弌偟
putBack(ch);
getToken(directive);
token += directive;
}
//line僨傿儗僋僥傿僽偺夝愅
if(directive.compare("line") == 0)
{
Token token;
getToken(token, Token::INTEGER);
setCurrentLine(token.value -1);
getToken(token, Token::STRINGLITERAL);
try {
token.chopLiteral();
}
catch(Exception &) {
token.assign("Unknown");
}
setStreamIdentifier(token);
return true;
}
//pragma僨傿儗僋僥傿僽偺夝愅
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;
}
}
}
//include僨傿儗僋僥傿僽偺夝愅
if(directive.compare("include") == 0)
{
cerr << getStreamLocation() << Message(": Configurator found 'include' directive\nKernel configuration file must be preprocessed.\n",": #include僨傿儗僋僥傿僽傪敪尒偟傑偟偨\n 僇乕僱儖峔惉僼傽僀儖偼C僾儕僾儘僙僢僒傪捠夁偝偣傞昁梫偑偁傝傑偡\n");
ExceptionMessage("Illegal kernel configuration file","晄惓側僇乕僱儖峔惉僼傽僀儖").throwException();
}
putBack(directive);
return false;
}
/*
* 嬻敀暥帤偺愗弌偟
* 丒僗儁乕僗, 僞僽 丒#偱巒傑偭偰夵峴傑偱 丒C尵岅偺僐儊儞僩僽儘僢僋
* 丒2楢偺僗儔僢僔儏(//)偐傜夵峴傑偱
* 丒忋偺4偮傪慻傒崌傢偣偨傕偺
*/
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 getOperator(token, '/');;
}
break;
/* # 偱巒傑傞峴 */
case '#':
/* 僨傿儗僋僥傿僽偑柍岠 or 偦傫側僨傿儗僋僥傿僽偼抦傜側偄 */
if(! (isenabled(DIRECTIVE) && parseDirectives(token, ch, allow_space)) )
{
//夵峴傑偱撉傒旘偽偟
TokenStack.clear();
do {
token += static_cast<char>(ch);
ch = getChar();
} while(ch != '\n');
putBack(ch);
}
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;
}
/*
* 惍悢抣偺愗弌偟 (8/10/16恑, 惓悢/晧悢)
* 丒2恑偼晄昡偩偭偨偺偱傗傔傑偟偨
*/
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');
}
/* integer-suffix */
if(ch != -1)
{
bool unsigned_suffix = false;
bool long_suffix = false;
int first_longsuffix;
if(ch == 'u' || ch == 'U')
{
unsigned_suffix = true;
token += static_cast<char>(ch);
ch = getChar();
}
if(ch == 'i' || ch == 'I') //i8, i16, i32, i64
{
int first, second;
bool accept = false;
const signed char suffix_list[10] = { -1, '6', -1, '2', -1, -1, '4', -1, 0, -1}; //8, 16, 32, 64偺傒傪庴棟
first = getChar();
second = -1;
if(first >= '0' && first <= '9')
{
if(suffix_list[first - '0'] > 0)
{
second = getChar();
if(second == suffix_list[first - '0'])
accept = true;
}else
if(suffix_list[first - '0'] == 0)
accept = true;
}
if(!accept)
{
if(second != -1)
putBack(second);
putBack(first);
} else
{
token += static_cast<char>(ch);
token += static_cast<char>(first);
if(second != -1)
token += static_cast<char>(second);
ch = getChar();
}
} else
{
if(ch == 'l' || ch == 'L')
{
first_longsuffix = ch;
long_suffix = true;
token += static_cast<char>(ch);
ch = getChar();
if(ch == first_longsuffix)
{
token += static_cast<char>(ch);
ch = getChar();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -