3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
9 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
10 * によって公表されている GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 * @(#) $Id: parser.h,v 1.1 2009/01/31 05:27:37 suikan Exp $
40 // $Header: /cvsroot/toppersjsp4bf/jsp/cfg/base/parser.h,v 1.1 2009/01/31 05:27:37 suikan Exp $
45 #include "base/defs.h"
47 #include "base/message.h"
49 #include "base/directorymap.h"
50 #include "base/component.h"
59 #define PARSERESULT "/parse_result"
62 #undef ERROR /* MinGW環境だとwingdi.hでERRORが定義される */
65 class Token : public std::string
82 EOS = 0xff //End of Stream
85 enum tagTokenType type;
89 Token(void) { type = UNKNOWN; value = 0; };
90 Token(const Token & src) { (*this) = src; };
91 Token(enum tagTokenType, const char *);
93 operator const enum tagTokenType (void) const { return type; };
95 Token & operator =(const Token & src);
96 bool operator == (const Token & src) const;
99 Token & chopLiteral(void);
100 void confirm(const char *) const;
106 enum tagFunctionarities
107 { UNKNOWN = 0, DIRECTIVE = 1, LOGGING = 2 };
111 std::string identifier;
112 std::istream * stream;
117 static const char * Punctuator;
118 static const char * Operator;
119 static Token lastErrorToken;
121 std::string * LogBuffer;
122 unsigned int PutBackCount;
125 Directory * Container;
128 std::list<Token> TokenStack;
129 std::list<tagFile *> fileStack;
132 std::string preprocessname; //プリプロセッサを通すときに使った名前
133 std::string originalname; //本来の名前
135 bool parseDirectives(Token &, int, bool);
137 bool getIdentifier(Token &, int);
138 bool getWhitespace(Token &, int, bool);
139 bool getInteger(Token &, int);
140 bool getStringLiteral(Token &, int);
141 bool getOperator(Token &, int);
146 void initialize(void) { current = 0; functionalities = DIRECTIVE|LOGGING; PutBackCount = 0; LogBuffer = 0; isHeadofLine = true; };
148 bool isenabled(enum tagFunctionarities func) { return (functionalities & (int)func) != 0; };
151 Parser(Directory & cnt) : Container(&cnt) { initialize(); };
152 Parser(Directory * cnt) : Container(cnt) { initialize(); };
155 void pushStream(const std::string & filename, std::string = "");
156 void pushStdStream(std::string = "Standard Input");
158 void setStreamIdentifier(const std::string & id);
159 void setCurrentLine(unsigned int pos) { current->line = pos; };
160 unsigned int getCurrentLine(void);
161 const char * getStreamIdentifier(void);
162 std::string getStreamLocation(void);
164 enum Token::tagTokenType getToken(Token &,bool = false);
165 void getToken(Token &,enum Token::tagTokenType, const char * = NULL);
166 void getToken(const char *) throw(Exception);
167 void getToken(const char *, const char * , const char * = 0, const char * = 0) throw(Exception);
169 void putBack(Token &);
171 static const Token & getLastErrorToken(void) { return lastErrorToken; };
173 void enable(enum tagFunctionarities func) { functionalities |= (int)func; };
174 void disable(enum tagFunctionarities func) { functionalities &= ~(int)func; };
176 std::string * setLogBuffer(std::string * buffer);
177 std::streampos getLogBufferPos(int offset = 0);
179 void doPreProcess(const char * cmd);
188 static Token & parseParameter(Parser &);
189 static int parseParameters(Parser &, Directory *, int, int=0);
190 static int parseParameters(Parser &, Directory *, const char *);
193 ParseUnit(void *, const char *);
194 virtual ~ParseUnit(void) {};
196 const char * getIdentifier(void) const;
197 virtual void body(const std::string &, Directory &, Parser &, const std::string &) =0;
199 static void printList(void * container);
202 #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)
206 class StaticAPI : public ParseUnit
209 static Directory * last;
210 Directory * allocate(Parser & p, Directory &, const Token &, const char *, bool = true);
211 Directory * allocate(Directory &, const Token &, const char *, bool = true);
212 Directory * find (Directory &, const Token &, const char *);
215 StaticAPI(const char * name) : ParseUnit(&(container()), name) {};
217 static void printList(void) { ParseUnit::printList(&(container())); };
218 static void clearLastObject(void) { last = NULL; };
219 static void dropLastObject(void);
221 static std::map<std::string, class ParseUnit *> & container(void);
224 #define DECLARE_API(x,y) __DECLARE_PARSEUNIT(StaticAPI,x,y)
228 class Directive : public ParseUnit
231 static std::map<std::string, class ParseUnit *> & container(void);
233 Directive(const char * name) : ParseUnit(&(container()), name) {};
234 static void printList(void) { ParseUnit::printList(&(container())); }
237 #define DECLARE_DIRECTIVE(x,y) __DECLARE_PARSEUNIT(Directive,x,y)
241 class ParserComponent : public Component
245 bool ignoreUnknownAPI;
247 static void throughConfigurationFile(std::string & log, Directory & container);
249 virtual void parseOption(Directory &);
250 virtual void body(Directory &);
252 bool parseStaticAPI(Parser & p, Directory & container, Token token, const std::string = "");
254 virtual bool parse(Parser & p, Directory & container) = 0;
257 ParserComponent(void) throw();
258 virtual ~ParserComponent(void) throw();
265 enum tagAssignmentOrder { UNKNOWN, ALPHABETIC, FCFS, REVERSE=0x80, REVERSE_ALPHABETIC, REVERSE_FCFS };
267 enum tagAssignmentOrder parseOrder(Directory * order_option_node);
268 enum tagAssignmentOrder parseOrder(OptionParameter::OptionItem order_option_node);
269 int assignID(Directory & container, const char * category, const char * top, enum tagAssignmentOrder = FCFS);
274 inline Token::Token(enum tagTokenType type, const char * term)
281 inline Token & Token::operator =(const Token & src)
290 inline bool Token::operator ==(const Token & src) const
294 if(type == Token::INTEGER && value != src.value)
297 if(compare(src) != 0)
303 inline void Token::confirm(const char * str) const
305 if(compare(str) != 0)
306 ExceptionMessage("Illegal token (%) appears during parse process.","字句解析の途中で不正なトークン(%)が出現しました") << str << throwException;
309 inline void Parser::getToken(Token & token, enum Token::tagTokenType type, const char * term)
311 getToken(token, type == Token::SPACE);
313 if(type == Token::STRING && token == Token::STRINGLITERAL)
316 if((type != token) || (term != NULL && token.compare(term) != 0))
318 lastErrorToken = token;
319 ExceptionMessage("Parse error on reading [%]","字句解析のエラー [%]") << token << throwException;
323 inline void Parser::putBack(Token & token)
324 { TokenStack.push_front(token); }
326 inline Directory * StaticAPI::find(Directory & container, const Token & token, const char * id)
330 node = container.findChild(id,token.c_str(),NULL);
332 ExceptionMessage("The object %(%) does not exist.","オブジェクト%(%)は未定義です") << token << throwException;
337 inline void StaticAPI::dropLastObject(void)
346 inline Directory * StaticAPI::allocate(Parser & p, Directory & container, const Token & token, const char * category, bool regist)
348 Directory * node = allocate(container, token, category, regist);
350 (*node)["position"] = p.getStreamLocation();
354 inline void Parser::setStreamIdentifier(const std::string & id)
356 if(preprocessname.compare(id) != 0)
357 current->identifier = id;
359 current->identifier = originalname;