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 }, 30 31 # keywords start with 'b' 32 { 33 "bigint" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_BIGINT"], 34 "boolean" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_BOOLEAN"], 35 "break" => ["TokenType::KEYW_BREAK", "TokenType::KEYW_BREAK"], 36 }, 37 38 # keywords start with 'c' 39 { 40 "case" => ["TokenType::KEYW_CASE", "TokenType::KEYW_CASE"], 41 "catch" => ["TokenType::KEYW_CATCH", "TokenType::KEYW_CATCH"], 42 "class" => ["TokenType::KEYW_CLASS", "TokenType::KEYW_CLASS"], 43 "const" => ["TokenType::KEYW_CONST", "TokenType::KEYW_CONST"], 44 "continue" => ["TokenType::KEYW_CONTINUE", "TokenType::KEYW_CONTINUE"] 45 }, 46 47 # keywords start with 'd' 48 { 49 "debugger" => ["TokenType::KEYW_DEBUGGER", "TokenType::KEYW_DEBUGGER"], 50 "declare" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_DECLARE"], 51 "default" => ["TokenType::KEYW_DEFAULT", "TokenType::KEYW_DEFAULT"], 52 "delete" => ["TokenType::KEYW_DELETE", "TokenType::KEYW_DELETE"], 53 "do" => ["TokenType::KEYW_DO", "TokenType::KEYW_DO"], 54 }, 55 56 # keywords start with 'e' 57 { 58 "else" => ["TokenType::KEYW_ELSE", "TokenType::KEYW_ELSE"], 59 "enum" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ENUM"], 60 "eval" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_EVAL"], 61 "export" => ["TokenType::KEYW_EXPORT", "TokenType::KEYW_EXPORT"], 62 "extends" => ["TokenType::KEYW_EXTENDS", "TokenType::KEYW_EXTENDS"], 63 }, 64 65 # keywords start with 'f' 66 { 67 "false" => ["TokenType::LITERAL_FALSE", "TokenType::LITERAL_FALSE"], 68 "finally" => ["TokenType::KEYW_FINALLY", "TokenType::KEYW_FINALLY"], 69 "for" => ["TokenType::KEYW_FOR", "TokenType::KEYW_FOR"], 70 "from" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_FROM"], 71 "function" => ["TokenType::KEYW_FUNCTION", "TokenType::KEYW_FUNCTION"], 72 }, 73 74 # keywords start with 'g' 75 { 76 "get" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_GET"], 77 "global" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_GLOBAL"], 78 }, 79 80 # keywords start with 'i' 81 { 82 "if" => ["TokenType::KEYW_IF", "TokenType::KEYW_IF"], 83 "implements" => ["TokenType::KEYW_IMPLEMENTS", "TokenType::KEYW_IMPLEMENTS"], 84 "import" => ["TokenType::KEYW_IMPORT", "TokenType::KEYW_IMPORT"], 85 "in" => ["TokenType::KEYW_IN", "TokenType::KEYW_IN"], 86 "infer" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_INFER"], 87 "instanceof" => ["TokenType::KEYW_INSTANCEOF", "TokenType::KEYW_INSTANCEOF"], 88 "interface" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_INTERFACE"], 89 "is" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_IS"], 90 }, 91 92 # keywords start with 'k' 93 { 94 "keyof" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_KEYOF"], 95 }, 96 97 # keywords start with 'l' 98 { 99 "let" => ["TokenType::KEYW_LET", "TokenType::KEYW_LET"], 100 }, 101 102 # keywords start with 'm' 103 { 104 "meta" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_META"], 105 "module" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_MODULE"], 106 "namespace" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NAMESPACE"], 107 }, 108 109 # keywords start with 'n' 110 { 111 "never" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NEVER"], 112 "new" => ["TokenType::KEYW_NEW", "TokenType::KEYW_NEW"], 113 "null" => ["TokenType::LITERAL_NULL", "TokenType::LITERAL_NULL"], 114 "number" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NUMBER"], 115 }, 116 117 # keywords start with 'o' 118 { 119 "object" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OBJECT"], 120 "of" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OF"], 121 }, 122 123 # keywords start with 'p' 124 { 125 "package" => ["TokenType::KEYW_PACKAGE", "TokenType::KEYW_PACKAGE"], 126 "private" => ["TokenType::KEYW_PRIVATE", "TokenType::KEYW_PRIVATE"], 127 "protected" => ["TokenType::KEYW_PROTECTED", "TokenType::KEYW_PROTECTED"], 128 "public" => ["TokenType::KEYW_PUBLIC", "TokenType::KEYW_PUBLIC"], 129 }, 130 131 # keywords start with 'r' 132 { 133 "readonly" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_READONLY"], 134 "return" => ["TokenType::KEYW_RETURN", "TokenType::KEYW_RETURN"], 135 "require" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_REQUIRE"], 136 }, 137 138 # keywords start with 's' 139 { 140 "set" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SET"], 141 "static" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STATIC"], 142 "string" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STRING"], 143 "super" => ["TokenType::KEYW_SUPER", "TokenType::KEYW_SUPER"], 144 "switch" => ["TokenType::KEYW_SWITCH", "TokenType::KEYW_SWITCH"], 145 "symbol" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SYMBOL"], 146 }, 147 148 # keywords start with 't' 149 { 150 "this" => ["TokenType::KEYW_THIS", "TokenType::KEYW_THIS"], 151 "throw" => ["TokenType::KEYW_THROW", "TokenType::KEYW_THROW"], 152 "true" => ["TokenType::LITERAL_TRUE", "TokenType::LITERAL_TRUE"], 153 "try" => ["TokenType::KEYW_TRY", "TokenType::KEYW_TRY"], 154 "type" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_TYPE"], 155 "typeof" => ["TokenType::KEYW_TYPEOF", "TokenType::KEYW_TYPEOF"], 156 }, 157 158 # keywords start with 'u' 159 { 160 "undefined" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNDEFINED"], 161 "unique" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNIQUE"], 162 "unknown" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNKNOWN"], 163 }, 164 165 # keywords start with 'v' 166 { 167 "var" => ["TokenType::KEYW_VAR", "TokenType::KEYW_VAR"], 168 "void" => ["TokenType::KEYW_VOID", "TokenType::KEYW_VOID"], 169 }, 170 171 # keywords start with 'w' 172 { 173 "while" => ["TokenType::KEYW_WHILE", "TokenType::KEYW_WHILE"], 174 "with" => ["TokenType::KEYW_WITH", "TokenType::KEYW_WITH"], 175 }, 176 177 # keywords start with 'y' 178 { 179 "yield" => ["TokenType::KEYW_YIELD", "TokenType::KEYW_YIELD"], 180 }, 181] 182 183def collect_functions(functions, keys) 184 offset = 0 185 186 while true 187 has_more = false 188 189 keys.each do |key| 190 if key.length < offset + 1 191 next 192 end 193 194 has_more = true 195 func_name = key[0..offset]; 196 197 if functions.has_key?(func_name) 198 functions[func_name].add(key[offset + 1]) 199 else 200 functions[func_name] = Set[key[offset + 1]] 201 end 202 end 203 204 if has_more 205 offset += 1 206 next 207 end 208 209 break 210 end 211end 212 213def generate(keywords, template_file, output_file) 214 functions = {} 215 keywords.each do |group| 216 collect_functions(functions, group.keys) 217 end 218 219 template = File.read(template_file) 220 t = ERB.new(template, nil, '%-') 221 t.filename = OpenStruct.new.template 222 res = t.result(binding) 223 224 File.open(output_file, "w") do |file| 225 file.write(res) 226 end 227end 228 229abort "Failed: input file required!" if ARGV.size < 2 230 231generate(keywords, ARGV[0], ARGV[1]) 232