-
Notifications
You must be signed in to change notification settings - Fork 347
/
Copy pathtemplate.h
153 lines (119 loc) · 5.76 KB
/
template.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// Created by huangyuyang on 5/29/24.
//
#ifndef FASTLLM_TEMPLATE_H
#define FASTLLM_TEMPLATE_H
#include "utils/utils.h"
namespace fastllm {
struct JinjaVar {
enum JinjaVarType {
JinjaNone = 0, JinjaInt = 1, JinjaFloat = 2, JinjaString = 3,
JinjaArray = 100, JinjaDict = 101
};
JinjaVarType type = JinjaNone;
long long intValue = 0LL;
float floatValue = 0.0f;
std::string stringValue;
std::vector <JinjaVar> arrayValue;
std::map <std::string, JinjaVar> dictValue;
JinjaVar () {}
JinjaVar (int intValue) : type(JinjaInt), intValue(intValue) {}
JinjaVar (long long intValue) : type(JinjaInt), intValue(intValue) {}
JinjaVar (float floatValue) : type(JinjaFloat), floatValue(floatValue) {}
JinjaVar (const char *stringValue) : type(JinjaString), stringValue(stringValue) {}
JinjaVar (const std::string &stringValue) : type(JinjaString), stringValue(stringValue) {}
JinjaVar (const std::vector <JinjaVar> &vars) : type(JinjaArray), arrayValue(vars) {}
JinjaVar (std::initializer_list <std::pair <std::string, JinjaVar> > dict) : type(JinjaDict) {
for (auto &it : dict) {
this->dictValue[it.first] = it.second;
}
}
JinjaVar (JinjaVarType type, const std::string &value) : type(type), stringValue(value) {}
bool BoolValue() const;
JinjaVar &operator[] (const JinjaVar &b);
std::string DirectValue() const;
std::string Dump() const;
};
using JinjaArray = std::vector <JinjaVar>;
// 词法分析后的Token
struct JinjaToken {
enum JinjaToKenType {
JinjaTokenID = 0, JinjaTokenBOOL, JinjaTokenNUM, JinjaTokenSTRING, JinjaTokenDOT,
JinjaTokenLMB, JinjaTokenRMB, JinjaTokenLSB, JinjaTokenRSB,
JinjaTokenSet, JinjaTokenFor, JinjaTokenEndFor, JinjaTokenIf, JinjaTokenElse, JinjaTokenElseIf, JinjaTokenEndif,
JinjaTokenIn,
JinjaTokenAssign, JinjaTokenNotEqual, JinjaTokenEqual, JinjaTokenAdd, JinjaTokenSub, JinjaTokenMul, JinjaTokenDiv, JinjaTokenMod,
JinjaTokenNot, JinjaTokenAnd, JinjaTokenOr,
JinjaTokenFilter, JinjaTokenNamespace, JinjaTokenSlice
};
JinjaToKenType type;
std::string value;
JinjaToken (JinjaToKenType type, const std::string &value = "") : type(type), value(value) {}
};
static std::map <char, JinjaToken::JinjaToKenType> singleCharTokens = {
{'(', JinjaToken::JinjaToKenType::JinjaTokenLSB},
{')', JinjaToken::JinjaToKenType::JinjaTokenRSB},
{'[', JinjaToken::JinjaToKenType::JinjaTokenLMB},
{']', JinjaToken::JinjaToKenType::JinjaTokenRMB},
{'.', JinjaToken::JinjaToKenType::JinjaTokenDOT},
{'+', JinjaToken::JinjaToKenType::JinjaTokenAdd},
{'-', JinjaToken::JinjaToKenType::JinjaTokenSub},
{'*', JinjaToken::JinjaToKenType::JinjaTokenMul},
{'/', JinjaToken::JinjaToKenType::JinjaTokenDiv},
{'%', JinjaToken::JinjaToKenType::JinjaTokenMod},
{'|', JinjaToken::JinjaToKenType::JinjaTokenFilter},
{':', JinjaToken::JinjaToKenType::JinjaTokenSlice}
};
static std::map <char, char> escapeChars = {
{'n', '\n'}, {'r', '\r'}, {'t', '\t'}, {'b', '\b'}, {'f', '\f'}, {'v', '\v'}, {'\\', '\\'},
{'\'', '\''}, {'\"', '\"'}, {'0', '\0'}
};
static std::map <std::string, JinjaToken::JinjaToKenType> keyWords = {
{"for", JinjaToken::JinjaToKenType::JinjaTokenFor},
{"endfor", JinjaToken::JinjaToKenType::JinjaTokenEndFor},
{"if", JinjaToken::JinjaToKenType::JinjaTokenIf},
{"elif", JinjaToken::JinjaToKenType::JinjaTokenElseIf},
{"else", JinjaToken::JinjaToKenType::JinjaTokenElse},
{"endif", JinjaToken::JinjaToKenType::JinjaTokenEndif},
{"set", JinjaToken::JinjaToKenType::JinjaTokenSet},
{"in", JinjaToken::JinjaToKenType::JinjaTokenIn},
{"is", JinjaToken::JinjaToKenType::JinjaTokenIn},
{"true", JinjaToken::JinjaToKenType::JinjaTokenBOOL},
{"false", JinjaToken::JinjaToKenType::JinjaTokenBOOL},
{"and", JinjaToken::JinjaToKenType::JinjaTokenAnd},
{"or", JinjaToken::JinjaToKenType::JinjaTokenOr},
{"not", JinjaToken::JinjaToKenType::JinjaTokenNot},
{"namespace", JinjaToken::JinjaToKenType::JinjaTokenNamespace}
};
// 一个Jinja块
struct JinjaBlock {
enum JinjaBlockType {
JinjaBlockOriginal = 0, JinjaBlockEmpty, JinjaBlockVar, JinjaBlockFor,
JinjaBlockEndFor, JinjaBlockIf, JinjaBlockElseIf, JinjaBlockElse, JinjaBlockEndIf,
JinjaBlockSet
};
JinjaBlockType type = JinjaBlockType::JinjaBlockOriginal;
std::string value;
std::vector <JinjaToken> tokens;
bool IsWhite(char c);
bool IsDigit(char c);
bool IsAlpha(char c);
int FindNextChar(int pos, int end, int target);
JinjaBlock () {}
JinjaBlock(const std::string &value);
};
JinjaVar JinjaBinaryOp(const JinjaVar &a, const JinjaVar &b, JinjaToken::JinjaToKenType op);
JinjaVar JinjaTrim(const JinjaVar &a);
int GetOpLevel(JinjaToken::JinjaToKenType type);
// Jinja模板
struct JinjaTemplate {
std::string temp;
std::vector <JinjaBlock> blocks;
JinjaTemplate () {}
JinjaTemplate (const std::string &temp);
JinjaVar ComputeExpression(JinjaVar &local, std::vector <JinjaToken> tokens, int st, int end);
void Parse(int st, int end, JinjaVar &var, std::string &ret);
std::string Apply(const JinjaVar &var);
};
}
#endif //FASTLLM_TEMPLATE_H