13af6ab5fSopenharmony_ci#!/usr/bin/env ruby
23af6ab5fSopenharmony_ci# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci# You may obtain a copy of the License at
63af6ab5fSopenharmony_ci#
73af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci#
93af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci# limitations under the License.
143af6ab5fSopenharmony_ci
153af6ab5fSopenharmony_cirequire 'erb'
163af6ab5fSopenharmony_cirequire 'ostruct'
173af6ab5fSopenharmony_cirequire 'set'
183af6ab5fSopenharmony_ci
193af6ab5fSopenharmony_cikeywords = [
203af6ab5fSopenharmony_ci    # keywords start with 'a'
213af6ab5fSopenharmony_ci    {
223af6ab5fSopenharmony_ci        "abstract" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ABSTRACT"],
233af6ab5fSopenharmony_ci        "any" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ANY"],
243af6ab5fSopenharmony_ci        "arguments" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ARGUMENTS"],
253af6ab5fSopenharmony_ci        "as" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_AS"],
263af6ab5fSopenharmony_ci        "asserts" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ASSERTS"],
273af6ab5fSopenharmony_ci        "async" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ASYNC"],
283af6ab5fSopenharmony_ci        "await" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_AWAIT"],
293af6ab5fSopenharmony_ci        "accessor" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ACCESSOR"],
303af6ab5fSopenharmony_ci    },
313af6ab5fSopenharmony_ci
323af6ab5fSopenharmony_ci    # keywords start with 'b'
333af6ab5fSopenharmony_ci    {
343af6ab5fSopenharmony_ci        "bigint" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_BIGINT"],
353af6ab5fSopenharmony_ci        "boolean" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_BOOLEAN"],
363af6ab5fSopenharmony_ci        "break" => ["TokenType::KEYW_BREAK", "TokenType::KEYW_BREAK"],
373af6ab5fSopenharmony_ci    },
383af6ab5fSopenharmony_ci
393af6ab5fSopenharmony_ci    # keywords start with 'c'
403af6ab5fSopenharmony_ci    {
413af6ab5fSopenharmony_ci        "case" => ["TokenType::KEYW_CASE", "TokenType::KEYW_CASE"],
423af6ab5fSopenharmony_ci        "catch" => ["TokenType::KEYW_CATCH", "TokenType::KEYW_CATCH"],
433af6ab5fSopenharmony_ci        "class" => ["TokenType::KEYW_CLASS", "TokenType::KEYW_CLASS"],
443af6ab5fSopenharmony_ci        "const" => ["TokenType::KEYW_CONST", "TokenType::KEYW_CONST"],
453af6ab5fSopenharmony_ci        "continue" => ["TokenType::KEYW_CONTINUE", "TokenType::KEYW_CONTINUE"]
463af6ab5fSopenharmony_ci    },
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_ci    # keywords start with 'd'
493af6ab5fSopenharmony_ci    {
503af6ab5fSopenharmony_ci        "debugger" => ["TokenType::KEYW_DEBUGGER", "TokenType::KEYW_DEBUGGER"],
513af6ab5fSopenharmony_ci        "declare" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_DECLARE"],
523af6ab5fSopenharmony_ci        "default" => ["TokenType::KEYW_DEFAULT", "TokenType::KEYW_DEFAULT"],
533af6ab5fSopenharmony_ci        "delete" => ["TokenType::KEYW_DELETE", "TokenType::KEYW_DELETE"],
543af6ab5fSopenharmony_ci        "do" => ["TokenType::KEYW_DO", "TokenType::KEYW_DO"],
553af6ab5fSopenharmony_ci    },
563af6ab5fSopenharmony_ci
573af6ab5fSopenharmony_ci    # keywords start with 'e'
583af6ab5fSopenharmony_ci    {
593af6ab5fSopenharmony_ci        "else" => ["TokenType::KEYW_ELSE", "TokenType::KEYW_ELSE"],
603af6ab5fSopenharmony_ci        "enum" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_ENUM"],
613af6ab5fSopenharmony_ci        "eval" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_EVAL"],
623af6ab5fSopenharmony_ci        "export" => ["TokenType::KEYW_EXPORT", "TokenType::KEYW_EXPORT"],
633af6ab5fSopenharmony_ci        "extends" => ["TokenType::KEYW_EXTENDS", "TokenType::KEYW_EXTENDS"],
643af6ab5fSopenharmony_ci    },
653af6ab5fSopenharmony_ci
663af6ab5fSopenharmony_ci    # keywords start with 'f'
673af6ab5fSopenharmony_ci    {
683af6ab5fSopenharmony_ci        "false" => ["TokenType::LITERAL_FALSE", "TokenType::LITERAL_FALSE"],
693af6ab5fSopenharmony_ci        "finally" => ["TokenType::KEYW_FINALLY", "TokenType::KEYW_FINALLY"],
703af6ab5fSopenharmony_ci        "for" => ["TokenType::KEYW_FOR", "TokenType::KEYW_FOR"],
713af6ab5fSopenharmony_ci        "from" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_FROM"],
723af6ab5fSopenharmony_ci        "function" => ["TokenType::KEYW_FUNCTION", "TokenType::KEYW_FUNCTION"],
733af6ab5fSopenharmony_ci    },
743af6ab5fSopenharmony_ci
753af6ab5fSopenharmony_ci    # keywords start with 'g'
763af6ab5fSopenharmony_ci    {
773af6ab5fSopenharmony_ci        "get" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_GET"],
783af6ab5fSopenharmony_ci        "global" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_GLOBAL"],
793af6ab5fSopenharmony_ci    },
803af6ab5fSopenharmony_ci
813af6ab5fSopenharmony_ci    # keywords start with 'i'
823af6ab5fSopenharmony_ci    {
833af6ab5fSopenharmony_ci        "if" => ["TokenType::KEYW_IF", "TokenType::KEYW_IF"],
843af6ab5fSopenharmony_ci        "implements" => ["TokenType::KEYW_IMPLEMENTS", "TokenType::KEYW_IMPLEMENTS"],
853af6ab5fSopenharmony_ci        "import" => ["TokenType::KEYW_IMPORT", "TokenType::KEYW_IMPORT"],
863af6ab5fSopenharmony_ci        "in" => ["TokenType::KEYW_IN", "TokenType::KEYW_IN"],
873af6ab5fSopenharmony_ci        "infer" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_INFER"],
883af6ab5fSopenharmony_ci        "instanceof" => ["TokenType::KEYW_INSTANCEOF", "TokenType::KEYW_INSTANCEOF"],
893af6ab5fSopenharmony_ci        "interface" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_INTERFACE"],
903af6ab5fSopenharmony_ci        "is" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_IS"],
913af6ab5fSopenharmony_ci    },
923af6ab5fSopenharmony_ci
933af6ab5fSopenharmony_ci    # keywords start with 'k'
943af6ab5fSopenharmony_ci    {
953af6ab5fSopenharmony_ci        "keyof" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_KEYOF"],
963af6ab5fSopenharmony_ci    },
973af6ab5fSopenharmony_ci
983af6ab5fSopenharmony_ci    # keywords start with 'l'
993af6ab5fSopenharmony_ci    {
1003af6ab5fSopenharmony_ci        "lazy" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_LAZY"],
1013af6ab5fSopenharmony_ci        "let" => ["TokenType::KEYW_LET", "TokenType::KEYW_LET"],
1023af6ab5fSopenharmony_ci    },
1033af6ab5fSopenharmony_ci
1043af6ab5fSopenharmony_ci    # keywords start with 'm'
1053af6ab5fSopenharmony_ci    {
1063af6ab5fSopenharmony_ci        "meta" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_META"],
1073af6ab5fSopenharmony_ci        "module" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_MODULE"],
1083af6ab5fSopenharmony_ci        "namespace" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NAMESPACE"],
1093af6ab5fSopenharmony_ci    },
1103af6ab5fSopenharmony_ci
1113af6ab5fSopenharmony_ci    # keywords start with 'n'
1123af6ab5fSopenharmony_ci    {
1133af6ab5fSopenharmony_ci        "never" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NEVER"],
1143af6ab5fSopenharmony_ci        "new" => ["TokenType::KEYW_NEW", "TokenType::KEYW_NEW"],
1153af6ab5fSopenharmony_ci        "null" => ["TokenType::LITERAL_NULL", "TokenType::LITERAL_NULL"],
1163af6ab5fSopenharmony_ci        "number" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_NUMBER"],
1173af6ab5fSopenharmony_ci    },
1183af6ab5fSopenharmony_ci
1193af6ab5fSopenharmony_ci    # keywords start with 'o'
1203af6ab5fSopenharmony_ci    {
1213af6ab5fSopenharmony_ci        "object" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OBJECT"],
1223af6ab5fSopenharmony_ci        "of" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OF"],
1233af6ab5fSopenharmony_ci        "out" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OUT"],
1243af6ab5fSopenharmony_ci        "override" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_OVERRIDE"],
1253af6ab5fSopenharmony_ci    },
1263af6ab5fSopenharmony_ci
1273af6ab5fSopenharmony_ci    # keywords start with 'p'
1283af6ab5fSopenharmony_ci    {
1293af6ab5fSopenharmony_ci        "package" => ["TokenType::KEYW_PACKAGE", "TokenType::KEYW_PACKAGE"],
1303af6ab5fSopenharmony_ci        "private" => ["TokenType::KEYW_PRIVATE", "TokenType::KEYW_PRIVATE"],
1313af6ab5fSopenharmony_ci        "protected" => ["TokenType::KEYW_PROTECTED", "TokenType::KEYW_PROTECTED"],
1323af6ab5fSopenharmony_ci        "public" => ["TokenType::KEYW_PUBLIC", "TokenType::KEYW_PUBLIC"],
1333af6ab5fSopenharmony_ci    },
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_ci    # keywords start with 'r'
1363af6ab5fSopenharmony_ci    {
1373af6ab5fSopenharmony_ci        "readonly" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_READONLY"],
1383af6ab5fSopenharmony_ci        "return" => ["TokenType::KEYW_RETURN", "TokenType::KEYW_RETURN"],
1393af6ab5fSopenharmony_ci        "require" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_REQUIRE"],
1403af6ab5fSopenharmony_ci    },
1413af6ab5fSopenharmony_ci
1423af6ab5fSopenharmony_ci    # keywords start with 's'
1433af6ab5fSopenharmony_ci    {
1443af6ab5fSopenharmony_ci        "satisfies" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SATISFIES"],
1453af6ab5fSopenharmony_ci        "set" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SET"],
1463af6ab5fSopenharmony_ci        "static" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STATIC"],
1473af6ab5fSopenharmony_ci        "string" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_STRING"],
1483af6ab5fSopenharmony_ci        "super" => ["TokenType::KEYW_SUPER", "TokenType::KEYW_SUPER"],
1493af6ab5fSopenharmony_ci        "switch" => ["TokenType::KEYW_SWITCH", "TokenType::KEYW_SWITCH"],
1503af6ab5fSopenharmony_ci        "symbol" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_SYMBOL"],
1513af6ab5fSopenharmony_ci    },
1523af6ab5fSopenharmony_ci
1533af6ab5fSopenharmony_ci    # keywords start with 't'
1543af6ab5fSopenharmony_ci    {
1553af6ab5fSopenharmony_ci        "this" => ["TokenType::KEYW_THIS", "TokenType::KEYW_THIS"],
1563af6ab5fSopenharmony_ci        "throw" => ["TokenType::KEYW_THROW", "TokenType::KEYW_THROW"],
1573af6ab5fSopenharmony_ci        "true" => ["TokenType::LITERAL_TRUE", "TokenType::LITERAL_TRUE"],
1583af6ab5fSopenharmony_ci        "try" => ["TokenType::KEYW_TRY", "TokenType::KEYW_TRY"],
1593af6ab5fSopenharmony_ci        "type" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_TYPE"],
1603af6ab5fSopenharmony_ci        "typeof" => ["TokenType::KEYW_TYPEOF", "TokenType::KEYW_TYPEOF"],
1613af6ab5fSopenharmony_ci    },
1623af6ab5fSopenharmony_ci
1633af6ab5fSopenharmony_ci    # keywords start with 'u'
1643af6ab5fSopenharmony_ci    {
1653af6ab5fSopenharmony_ci        "undefined" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNDEFINED"],
1663af6ab5fSopenharmony_ci        "unique" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNIQUE"],
1673af6ab5fSopenharmony_ci        "unknown" => ["TokenType::LITERAL_IDENT", "TokenType::KEYW_UNKNOWN"],
1683af6ab5fSopenharmony_ci    },
1693af6ab5fSopenharmony_ci
1703af6ab5fSopenharmony_ci    # keywords start with 'v'
1713af6ab5fSopenharmony_ci    {
1723af6ab5fSopenharmony_ci        "var" => ["TokenType::KEYW_VAR", "TokenType::KEYW_VAR"],
1733af6ab5fSopenharmony_ci        "void" => ["TokenType::KEYW_VOID", "TokenType::KEYW_VOID"],
1743af6ab5fSopenharmony_ci    },
1753af6ab5fSopenharmony_ci
1763af6ab5fSopenharmony_ci    # keywords start with 'w'
1773af6ab5fSopenharmony_ci    {
1783af6ab5fSopenharmony_ci        "while" => ["TokenType::KEYW_WHILE", "TokenType::KEYW_WHILE"],
1793af6ab5fSopenharmony_ci        "with" => ["TokenType::KEYW_WITH", "TokenType::KEYW_WITH"],
1803af6ab5fSopenharmony_ci    },
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ci    # keywords start with 'y'
1833af6ab5fSopenharmony_ci    {
1843af6ab5fSopenharmony_ci        "yield" => ["TokenType::KEYW_YIELD", "TokenType::KEYW_YIELD"],
1853af6ab5fSopenharmony_ci    },
1863af6ab5fSopenharmony_ci]
1873af6ab5fSopenharmony_ci
1883af6ab5fSopenharmony_cidef collect_functions(functions, keys)
1893af6ab5fSopenharmony_ci    offset = 0
1903af6ab5fSopenharmony_ci
1913af6ab5fSopenharmony_ci    while true
1923af6ab5fSopenharmony_ci        has_more = false
1933af6ab5fSopenharmony_ci
1943af6ab5fSopenharmony_ci        keys.each do |key|
1953af6ab5fSopenharmony_ci            if key.length < offset + 1
1963af6ab5fSopenharmony_ci                next
1973af6ab5fSopenharmony_ci            end
1983af6ab5fSopenharmony_ci
1993af6ab5fSopenharmony_ci            has_more = true
2003af6ab5fSopenharmony_ci            func_name = key[0..offset];
2013af6ab5fSopenharmony_ci
2023af6ab5fSopenharmony_ci            if functions.has_key?(func_name)
2033af6ab5fSopenharmony_ci                functions[func_name].add(key[offset + 1])
2043af6ab5fSopenharmony_ci            else
2053af6ab5fSopenharmony_ci                functions[func_name] = Set[key[offset + 1]]
2063af6ab5fSopenharmony_ci            end
2073af6ab5fSopenharmony_ci        end
2083af6ab5fSopenharmony_ci
2093af6ab5fSopenharmony_ci        if has_more
2103af6ab5fSopenharmony_ci            offset += 1
2113af6ab5fSopenharmony_ci            next
2123af6ab5fSopenharmony_ci        end
2133af6ab5fSopenharmony_ci
2143af6ab5fSopenharmony_ci        break
2153af6ab5fSopenharmony_ci    end
2163af6ab5fSopenharmony_ciend
2173af6ab5fSopenharmony_ci
2183af6ab5fSopenharmony_cidef generate(keywords, template_file, output_file)   
2193af6ab5fSopenharmony_ci    functions = {}
2203af6ab5fSopenharmony_ci    keywords.each do |group|
2213af6ab5fSopenharmony_ci        collect_functions(functions, group.keys)
2223af6ab5fSopenharmony_ci    end
2233af6ab5fSopenharmony_ci
2243af6ab5fSopenharmony_ci    template = File.read(template_file)
2253af6ab5fSopenharmony_ci    t = ERB.new(template, nil, '%-')
2263af6ab5fSopenharmony_ci    t.filename = OpenStruct.new.template
2273af6ab5fSopenharmony_ci    res = t.result(binding)
2283af6ab5fSopenharmony_ci
2293af6ab5fSopenharmony_ci    File.open(output_file, "w") do |file|
2303af6ab5fSopenharmony_ci        file.write(res)
2313af6ab5fSopenharmony_ci    end
2323af6ab5fSopenharmony_ciend
2333af6ab5fSopenharmony_ci
2343af6ab5fSopenharmony_ciabort "Failed: input file required!" if ARGV.size < 2
2353af6ab5fSopenharmony_ci
2363af6ab5fSopenharmony_cigenerate(keywords, ARGV[0], ARGV[1])
237