Tensorium
Loading...
Searching...
No Matches
Latex.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <vector>
5#include <unordered_map>
6#include <cctype>
7
17
18enum class GreekSymbolminus {
21 lambda, mu, nu, xi, omicron,
23 phi, chi, psi, omega
24};
25
26enum class GreekSymbolplus {
29 Lambda, Mu, Nu, Xi, Omicron,
31 Phi, Chi, Psi, Omega
32};
33
34
35struct Token {
39 std::string value;
40
41 Token(TokenType t, const std::string& val)
42 : type(t), value(val) {}
43
44 Token(TokenType t, GreekSymbolminus g, GreekSymbolplus G, const std::string& val)
45 : type(t), greek_minus(g), greek_plus(G), value(val) {}
46};
47
48
49class Lexer {
50 public:
51 explicit Lexer(const std::string& input) : input(input), pos(0) {}
52
53 std::vector<Token> tokenize() {
54 std::vector<Token> tokens;
55
56 while (!eof()) {
58 char c = peek();
59
60 if (std::isdigit(c)) {
61 tokens.push_back(parseNumber());
62 } else if (c == '\\' || std::isalpha(c)) {
63 tokens.push_back(parseCommandOrSymbol());
64 } else {
65 std::string s(1, get());
66 auto it = SyntaxTable.find(s);
67 tokens.push_back({
68 it != SyntaxTable.end() ? it->second : TokenType::unknown,
69 s
70 });
71 }
72 }
73
74 tokens.emplace_back(TokenType::end, "");
75 return tokens;
76 }
77
78 private:
79 std::string input;
80 size_t pos;
81
82 char peek() const {
83 return pos < input.size() ? input[pos] : '\0';
84 }
85
86 char get() {
87 return pos < input.size() ? input[pos++] : '\0';
88 }
89
90 bool eof() const {
91 return pos >= input.size();
92 }
93
95 while (!eof() && std::isspace(peek()))
96 get();
97 }
98
100 std::string num;
101 bool has_dot = false;
102
103 while (!eof() && (std::isdigit(peek()) || peek() == '.')) {
104 if (peek() == '.') has_dot = true;
105 num += get();
106 }
107
108 return {
110 num
111 };
112 }
113
115 std::string s;
116 if (peek() == '\\') s += get();
117
118 while (!eof() && (std::isalpha(peek()) || peek() == '_')) {
119 s += get();
120 }
121
122 if (auto gmin = GreekMapLower.find(s); gmin != GreekMapLower.end()) {
123 return Token(TokenType::symbol, gmin->second, GreekSymbolplus::Alpha, s);
124 }
125
126 if (auto gmaj = GreekMapUpper.find(s); gmaj != GreekMapUpper.end()) {
127 return Token(TokenType::symbol, GreekSymbolminus::alpha, gmaj->second, s);
128 }
129
130 if (auto tok = SyntaxTable.find(s); tok != SyntaxTable.end()) {
131 return Token(tok->second, s);
132 }
133
134 return Token(TokenType::symbol, s);
135 }
136
137 private:
138 inline static const std::unordered_map<std::string, TokenType> SyntaxTable = {
141 {"d", TokenType::derivative}, {"\\partial", TokenType::partial}, {"\\int", TokenType::integral},
143 {"\\cdot", TokenType::inner}, {"\\otimes", TokenType::outer},
144 };
145
146 inline static const std::unordered_map<std::string, GreekSymbolminus> GreekMapLower = {
147 {"\\alpha", GreekSymbolminus::alpha}, {"\\beta", GreekSymbolminus::beta},
148 {"\\gamma", GreekSymbolminus::gamma}, {"\\delta", GreekSymbolminus::delta},
149 {"\\epsilon", GreekSymbolminus::epsilon}, {"\\zeta", GreekSymbolminus::zeta},
150 {"\\eta", GreekSymbolminus::eta}, {"\\theta", GreekSymbolminus::theta},
151 {"\\iota", GreekSymbolminus::iota}, {"\\kappa", GreekSymbolminus::kappa},
152 {"\\lambda", GreekSymbolminus::lambda}, {"\\mu", GreekSymbolminus::mu},
153 {"\\nu", GreekSymbolminus::nu}, {"\\xi", GreekSymbolminus::xi},
154 {"\\omicron", GreekSymbolminus::omicron}, {"\\pi", GreekSymbolminus::pi},
155 {"\\rho", GreekSymbolminus::rho}, {"\\sigma", GreekSymbolminus::sigma},
156 {"\\tau", GreekSymbolminus::tau}, {"\\upsilon", GreekSymbolminus::upsilon},
157 {"\\phi", GreekSymbolminus::phi}, {"\\chi", GreekSymbolminus::chi},
158 {"\\psi", GreekSymbolminus::psi}, {"\\omega", GreekSymbolminus::omega}
159 };
160
161 inline static const std::unordered_map<std::string, GreekSymbolplus> GreekMapUpper = {
162 {"\\Alpha", GreekSymbolplus::Alpha}, {"\\Beta", GreekSymbolplus::Beta},
163 {"\\Gamma", GreekSymbolplus::Gamma}, {"\\Delta", GreekSymbolplus::Delta},
164 {"\\Epsilon", GreekSymbolplus::Epsilon}, {"\\Zeta", GreekSymbolplus::Zeta},
165 {"\\Eta", GreekSymbolplus::Eta}, {"\\Theta", GreekSymbolplus::Theta},
166 {"\\Iota", GreekSymbolplus::Iota}, {"\\Kappa", GreekSymbolplus::Kappa},
167 {"\\Lambda", GreekSymbolplus::Lambda}, {"\\Mu", GreekSymbolplus::Mu},
168 {"\\Nu", GreekSymbolplus::Nu}, {"\\Xi", GreekSymbolplus::Xi},
169 {"\\Omicron", GreekSymbolplus::Omicron}, {"\\Pi", GreekSymbolplus::Pi},
170 {"\\Rho", GreekSymbolplus::Rho}, {"\\Sigma", GreekSymbolplus::Sigma},
171 {"\\Tau", GreekSymbolplus::Tau}, {"\\Upsilon", GreekSymbolplus::Upsilon},
172 {"\\Phi", GreekSymbolplus::Phi}, {"\\Chi", GreekSymbolplus::Chi},
173 {"\\Psi", GreekSymbolplus::Psi}, {"\\Omega", GreekSymbolplus::Omega}
174 };
175
176};
TokenType
Definition Latex.hpp:8
GreekSymbolminus
Definition Latex.hpp:18
GreekSymbolplus
Definition Latex.hpp:26
Definition Latex.hpp:49
size_t pos
Definition Latex.hpp:80
char peek() const
Definition Latex.hpp:82
static const std::unordered_map< std::string, GreekSymbolplus > GreekMapUpper
Definition Latex.hpp:161
std::string input
Definition Latex.hpp:79
char get()
Definition Latex.hpp:86
void skipWhitespace()
Definition Latex.hpp:94
static const std::unordered_map< std::string, TokenType > SyntaxTable
Definition Latex.hpp:138
static const std::unordered_map< std::string, GreekSymbolminus > GreekMapLower
Definition Latex.hpp:146
Token parseNumber()
Definition Latex.hpp:99
bool eof() const
Definition Latex.hpp:90
Token parseCommandOrSymbol()
Definition Latex.hpp:114
Lexer(const std::string &input)
Definition Latex.hpp:51
std::vector< Token > tokenize()
Definition Latex.hpp:53
Definition Latex.hpp:35
std::string value
Definition Latex.hpp:39
TokenType type
Definition Latex.hpp:36
Token(TokenType t, const std::string &val)
Definition Latex.hpp:41
GreekSymbolplus greek_plus
Definition Latex.hpp:38
Token(TokenType t, GreekSymbolminus g, GreekSymbolplus G, const std::string &val)
Definition Latex.hpp:44
GreekSymbolminus greek_minus
Definition Latex.hpp:37