OSDN Git Service

最初のコミット。sample1が通る。
[uzume/uzume_bfin.git] / uzume_prototype / kernel / cfg / base / parser.h
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  * 
6  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  * 
9  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
10  *  によって公表されている GNU General Public License の Version 2 に記
11  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
13  *  利用と呼ぶ)することを無償で許諾する.
14  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16  *      スコード中に含まれていること.
17  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20  *      の無保証規定を掲載すること.
21  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23  *      と.
24  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
26  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27  *        報告すること.
28  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30  * 
31  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
35  * 
36  *  @(#) $Id: parser.h,v 1.1 2009/01/31 05:27:37 suikan Exp $
37  */
38
39
40 // $Header: /cvsroot/toppersjsp4bf/jsp/cfg/base/parser.h,v 1.1 2009/01/31 05:27:37 suikan Exp $
41
42 #ifndef PARSER_H
43 #define PARSER_H
44
45 #include "base/defs.h"
46
47 #include "base/message.h"
48
49 #include "base/directorymap.h"
50 #include "base/component.h"
51
52 #include <stdarg.h>
53 #include <iostream>
54 #include <list>
55 #include <string>
56 #include <fstream>
57 #include <sstream>
58
59 #define PARSERESULT         "/parse_result"
60
61 #ifndef  ERROR
62 #undef   ERROR   /* MinGW環境だとwingdi.hでERRORが定義される */
63 #endif
64
65 class Token : public std::string
66 {
67         //メンバの隠蔽はしない
68 public:
69     enum tagTokenType
70     {
71         IDENTIFIER      = 0x01,
72         INTEGER         = 0x02,
73         STRINGLITERAL   = 0x03,
74         STRING          = 0x04,
75         OPERATOR        = 0x05,
76         PUNCTUATOR      = 0x06,
77         RESERVEDWORD    = 0x07,
78         SPECIAL         = 0x80,
79         SPACE           = 0x81,
80         UNKNOWN         = 0xfd,
81         ERROR           = 0xfe,
82         EOS             = 0xff      //End of Stream
83     };
84
85     enum tagTokenType   type;
86     long                value;
87     unsigned int        line;
88
89     Token(void)                 { type = UNKNOWN;  value = 0;   };
90     Token(const Token & src)    { (*this) = src; };
91     Token(enum tagTokenType, const char *);
92
93     operator const enum tagTokenType (void) const { return type; };
94
95     Token & operator =(const Token & src);
96     bool operator == (const Token & src) const;
97
98     Token & trim(void);
99     Token & chopLiteral(void);
100     void    confirm(const char *) const;
101 };
102
103 class Parser
104 {
105 public:
106     enum tagFunctionarities
107     {   UNKNOWN = 0, DIRECTIVE = 1, LOGGING = 2 };
108
109     struct tagFile
110     {
111         std::string    identifier;
112         std::istream * stream;
113         unsigned int   line;
114     };
115
116 protected:
117     static const char * Punctuator;
118     static const char * Operator;
119     static Token        lastErrorToken;
120     
121     std::string *       LogBuffer;
122     unsigned int        PutBackCount;
123     bool                isHeadofLine;
124
125     Directory *         Container;
126
127     tagFile *             current;
128     std::list<Token>      TokenStack;
129     std::list<tagFile *>  fileStack;
130     int                   functionalities;
131
132     std::string           preprocessname;   //プリプロセッサを通すときに使った名前
133     std::string           originalname;     //本来の名前
134
135     bool parseDirectives(Token &, int, bool);
136
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);
142
143     int  getChar(void);
144     void putBack(int);
145
146     void initialize(void) { current = 0; functionalities = DIRECTIVE|LOGGING; PutBackCount = 0; LogBuffer = 0; isHeadofLine = true; };
147
148     bool isenabled(enum tagFunctionarities func)  { return (functionalities & (int)func) != 0; };
149
150 public:
151     Parser(Directory & cnt) : Container(&cnt) { initialize(); };
152     Parser(Directory * cnt) : Container(cnt)  { initialize(); };
153     ~Parser(void);
154
155     void pushStream(const std::string & filename, std::string = "");
156     void pushStdStream(std::string = "Standard Input");
157
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);
163
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);
168
169     void putBack(Token &);
170
171     static const Token & getLastErrorToken(void) { return lastErrorToken; };
172
173     void enable(enum tagFunctionarities func)  { functionalities |=  (int)func; };
174     void disable(enum tagFunctionarities func) { functionalities &= ~(int)func; };
175
176     std::string *  setLogBuffer(std::string * buffer);
177     std::streampos getLogBufferPos(int offset = 0);
178
179     void doPreProcess(const char * cmd);
180 };
181
182
183 //---
184
185 class ParseUnit
186 {
187 protected:
188     static Token & parseParameter(Parser &);
189     static int     parseParameters(Parser &, Directory *, int, int=0);
190     static int     parseParameters(Parser &, Directory *, const char *);
191
192 public:
193     ParseUnit(void *, const char *);
194     virtual ~ParseUnit(void) {};
195
196     const char * getIdentifier(void) const;
197     virtual void body(const std::string &, Directory &, Parser &, const std::string &) =0;
198
199     static void printList(void * container);
200 };
201
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)
203
204 //---
205
206 class StaticAPI : public ParseUnit
207 {
208 protected:
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 *);
213
214 public:
215     StaticAPI(const char * name) : ParseUnit(&(container()), name) {};
216
217     static void printList(void)         { ParseUnit::printList(&(container())); };
218     static void clearLastObject(void)   { last = NULL; };
219     static void dropLastObject(void);
220
221     static std::map<std::string, class ParseUnit *> & container(void);
222 };
223
224 #define DECLARE_API(x,y) __DECLARE_PARSEUNIT(StaticAPI,x,y)
225
226 //---
227
228 class Directive : public ParseUnit
229 {
230 public:
231     static std::map<std::string, class ParseUnit *> & container(void);
232
233     Directive(const char * name) : ParseUnit(&(container()), name) {};
234     static void printList(void) { ParseUnit::printList(&(container())); }
235 };
236
237 #define DECLARE_DIRECTIVE(x,y) __DECLARE_PARSEUNIT(Directive,x,y)
238
239 //---
240
241 class ParserComponent : public Component
242 {
243 protected:
244     int  failCount;
245     bool ignoreUnknownAPI;
246
247     static void throughConfigurationFile(std::string & log, Directory & container);
248
249     virtual void parseOption(Directory &);    
250     virtual void body(Directory &);
251
252     bool         parseStaticAPI(Parser & p, Directory & container, Token token, const std::string = "");
253
254     virtual bool parse(Parser & p, Directory & container) = 0;
255
256 public:
257     ParserComponent(void) throw();
258     virtual ~ParserComponent(void) throw();
259 };
260
261 //---
262
263 namespace Common {
264     
265     enum tagAssignmentOrder { UNKNOWN, ALPHABETIC, FCFS, REVERSE=0x80, REVERSE_ALPHABETIC, REVERSE_FCFS };
266
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);
270 }
271
272 //---
273
274 inline Token::Token(enum tagTokenType type, const char * term)
275 {
276     type = type;
277     value = 0;
278     assign(term);
279 }
280
281 inline Token & Token::operator =(const Token & src)
282 {   
283     type = src.type; 
284     value = src.value; 
285     line = src.line;
286     assign(src); 
287     return *this;   
288 }
289
290 inline bool Token::operator ==(const Token & src) const
291 {
292     if(type != src.type)
293         return false;
294     if(type == Token::INTEGER && value != src.value)
295         return false;
296     else
297         if(compare(src) != 0)
298             return false;
299
300     return true;
301 }
302
303 inline void Token::confirm(const char * str) const
304 {
305     if(compare(str) != 0)
306         ExceptionMessage("Illegal token (%) appears during parse process.","字句解析の途中で不正なトークン(%)が出現しました") << str << throwException;
307 }
308
309 inline void Parser::getToken(Token & token, enum Token::tagTokenType type, const char * term)
310 {
311     getToken(token, type == Token::SPACE);
312
313     if(type == Token::STRING && token == Token::STRINGLITERAL)
314         token.chopLiteral();
315
316     if((type != token) || (term != NULL && token.compare(term) != 0))
317     {
318         lastErrorToken = token;
319         ExceptionMessage("Parse error on reading [%]","字句解析のエラー [%]") << token << throwException;
320     }
321 }
322
323 inline void Parser::putBack(Token & token)
324 {   TokenStack.push_front(token);   }
325
326 inline Directory * StaticAPI::find(Directory & container, const Token & token, const char * id)
327 {
328     Directory * node;
329
330     node = container.findChild(id,token.c_str(),NULL);
331     if(node == 0)
332         ExceptionMessage("The object %(%) does not exist.","オブジェクト%(%)は未定義です") << token << throwException;
333
334     return node;
335 }
336
337 inline void StaticAPI::dropLastObject(void)
338 {
339     if(last != NULL)
340     {
341         last->erase();
342         last = NULL;
343     }
344 }
345
346 inline Directory * StaticAPI::allocate(Parser & p, Directory & container, const Token & token, const char * category, bool regist)
347 {
348     Directory * node = allocate(container, token, category, regist);
349     if(node != 0)
350         (*node)["position"] = p.getStreamLocation();
351     return node;
352 }
353
354 inline void Parser::setStreamIdentifier(const std::string & id)
355 {
356     if(preprocessname.compare(id) != 0)
357         current->identifier = id;
358     else
359         current->identifier = originalname;
360 }
361
362 #endif
363