/*! * bnf::Context * * Copyright (c) 2007 tkuri {at} fat.coara.or.jp */ #ifndef BNF_CXT_HPP_ #define BNF_CXT_HPP_ #include "bnf.hpp" #include "bnf_string.hpp" #include "bnf_map.hpp" #include "bnf_list.hpp" #include "bnf_ptr.hpp" // 一番大きな int 型の数値 // 要素の繰り返しの条件で使われます #define BNF_LARGEST_INT (0x7fffffff) namespace bnf { //========================================================= /*! * マッチした結果を保持しています */ struct MatchResult { /// マッチした? bool hit; /// マッチした位置 int start; /// マッチした位置 int end; /*! コンストラクタ */ MatchResult(bool aHit = false, int aStart = -1, int aEnd = -1) : hit(aHit), start(aStart), end(aEnd) { } }; //========================================================= /*! * context */ typedef Ptr ExpressionPtr; typedef Ptr ElementPtr; struct Context { /// ルール名とExpressionを対応付けるMapの型 typedef Map< ExpressionPtr > RulesMap; /// 解析中の文字列 String buf_; /// 解析中の位置 int pos_; /// ルール名とExpressionを対応付けるMap RulesMap rules_; /// コールバック用の任意の引数 void * option_; /// コールバック Callback callback_; /// factor の but_case のマネジメント ElementPtr but_case_; // コンストラクタ Context(); // ルール追加 void add_rule(String const & name, ExpressionPtr const & rule) { rules_.put(name, rule); } /*! * 解析 */ MatchResult parse(String const & target, String const & top_rule, void * option, Callback callback); // ルール名に対する Expression オブジェクト // 見つからなければNULL ExpressionPtr find_rule_expression(String const & name); // ルールがマッチした時にコールバックを行う void exec_callback(String const & rulename, MatchResult const & mr, int reason) const; // but_case にマッチするか? bool match_but_case(); // but_case のマネジメント ElementPtr set_but_case(ElementPtr const & but_case); // peek 1 char char_t peek1() const { if (pos_ < (int) buf_.length()) { return buf_[pos_]; } return 0; } // get 1 char char_t get1() { char_t c = peek1(); if (c != 0) { pos_++; } return c; } // getpos int getpos() const { return pos_; } // setpos void setpos(int p) { pos_ = p; } // pos_ からのサブシーケンスが arg とマッチするか? bool will_match(String const & arg) const { return buf_.compare(pos_, arg.length(), arg) == 0; } }; //========================================================= /*! * IMatcher */ class IMatcher { public: /*! * コンストラクタ */ IMatcher(); /*! * デストラクタ */ virtual ~IMatcher(); /*! * match */ virtual MatchResult match(Context* x) = 0; /*! * 文字列表現 */ virtual String str() const = 0; }; typedef Ptr IMatcherPtr; // デバグ用: IMatcherインスタンスがいくつ存在しているか? int _get_matchers_count(); //========================================================= /*! * Expression ::= term | term | ... */ class Term; typedef Ptr TermPtr; class Expression: public IMatcher { typedef List TermList; TermList terms_; public: /*! * add term */ void add(TermPtr const & t); /*! * match */ virtual MatchResult match(Context* x); /*! * str */ virtual String str() const; }; //========================================================= /*! * Term ::= factor factor ... */ class Factor; typedef Ptr FactorPtr; class Term: public IMatcher { typedef List FactorList; FactorList factors_; public: /*! * add factor */ void add(FactorPtr const & ); /*! * match */ virtual MatchResult match(Context* x); /*! * str */ virtual String str() const; }; //========================================================= /*! * Factor ::= element - element */ class Element; typedef Ptr ElementPtr; class Factor: public IMatcher { ElementPtr element_; ElementPtr but_; public: /*! ctor */ Factor(); void set_element(ElementPtr const & ); void set_but(ElementPtr const & ); /*! * match */ virtual MatchResult match(Context* x); /*! * str */ virtual String str() const; }; //========================================================= /*! * Element ::= atom [+*?] */ class Element: public IMatcher { IMatcherPtr atom_; int least_match_count_; int most_match_count_; public: /*! ctor */ Element(); void set_atom(IMatcherPtr const & ); void set_option_char(char_t opt); /*! * match */ virtual MatchResult match(Context* x); /*! * str */ virtual String str() const; }; //========================================================= /*! * rulename */ class Rulename: public IMatcher { String rulename_; public: /*! ctor */ Rulename(String const & ); const String& get_rulename() const; /*! * match */ virtual MatchResult match(Context* x); /*! * str */ virtual String str() const; }; typedef Ptr RulenamePtr; //========================================================= /*! * literal */ class Literal: public IMatcher { String literal_; public: /*! 内容物を指定してのコンストラクタ */ Literal(String const & ); void set_literal(String const & ); const String& get_literal() const; /*! * match */ virtual MatchResult match(Context* x); /*! * str */ virtual String str() const; }; typedef Ptr LiteralPtr; //========================================================= /*! * charclass */ class Charclass: public IMatcher { struct CharRange { char_t from, to; bool accept(char_t c) const { return from <= c && c <= to; } }; typedef List RangeList; RangeList ranges_; bool negate_; bool accept(char_t c); public: /*! ctor */ Charclass(): negate_(false) { } /*! negate */ void set_negate(bool n); /*! set range */ void add_range(char_t, char_t); /*! * match */ virtual MatchResult match(Context* x); /*! * str */ virtual String str() const; }; typedef Ptr CharclassPtr; } // end of namespace #endif // BNF_CXT_HPP_