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 "lazy" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_LAZY"], 101 "let" => ["TokenType::KEYW_LET", "TokenType::KEYW_LET"], 102 }, 103 104 # keywords start with 'm' 105 { 106 "meta" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_META"], 107 "module" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_MODULE"], 108 "namespace" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NAMESPACE"], 109 }, 110 111 # keywords start with 'n' 112 { 113 "never" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NEVER"], 114 "new" => ["TokenType::KEYW_NEW", "TokenType::KEYW_NEW"], 115 "null" => ["TokenType::LITERAL_NULL", "TokenType::LITERAL_NULL"], 116 "number" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NUMBER"], 117 }, 118 119 # keywords start with 'o' 120 { 121 "object" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OBJECT"], 122 "of" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OF"], 123 "out" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OUT"], 124 "override" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OVERRIDE"], 125 }, 126 127 # keywords start with 'p' 128 { 129 "package" => ["TokenType::KEYW_PACKAGE", "TokenType::KEYW_PACKAGE"], 130 "private" => ["TokenType::KEYW_PRIVATE", "TokenType::KEYW_PRIVATE"], 131 "protected" => ["TokenType::KEYW_PROTECTED", "TokenType::KEYW_PROTECTED"], 132 "public" => ["TokenType::KEYW_PUBLIC", "TokenType::KEYW_PUBLIC"], 133 }, 134 135 # keywords start with 'r' 136 { 137 "readonly" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_READONLY"], 138 "return" => ["TokenType::KEYW_RETURN", "TokenType::KEYW_RETURN"], 139 "require" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_REQUIRE"], 140 }, 141 142 # keywords start with 's' 143 { 144 "satisfies" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SATISFIES"], 145 "set" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SET"], 146 "static" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STATIC"], 147 "string" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STRING"], 148 "super" => ["TokenType::KEYW_SUPER", "TokenType::KEYW_SUPER"], 149 "switch" => ["TokenType::KEYW_SWITCH", "TokenType::KEYW_SWITCH"], 150 "symbol" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SYMBOL"], 151 }, 152 153 # keywords start with 't' 154 { 155 "this" => ["TokenType::KEYW_THIS", "TokenType::KEYW_THIS"], 156 "throw" => ["TokenType::KEYW_THROW", "TokenType::KEYW_THROW"], 157 "true" => ["TokenType::LITERAL_TRUE", "TokenType::LITERAL_TRUE"], 158 "try" => ["TokenType::KEYW_TRY", "TokenType::KEYW_TRY"], 159 "type" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_TYPE"], 160 "typeof" => ["TokenType::KEYW_TYPEOF", "TokenType::KEYW_TYPEOF"], 161 }, 162 163 # keywords start with 'u' 164 { 165 "undefined" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNDEFINED"], 166 "unique" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNIQUE"], 167 "unknown" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNKNOWN"], 168 }, 169 170 # keywords start with 'v' 171 { 172 "var" => ["TokenType::KEYW_VAR", "TokenType::KEYW_VAR"], 173 "void" => ["TokenType::KEYW_VOID", "TokenType::KEYW_VOID"], 174 }, 175 176 # keywords start with 'w' 177 { 178 "while" => ["TokenType::KEYW_WHILE", "TokenType::KEYW_WHILE"], 179 "with" => ["TokenType::KEYW_WITH", "TokenType::KEYW_WITH"], 180 }, 181 182 # keywords start with 'y' 183 { 184 "yield" => ["TokenType::KEYW_YIELD", "TokenType::KEYW_YIELD"], 185 }, 186] 187 188def collect_functions(functions, keys) 189 offset = 0 190 191 while true 192 has_more = false 193 194 keys.each do |key| 195 if key.length < offset + 1 196 next 197 end 198 199 has_more = true 200 func_name = key[0..offset]; 201 202 if functions.has_key?(func_name) 203 functions[func_name].add(key[offset + 1]) 204 else 205 functions[func_name] = Set[key[offset + 1]] 206 end 207 end 208 209 if has_more 210 offset += 1 211 next 212 end 213 214 break 215 end 216end 217 218def generate(keywords, template_file, output_file) 219 functions = {} 220 keywords.each do |group| 221 collect_functions(functions, group.keys) 222 end 223 224 template = File.read(template_file) 225 t = ERB.new(template, nil, '%-') 226 t.filename = OpenStruct.new.template 227 res = t.result(binding) 228 229 File.open(output_file, "w") do |file| 230 file.write(res) 231 end 232end 233 234abort "Failed: input file required!" if ARGV.size < 2 235 236generate(keywords, ARGV[0], ARGV[1]) 237