1#!/usr/bin/env ruby 2# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15require 'erb' 16require 'ostruct' 17require 'set' 18 19keywords = [ 20 # keywords start with 'a' 21 { 22 "abstract" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ABSTRACT"], 23 "any" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ANY"], 24 "arguments" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ARGUMENTS"], 25 "as" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_AS"], 26 "asserts" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ASSERTS"], 27 "async" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ASYNC"], 28 "await" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_AWAIT"], 29 "accessor" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ACCESSOR"], 30 }, 31 32 # keywords start with 'b' 33 { 34 "bigint" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_BIGINT"], 35 "boolean" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_BOOLEAN"], 36 "break" => ["TokenType::KEYW_BREAK", "TokenType::KEYW_BREAK"], 37 }, 38 39 # keywords start with 'c' 40 { 41 "case" => ["TokenType::KEYW_CASE", "TokenType::KEYW_CASE"], 42 "catch" => ["TokenType::KEYW_CATCH", "TokenType::KEYW_CATCH"], 43 "class" => ["TokenType::KEYW_CLASS", "TokenType::KEYW_CLASS"], 44 "const" => ["TokenType::KEYW_CONST", "TokenType::KEYW_CONST"], 45 "continue" => ["TokenType::KEYW_CONTINUE", "TokenType::KEYW_CONTINUE"] 46 }, 47 48 # keywords start with 'd' 49 { 50 "debugger" => ["TokenType::KEYW_DEBUGGER", "TokenType::KEYW_DEBUGGER"], 51 "declare" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_DECLARE"], 52 "default" => ["TokenType::KEYW_DEFAULT", "TokenType::KEYW_DEFAULT"], 53 "delete" => ["TokenType::KEYW_DELETE", "TokenType::KEYW_DELETE"], 54 "do" => ["TokenType::KEYW_DO", "TokenType::KEYW_DO"], 55 }, 56 57 # keywords start with 'e' 58 { 59 "else" => ["TokenType::KEYW_ELSE", "TokenType::KEYW_ELSE"], 60 "enum" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ENUM"], 61 "eval" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_EVAL"], 62 "export" => ["TokenType::KEYW_EXPORT", "TokenType::KEYW_EXPORT"], 63 "extends" => ["TokenType::KEYW_EXTENDS", "TokenType::KEYW_EXTENDS"], 64 }, 65 66 # keywords start with 'f' 67 { 68 "false" => ["TokenType::LITERAL_FALSE", "TokenType::LITERAL_FALSE"], 69 "finally" => ["TokenType::KEYW_FINALLY", "TokenType::KEYW_FINALLY"], 70 "for" => ["TokenType::KEYW_FOR", "TokenType::KEYW_FOR"], 71 "from" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_FROM"], 72 "function" => ["TokenType::KEYW_FUNCTION", "TokenType::KEYW_FUNCTION"], 73 }, 74 75 # keywords start with 'g' 76 { 77 "get" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_GET"], 78 "global" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_GLOBAL"], 79 }, 80 81 # keywords start with 'i' 82 { 83 "if" => ["TokenType::KEYW_IF", "TokenType::KEYW_IF"], 84 "implements" => ["TokenType::KEYW_IMPLEMENTS", "TokenType::KEYW_IMPLEMENTS"], 85 "import" => ["TokenType::KEYW_IMPORT", "TokenType::KEYW_IMPORT"], 86 "in" => ["TokenType::KEYW_IN", "TokenType::KEYW_IN"], 87 "infer" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_INFER"], 88 "instanceof" => ["TokenType::KEYW_INSTANCEOF", "TokenType::KEYW_INSTANCEOF"], 89 "interface" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_INTERFACE"], 90 "is" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_IS"], 91 }, 92 93 # keywords start with 'k' 94 { 95 "keyof" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_KEYOF"], 96 }, 97 98 # keywords start with 'l' 99 { 100 "let" => ["TokenType::KEYW_LET", "TokenType::KEYW_LET"], 101 }, 102 103 # keywords start with 'm' 104 { 105 "meta" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_META"], 106 "module" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_MODULE"], 107 "namespace" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NAMESPACE"], 108 }, 109 110 # keywords start with 'n' 111 { 112 "never" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NEVER"], 113 "new" => ["TokenType::KEYW_NEW", "TokenType::KEYW_NEW"], 114 "null" => ["TokenType::LITERAL_NULL", "TokenType::LITERAL_NULL"], 115 "number" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NUMBER"], 116 }, 117 118 # keywords start with 'o' 119 { 120 "object" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OBJECT"], 121 "of" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OF"], 122 "out" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OUT"], 123 "override" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OVERRIDE"], 124 }, 125 126 # keywords start with 'p' 127 { 128 "package" => ["TokenType::KEYW_PACKAGE", "TokenType::KEYW_PACKAGE"], 129 "private" => ["TokenType::KEYW_PRIVATE", "TokenType::KEYW_PRIVATE"], 130 "protected" => ["TokenType::KEYW_PROTECTED", "TokenType::KEYW_PROTECTED"], 131 "public" => ["TokenType::KEYW_PUBLIC", "TokenType::KEYW_PUBLIC"], 132 }, 133 134 # keywords start with 'r' 135 { 136 "readonly" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_READONLY"], 137 "return" => ["TokenType::KEYW_RETURN", "TokenType::KEYW_RETURN"], 138 "require" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_REQUIRE"], 139 }, 140 141 # keywords start with 's' 142 { 143 "satisfies" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SATISFIES"], 144 "set" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SET"], 145 "static" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STATIC"], 146 "string" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STRING"], 147 "super" => ["TokenType::KEYW_SUPER", "TokenType::KEYW_SUPER"], 148 "switch" => ["TokenType::KEYW_SWITCH", "TokenType::KEYW_SWITCH"], 149 "symbol" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SYMBOL"], 150 }, 151 152 # keywords start with 't' 153 { 154 "this" => ["TokenType::KEYW_THIS", "TokenType::KEYW_THIS"], 155 "throw" => ["TokenType::KEYW_THROW", "TokenType::KEYW_THROW"], 156 "true" => ["TokenType::LITERAL_TRUE", "TokenType::LITERAL_TRUE"], 157 "try" => ["TokenType::KEYW_TRY", "TokenType::KEYW_TRY"], 158 "type" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_TYPE"], 159 "typeof" => ["TokenType::KEYW_TYPEOF", "TokenType::KEYW_TYPEOF"], 160 }, 161 162 # keywords start with 'u' 163 { 164 "undefined" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNDEFINED"], 165 "unique" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNIQUE"], 166 "unknown" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNKNOWN"], 167 }, 168 169 # keywords start with 'v' 170 { 171 "var" => ["TokenType::KEYW_VAR", "TokenType::KEYW_VAR"], 172 "void" => ["TokenType::KEYW_VOID", "TokenType::KEYW_VOID"], 173 }, 174 175 # keywords start with 'w' 176 { 177 "while" => ["TokenType::KEYW_WHILE", "TokenType::KEYW_WHILE"], 178 "with" => ["TokenType::KEYW_WITH", "TokenType::KEYW_WITH"], 179 }, 180 181 # keywords start with 'y' 182 { 183 "yield" => ["TokenType::KEYW_YIELD", "TokenType::KEYW_YIELD"], 184 }, 185] 186 187def collect_functions(functions, keys) 188 offset = 0 189 190 while true 191 has_more = false 192 193 keys.each do |key| 194 if key.length < offset + 1 195 next 196 end 197 198 has_more = true 199 func_name = key[0..offset]; 200 201 if functions.has_key?(func_name) 202 functions[func_name].add(key[offset + 1]) 203 else 204 functions[func_name] = Set[key[offset + 1]] 205 end 206 end 207 208 if has_more 209 offset += 1 210 next 211 end 212 213 break 214 end 215end 216 217def generate(keywords, template_file, output_file) 218 functions = {} 219 keywords.each do |group| 220 collect_functions(functions, group.keys) 221 end 222 223 template = File.read(template_file) 224 t = ERB.new(template, nil, '%-') 225 t.filename = OpenStruct.new.template 226 res = t.result(binding) 227 228 File.open(output_file, "w") do |file| 229 file.write(res) 230 end 231end 232 233abort "Failed: input file required!" if ARGV.size < 2 234 235generate(keywords, ARGV[0], ARGV[1]) 236