File indexing completed on 2025-02-09 04:28:37
0001 /* 0002 This file is part of the KTextTemplate library 0003 0004 SPDX-FileCopyrightText: 2009, 2010, 2011 Stephen Kelly <steveire@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 0008 */ 0009 0010 #ifndef KTEXTTEMPLATE_LEXER_P_H 0011 #define KTEXTTEMPLATE_LEXER_P_H 0012 0013 #include "textprocessingmachine_p.h" 0014 #include "token.h" 0015 0016 #include <QList> 0017 0018 namespace KTextTemplate 0019 { 0020 0021 class Lexer 0022 { 0023 public: 0024 explicit Lexer(const QString &templateString); 0025 ~Lexer(); 0026 0027 enum TrimType { NoSmartTrim, SmartTrim }; 0028 0029 QList<Token> tokenize(TrimType type = NoSmartTrim); 0030 0031 void markStartSyntax(); 0032 void markEndSyntax(); 0033 void markNewline(); 0034 void clearMarkers(); 0035 void finalizeToken(); 0036 void finalizeTokenWithTrimmedWhitespace(); 0037 0038 private: 0039 void reset(); 0040 void finalizeToken(int nextPosition, bool processSyntax); 0041 0042 private: 0043 QString m_templateString; 0044 0045 QList<Token> m_tokenList; 0046 int m_lineCount; 0047 int m_upto; 0048 int m_processedUpto; 0049 int m_startSyntaxPosition; 0050 int m_endSyntaxPosition; 0051 int m_newlinePosition; 0052 }; 0053 0054 struct NullLexerAction { 0055 static void doAction(Lexer *) 0056 { 0057 } 0058 }; 0059 0060 template<typename TType, typename Test, typename Action1 = NullLexerAction, typename Action2 = NullLexerAction> 0061 class LexerObject : public TType 0062 { 0063 public: 0064 LexerObject(Lexer *lexer, State<typename TType::Type> *sourceState = {}) 0065 : TType(sourceState) 0066 , m_lexer(lexer) 0067 { 0068 } 0069 0070 bool characterTest(QString::const_iterator character) 0071 { 0072 return Test::characterTest(character); 0073 } 0074 0075 void onTransition() 0076 { 0077 Action1::doAction(m_lexer); 0078 } 0079 0080 void onEntry() 0081 { 0082 Action1::doAction(m_lexer); 0083 } 0084 0085 void onExit() 0086 { 0087 Action2::doAction(m_lexer); 0088 } 0089 0090 private: 0091 Lexer *const m_lexer; 0092 }; 0093 0094 struct TokenFinalizer { 0095 static void doAction(Lexer *lexer) 0096 { 0097 lexer->finalizeToken(); 0098 } 0099 }; 0100 0101 struct TokenFinalizerWithTrimming { 0102 static void doAction(Lexer *lexer) 0103 { 0104 lexer->finalizeTokenWithTrimmedWhitespace(); 0105 } 0106 }; 0107 0108 struct TokenFinalizerWithTrimmingAndNewline { 0109 static void doAction(Lexer *lexer) 0110 { 0111 lexer->finalizeTokenWithTrimmedWhitespace(); 0112 lexer->markNewline(); 0113 } 0114 }; 0115 0116 struct MarkStartSyntax { 0117 static void doAction(Lexer *lexer) 0118 { 0119 lexer->markStartSyntax(); 0120 } 0121 }; 0122 0123 struct FinalizeAndMarkStartSyntax { 0124 static void doAction(Lexer *lexer) 0125 { 0126 lexer->finalizeToken(); 0127 lexer->markStartSyntax(); 0128 } 0129 }; 0130 0131 struct MarksClearer { 0132 static void doAction(Lexer *lexer) 0133 { 0134 lexer->clearMarkers(); 0135 } 0136 }; 0137 0138 struct MarkEndSyntax { 0139 static void doAction(Lexer *lexer) 0140 { 0141 lexer->markEndSyntax(); 0142 } 0143 }; 0144 0145 struct MarkNewline { 0146 static void doAction(Lexer *lexer) 0147 { 0148 lexer->markNewline(); 0149 } 0150 }; 0151 0152 template<char c, typename Action = NullLexerAction> 0153 class CharacterTransition : public LexerObject<State<CharTransitionInterface>::Transition, CharacterTest<c>, Action> 0154 { 0155 public: 0156 CharacterTransition(Lexer *lexer, State<CharTransitionInterface> *sourceState = {}) 0157 : LexerObject<State<CharTransitionInterface>::Transition, CharacterTest<c>, Action>(lexer, sourceState) 0158 { 0159 } 0160 }; 0161 0162 template<char c, typename Action = NullLexerAction> 0163 class NegateCharacterTransition : public LexerObject<State<CharTransitionInterface>::Transition, Negate<CharacterTest<c>>, Action> 0164 { 0165 public: 0166 NegateCharacterTransition(Lexer *lexer, State<CharTransitionInterface> *sourceState = {}) 0167 : LexerObject<State<CharTransitionInterface>::Transition, Negate<CharacterTest<c>>, Action>(lexer, sourceState) 0168 { 0169 } 0170 }; 0171 } 0172 0173 #endif