1 /* 2 This file is part of the Grantlee template system. 3 4 Copyright (c) 2009,2010,2011 Stephen Kelly <steveire@gmail.com> 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either version 9 2.1 of the Licence, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 19 */ 20 21 #ifndef GRANTLEE_LEXER_P_H 22 #define GRANTLEE_LEXER_P_H 23 24 #include "textprocessingmachine_p.h" 25 #include "token.h" 26 27 #include <QList> 28 29 namespace Grantlee 30 { 31 32 class Lexer 33 { 34 public: 35 Lexer(const QString &templateString); 36 ~Lexer(); 37 38 enum TrimType { NoSmartTrim, SmartTrim }; 39 40 QList<Token> tokenize(TrimType type = NoSmartTrim); 41 42 void markStartSyntax(); 43 void markEndSyntax(); 44 void markNewline(); 45 void clearMarkers(); 46 void finalizeToken(); 47 void finalizeTokenWithTrimmedWhitespace(); 48 49 private: 50 void reset(); 51 void finalizeToken(int nextPosition, bool processSyntax); 52 53 private: 54 QString m_templateString; 55 56 QList<Token> m_tokenList; 57 int m_lineCount; 58 int m_upto; 59 int m_processedUpto; 60 int m_startSyntaxPosition; 61 int m_endSyntaxPosition; 62 int m_newlinePosition; 63 }; 64 65 struct NullLexerAction { doActionNullLexerAction66 static void doAction(Lexer *) {} 67 }; 68 69 template <typename TType, typename Test, typename Action1 = NullLexerAction, 70 typename Action2 = NullLexerAction> 71 class LexerObject : public TType 72 { 73 public: 74 LexerObject(Lexer *lexer, State<typename TType::Type> *sourceState = {}) TType(sourceState)75 : TType(sourceState), m_lexer(lexer) 76 { 77 } 78 characterTest(QString::const_iterator character)79 bool characterTest(QString::const_iterator character) 80 { 81 return Test::characterTest(character); 82 } 83 onTransition()84 void onTransition() { return Action1::doAction(m_lexer); } 85 onEntry()86 void onEntry() { return Action1::doAction(m_lexer); } 87 onExit()88 void onExit() { return Action2::doAction(m_lexer); } 89 90 private: 91 Lexer *const m_lexer; 92 }; 93 94 struct TokenFinalizer { doActionTokenFinalizer95 static void doAction(Lexer *lexer) { lexer->finalizeToken(); } 96 }; 97 98 struct TokenFinalizerWithTrimming { doActionTokenFinalizerWithTrimming99 static void doAction(Lexer *lexer) 100 { 101 lexer->finalizeTokenWithTrimmedWhitespace(); 102 } 103 }; 104 105 struct TokenFinalizerWithTrimmingAndNewline { doActionTokenFinalizerWithTrimmingAndNewline106 static void doAction(Lexer *lexer) 107 { 108 lexer->finalizeTokenWithTrimmedWhitespace(); 109 lexer->markNewline(); 110 } 111 }; 112 113 struct MarkStartSyntax { doActionMarkStartSyntax114 static void doAction(Lexer *lexer) { lexer->markStartSyntax(); } 115 }; 116 117 struct FinalizeAndMarkStartSyntax { doActionFinalizeAndMarkStartSyntax118 static void doAction(Lexer *lexer) 119 { 120 lexer->finalizeToken(); 121 lexer->markStartSyntax(); 122 } 123 }; 124 125 struct MarksClearer { doActionMarksClearer126 static void doAction(Lexer *lexer) { lexer->clearMarkers(); } 127 }; 128 129 struct MarkEndSyntax { doActionMarkEndSyntax130 static void doAction(Lexer *lexer) { lexer->markEndSyntax(); } 131 }; 132 133 struct MarkNewline { doActionMarkNewline134 static void doAction(Lexer *lexer) { lexer->markNewline(); } 135 }; 136 137 template <char c, typename Action = NullLexerAction> 138 class CharacterTransition 139 : public LexerObject<State<CharTransitionInterface>::Transition, 140 CharacterTest<c>, Action> 141 { 142 public: 143 CharacterTransition(Lexer *lexer, 144 State<CharTransitionInterface> *sourceState = {}) 145 : LexerObject<State<CharTransitionInterface>::Transition, 146 CharacterTest<c>, Action>(lexer, sourceState) 147 { 148 } 149 }; 150 151 template <char c, typename Action = NullLexerAction> 152 class NegateCharacterTransition 153 : public LexerObject<State<CharTransitionInterface>::Transition, 154 Negate<CharacterTest<c>>, Action> 155 { 156 public: 157 NegateCharacterTransition(Lexer *lexer, 158 State<CharTransitionInterface> *sourceState = {}) 159 : LexerObject<State<CharTransitionInterface>::Transition, 160 Negate<CharacterTest<c>>, Action>(lexer, sourceState) 161 { 162 } 163 }; 164 } 165 166 #endif 167