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