📄 parser.h
字号:
/*
* 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.h,v 1.8 2003/06/30 12:50:32 takayuki Exp $
*/
// $Header: /home/CVS/configurator/base/parser.h,v 1.8 2003/06/30 12:50:32 takayuki Exp $
#ifndef PARSER_H
#define PARSER_H
#include "base/defs.h"
#include "base/message.h"
#include "base/directorymap.h"
#include "base/component.h"
#include <stdarg.h>
#include <iostream>
#include <list>
#include <string>
#include <fstream>
#include <sstream>
#define PARSERESULT "/parse_result"
class Token : public std::string
{
//儊儞僶偺塀暳偼偟側偄
public:
enum tagTokenType
{
IDENTIFIER = 0x01,
INTEGER = 0x02,
STRINGLITERAL = 0x03,
STRING = 0x04,
OPERATOR = 0x05,
PUNCTUATOR = 0x06,
RESERVEDWORD = 0x07,
SPECIAL = 0x80,
SPACE = 0x81,
UNKNOWN = 0xfd,
ERROR = 0xfe,
EOS = 0xff //End of Stream
};
enum tagTokenType type;
long value;
unsigned int line;
Token(void) { type = UNKNOWN; value = 0; };
Token(const Token & src) { (*this) = src; };
Token(enum tagTokenType, const char *);
operator const enum tagTokenType (void) const { return type; };
Token & operator =(const Token & src);
bool operator == (const Token & src) const;
Token & trim(void);
Token & chopLiteral(void);
void confirm(const char *) const;
};
class Parser
{
public:
enum tagFunctionarities
{ UNKNOWN = 0, DIRECTIVE = 1, LOGGING = 2 };
struct tagFile
{
std::string identifier;
std::istream * stream;
unsigned int line;
};
protected:
static const char * Punctuator;
static const char * Operator;
static Token lastErrorToken;
std::string * LogBuffer;
unsigned int PutBackCount;
bool isHeadofLine;
Directory * Container;
tagFile * current;
std::list<Token> TokenStack;
std::list<tagFile *> fileStack;
int functionalities;
std::string preprocessname; //僾儕僾儘僙僢僒傪捠偡偲偒偵巊偭偨柤慜
std::string originalname; //杮棃偺柤慜
bool parseDirectives(Token &, int, bool);
bool getIdentifier(Token &, int);
bool getWhitespace(Token &, int, bool);
bool getInteger(Token &, int);
bool getStringLiteral(Token &, int);
bool getOperator(Token &, int);
int getChar(void);
void putBack(int);
void initialize(void) { current = 0; functionalities = DIRECTIVE|LOGGING; PutBackCount = 0; LogBuffer = 0; isHeadofLine = true; };
bool isenabled(enum tagFunctionarities func) { return (functionalities & (int)func) != 0; };
public:
Parser(Directory & cnt) : Container(&cnt) { initialize(); };
Parser(Directory * cnt) : Container(cnt) { initialize(); };
~Parser(void);
void pushStream(const std::string & filename, std::string = "");
void pushStdStream(std::string = "Standard Input");
void setStreamIdentifier(const std::string & id);
void setCurrentLine(unsigned int pos) { current->line = pos; };
unsigned int getCurrentLine(void);
const char * getStreamIdentifier(void);
std::string getStreamLocation(void);
enum Token::tagTokenType getToken(Token &,bool = false);
void getToken(Token &,enum Token::tagTokenType, const char * = NULL);
void getToken(const char *, const char * = 0, ...);
void putBack(Token &);
static const Token & getLastErrorToken(void) { return lastErrorToken; };
void enable(enum tagFunctionarities func) { functionalities |= (int)func; };
void disable(enum tagFunctionarities func) { functionalities &= ~(int)func; };
std::string * setLogBuffer(std::string * buffer);
std::streampos getLogBufferPos(int offset = 0);
void doPreProcess(const char * cmd);
};
//---
class ParseUnit
{
protected:
static Token & parseParameter(Parser &);
static int parseParameters(Parser &, Directory *, int, int=0);
static int parseParameters(Parser &, Directory *, const char *);
public:
ParseUnit(void *, const char *);
virtual ~ParseUnit(void) {};
const char * getIdentifier(void) const;
virtual void body(const std::string &, Directory &, Parser &, const std::string &) =0;
static void printList(void * container);
};
#define __DECLARE_PARSEUNIT(x,y,z) class x##_##y : public x { public: x##_##y(void) : x(z) {}; protected: virtual void body(const std::string &, Directory &, Parser &, const std::string &); } instance_of_##x##_##y; void x##_##y::body(const std::string & identifier, Directory & container, Parser & p, const std::string & domain)
//---
class StaticAPI : public ParseUnit
{
protected:
static Directory * last;
Directory * allocate(Parser & p, Directory &, const Token &, const char *, bool = true);
Directory * allocate(Directory &, const Token &, const char *, bool = true);
Directory * find (Directory &, const Token &, const char *);
public:
StaticAPI(const char * name) : ParseUnit(&(container()), name) {};
static void printList(void) { ParseUnit::printList(&(container())); };
static void clearLastObject(void) { last = NULL; };
static void dropLastObject(void);
static std::map<std::string, class ParseUnit *> & container(void);
};
#define DECLARE_API(x,y) __DECLARE_PARSEUNIT(StaticAPI,x,y)
//---
class Directive : public ParseUnit
{
public:
static std::map<std::string, class ParseUnit *> & container(void);
Directive(const char * name) : ParseUnit(&(container()), name) {};
static void printList(void) { ParseUnit::printList(&(container())); }
};
#define DECLARE_DIRECTIVE(x,y) __DECLARE_PARSEUNIT(Directive,x,y)
//---
class ParserComponent : public Component
{
protected:
int failCount;
bool ignoreUnknownAPI;
static void throughConfigurationFile(std::string & log, Directory & container);
virtual void parseOption(Directory &);
virtual void body(Directory &);
bool parseStaticAPI(Parser & p, Directory & container, Token token, const std::string = "");
virtual bool parse(Parser & p, Directory & container) = 0;
public:
ParserComponent(void);
virtual ~ParserComponent(void);
};
//---
namespace Common {
enum tagAssignmentOrder { UNKNOWN, ALPHABETIC, FCFS, REVERSE=0x80, REVERSE_ALPHABETIC, REVERSE_FCFS };
enum tagAssignmentOrder parseOrder(Directory * order_option_node);
int assignID(Directory & container, const char * category, const char * top, enum tagAssignmentOrder = FCFS);
}
//---
inline Token::Token(enum tagTokenType type, const char * term)
{
type = type;
value = 0;
assign(term);
}
inline Token & Token::operator =(const Token & src)
{
type = src.type;
value = src.value;
line = src.line;
assign(src);
return *this;
}
inline bool Token::operator ==(const Token & src) const
{
if(type != src.type)
return false;
if(type == Token::INTEGER && value != src.value)
return false;
else
if(compare(src) != 0)
return false;
return true;
}
inline void Token::confirm(const char * str) const
{
if(compare(str) != 0)
ExceptionMessage("Illegal token (%) appears during parse process.","帤嬪夝愅偺搑拞偱晄惓側僩乕僋儞(%)偑弌尰偟傑偟偨") << str << throwException;
}
inline void Parser::getToken(Token & token, enum Token::tagTokenType type, const char * term)
{
getToken(token, type == Token::SPACE);
if(type == Token::STRING && token == Token::STRINGLITERAL)
token.chopLiteral();
if((type != token) || (term != NULL && token.compare(term) != 0))
{
lastErrorToken = token;
ExceptionMessage("Parse error on reading [%]","帤嬪夝愅偺僄儔乕 [%]") << token << throwException;
}
}
inline void Parser::putBack(Token & token)
{ TokenStack.push_front(token); }
inline Directory * StaticAPI::find(Directory & container, const Token & token, const char * id)
{
Directory * node;
node = container.findChild(id,token.c_str(),NULL);
if(node == 0)
ExceptionMessage("The object %(%) does not exist.","僆僽僕僃僋僩%(%)偼枹掕媊偱偡") << token << throwException;
return node;
}
inline void StaticAPI::dropLastObject(void)
{
if(last != NULL)
{
last->erase();
last = NULL;
}
}
inline Directory * StaticAPI::allocate(Parser & p, Directory & container, const Token & token, const char * category, bool regist)
{
Directory * node = allocate(container, token, category, regist);
if(node != 0)
(*node)["position"] = p.getStreamLocation();
return node;
}
inline void Parser::setStreamIdentifier(const std::string & id)
{
if(preprocessname.compare(id) != 0)
current->identifier = id;
else
current->identifier = originalname;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -