30static constexpr const char HEADER[] =
32 " * Copyright 2017 Google Inc.\n"
34 " * Use of this source code is governed by a BSD-style license that can be\n"
35 " * found in the LICENSE file.\n"
37 "/*****************************************************************************************\n"
38 " ******************** This file was generated by sksllex. Do not edit. *******************\n"
39 " *****************************************************************************************/\n";
41static void writeH(
const DFA& dfa,
const char* lexer,
const char* token,
42 const std::vector<std::string>&
tokens,
const char* hPath) {
43 std::ofstream
out(hPath);
46 out <<
"#ifndef SKSL_" << lexer <<
"\n";
47 out <<
"#define SKSL_" << lexer <<
"\n";
48 out <<
"#include <cstdint>\n";
49 out <<
"#include <string_view>\n";
50 out <<
"namespace SkSL {\n";
52 out <<
"struct " << token <<
" {\n";
53 out <<
" enum class Kind {\n";
54 for (
const std::string& t :
tokens) {
55 out <<
" TK_" << t <<
",\n";
61 )" << token << "() {}";
63 out << token << R
"((Kind kind, int32_t offset, int32_t length)
68 Kind fKind = Kind::TK_NONE;
73class )" << lexer << R"( {
75 void start(std::string_view text) {
80 )" << token << R"( next();
86 Checkpoint getCheckpoint() const {
90 void rewindToCheckpoint(Checkpoint checkpoint) {
91 fOffset = checkpoint.fOffset;
95 std::string_view fText;
104static void writeCPP(
const DFA& dfa,
const char* lexer,
const char* token,
const char* include,
105 const char* cppPath) {
106 std::ofstream
out(cppPath);
109 out <<
"#include \"" << include <<
"\"\n";
111 out <<
"namespace SkSL {\n";
116 states =
std::max(states, row.size());
118 out <<
"using State = " << (states <= 256 ?
"uint8_t" :
"uint16_t") <<
";\n";
121 size_t startChar = 0;
131 out <<
"static constexpr uint8_t kInvalidChar = 18;";
132 out <<
"static constexpr uint8_t kMappings[" << dfa.
fCharMappings.size() - startChar <<
"] = {";
133 for (
size_t index = startChar; index < dfa.
fCharMappings.size(); ++index) {
140 out <<
"static const uint8_t kAccepts[" << states <<
"] = {";
141 for (
size_t i = 0;
i < states; ++
i) {
151 out << token <<
" " << lexer <<
"::next() {";
153 // Note that we cheat here: normally a lexer needs to worry about the case
154 // where a token has a prefix which is not itself a valid token - for instance,
155 // maybe we have a valid token 'while', but 'w', 'wh', etc. are not valid
156 // tokens. Our grammar doesn't have this property, so we can simplify the logic
158 int32_t startOffset = fOffset;
161 if (fOffset >= (int32_t)fText.length()) {
162 if (startOffset == (int32_t)fText.length() || kAccepts[state] == 255) {
163 return )" << token << "(" << token << R
"(::Kind::TK_END_OF_FILE, startOffset, 0);
167 uint8_t c = (uint8_t)(fText[fOffset] - )" << startChar << R"();
168 if (c >= )" << dfa.fCharMappings.size() - startChar << R"() {
171 State newState = get_transition(kMappings[c], state);
178 Token::Kind kind = ()" << token << R"(::Kind) kAccepts[state];
179 return )" << token << R"((kind, startOffset, fOffset - startOffset);
186static void process(
const char* inPath,
const char* lexer,
const char* token,
const char* hPath,
187 const char* cppPath) {
189 std::vector<std::string>
tokens;
190 tokens.push_back(
"END_OF_FILE");
192 std::ifstream in(inPath);
193 while (std::getline(in,
line)) {
194 if (
line.length() == 0) {
197 if (
line.length() >= 2 &&
line[0] ==
'/' &&
line[1] ==
'/') {
200 std::istringstream split(
line);
201 std::string
name, delimiter, pattern;
202 if (split >>
name >> delimiter >> pattern) {
208 if (pattern[0] ==
'"') {
209 SkASSERT(pattern.size() > 2 && pattern[pattern.size() - 1] ==
'"');
211 for (
size_t i = 2;
i < pattern.size() - 1; ++
i) {
225 writeCPP(dfa, lexer, token, (std::string(
"src/sksl/SkSL") + lexer +
".h").c_str(), cppPath);
228int main(
int argc,
const char**
argv) {
230 printf(
"usage: sksllex <input.lex> <lexername> <tokenname> <output.h> <output.cpp>\n");
void WriteTransitionTable(std::ofstream &out, const DFA &dfa, size_t states)
static float max(float r, float g, float b)
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
DEF_SWITCHES_START aot vmservice shared library name
def parse(repo_root, recipes_cfg_path)
static SkString to_string(int n)
int main(int argc, const char **argv)
static constexpr const char HEADER[]
static void writeH(const DFA &dfa, const char *lexer, const char *token, const std::vector< std::string > &tokens, const char *hPath)
static void writeCPP(const DFA &dfa, const char *lexer, const char *token, const char *include, const char *cppPath)
static void process(const char *inPath, const char *lexer, const char *token, const char *hPath, const char *cppPath)
std::vector< int > fCharMappings
std::vector< int > fAccepts
std::vector< std::vector< int > > fTransitions
int addRegex(const RegexNode ®ex)