// Copyright (C) 2000-2007, Luca Padovani . // // This file is part of GtkMathView, a flexible, high-quality rendering // engine for MathML documents. // // GtkMathView is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // GtkMathView is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . #ifndef __TemplateStringParsers_hh__ #define __TemplateStringParsers_hh__ #include "TokenSet.hh" #include "TemplateStringScanners.hh" #include "Variant.hh" #include "Length.hh" #include "ValueConversion.hh" typedef Set TokenSet_Boolean; typedef Set TokenSet_Unit; class ParseBin { public: static inline bool sequence(void) { return false; } static bool parseInSequence(const UCS4String::const_iterator&, const UCS4String::const_iterator&, UCS4String::const_iterator&, std::vector< SmartPtr >&) { assert(false); return false; } }; template class Parse : public ParseBin { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { UCS4String::const_iterator p; ScanSpaces::scan(begin, end, p); if (Scanner::scan(p, end, next)) { NativeType v = Scanner::parse(p, next); return Variant::create(v); } return 0; } }; template <> class Parse { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { UCS4String::const_iterator p; ScanSpaces::scan(begin, end, p); if (ScanToken::scan(p, end, next)) { TokenId id = ScanToken::parse(p, next); if (TokenSet_Boolean::has(id)) return Variant::create(id == T_TRUE); } return 0; } }; class ParseLength : public ParseBin { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { UCS4String::const_iterator p; ScanSpaces::scan(begin, end, p); if (ScanNumber::scan(p, end, next)) { float v = ScanNumber::parse(p, next); p = next; ScanSpaces::scan(p, end, next); p = next; if (ScanToken::scan(p, end, next)) { TokenId id = ScanToken::parse(p, next); if (TokenSet_Unit::has(id)) return Variant::create(Length(v, toUnitId(id))); } } return 0; } }; class ParseString : public ParseBin { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { next = end; return Variant::create(Scan::toString(begin, end)); } }; class ParseKeyword : public ParseBin { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { UCS4String::const_iterator p; ScanSpaces::scan(begin, end, p); if (ScanKeywordToken::scan(p, end, next)) return Variant::create(Scan::toString(p, next)); else return 0; } }; template class ParseTokenSet : public ParseBin { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { UCS4String::const_iterator p; ScanSpaces::scan(begin, end, p); if (ScanToken::scan(p, end, next)) { TokenId id = ScanToken::parse(p, next); if (TokenSet::has(id)) return Variant::create(id); } return 0; } }; template class ParseToken : public ParseTokenSet< Singleton > { }; template class ParseChoice : public ParseBin { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { if (SmartPtr v = P1::parse(begin, end, next)) return v; else return P2::parse(begin, end, next); } }; template class ParseSeq { public: static inline bool sequence(void) { return true; } static bool parseInSequence(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next, std::vector< SmartPtr >& content) { UCS4String::const_iterator p; if (P1::sequence()) { if (!P1::parseInSequence(begin, end, p, content)) return false; } else if (SmartPtr v = P1::parse(begin, end, p)) content.push_back(v); else return false; if (P2::sequence()) { if (!P2::parseInSequence(p, end, next, content)) return false; } else if (SmartPtr v = P2::parse(p, end, next)) content.push_back(v); else return false; return true; } static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { std::vector< SmartPtr > content; if (parseInSequence(begin, end, next, content)) return Variant > >::create(content); else return 0; } }; template class ParseZeroOrOne : public ParseBin { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { if (SmartPtr v = P::parse(begin, end, next)) return v; else { next = begin; return Variant::create(); } } }; template class ParseOneOrMore : public ParseBin { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { UCS4String::const_iterator p = begin; std::vector< SmartPtr > content; while (SmartPtr v = P::parse(p, end, next)) { content.push_back(v); p = next; } if (!content.empty()) { next = p; return Variant< std::vector< SmartPtr > >::create(content); } else return 0; } }; template class ParseZeroOrMore : public ParseZeroOrOne< ParseOneOrMore

> { }; class ParseRGBColor { public: static SmartPtr parse(const UCS4String::const_iterator& begin, const UCS4String::const_iterator& end, UCS4String::const_iterator& next) { UCS4String::const_iterator p; ScanSpaces::scan(begin, end, p); if (ScanRGBColor::scan(p, end, next)) return Variant::create(ScanRGBColor::parse(p, next)); else return 0; } }; #endif // __TemplateStringParsers_hh__