#ifndef XTOKENIZER_KEYWORD_HPP #define XTOKENIZER_KEYWORD_HPP #include <string> #include <string_util.hpp> namespace xtokenizer { /** * キーワード。 */ enum class Keyword { K_UNKNOWN, //!< no keyword K_ABSTRACT, //!< abstract K_ALIAS, //!< alias K_ALIGN, //!< align K_ASM, //!< asm K_ASSERT, //!< assert K_AUTO, //!< auto K_BODY, //!< body K_BOOL, //!< bool K_BREAK, //!< break K_BYTE, //!< byte K_CASE, //!< case K_CAST, //!< cast K_CATCH, //!< catch K_CDOUBLE, //!< cdouble K_CENT, //!< cent K_CFLOAT, //!< cfloat K_CHAR, //!< char K_CLASS, //!< class K_CONST, //!< const K_CONTINUE, //!< continue K_CREAL, //!< creal K_DCHAR, //!< dchar K_DEBUG, //!< debug K_DEFAULT, //!< default K_DELEGATE, //!< delegate K_DELETE, //!< delete K_DEPRECATED, //!< deprecated K_DO, //!< do K_DOUBLE, //!< double K_ELSE, //!< else K_ENUM, //!< enum K_EXPORT, //!< export K_EXTERN, //!< extern K_FALSE, //!< false K_FINAL, //!< final K_FINALLY, //!< finally K_FLOAT, //!< float K_FOR, //!< for K_FOREACH, //!< foreach K_FUNCTION, //!< function K_FOREACH_REVERSE, //!< foreach_reverse K_GOTO, //!< goto K_IDOUBLE, //!< idouble K_IF, //!< if K_IFLOAT, //!< ifloat K_IMPORT, //!< import K_IN, //!< in K_INOUT, //!< inout K_INT, //!< int K_INTERFACE, //!< interface K_INVARIANT, //!< invariant K_IREAL, //!< ireal K_IS, //!< is K_LAZY, //!< lazy K_LONG, //!< long K_MACRO, //!< macro K_MIXIN, //!< mixin K_MODULE, //!< module K_NEW, //!< new K_NOTHROW, //!< nothrow K_NULL, //!< null K_NULLPTR, //!< nullptr K_OUT, //!< out K_OVERRIDE, //!< override K_PACKAGE, //!< package K_PRAGMA, //!< pragma K_PRIVATE, //!< private K_PROTECTED, //!< protected K_PUBLIC, //!< public K_PURE, //!< pure K_REAL, //!< real K_REF, //!< ref K_RETURN, //!< return K_SCOPE, //!< scope K_SHARED, //!< shared K_SHORT, //!< short K_STATIC, //!< static K_STRUCT, //!< struct K_SUPER, //!< super K_SWITCH, //!< switch K_SYNCHRONIZED, //!< synchronized K_TEMPLATE, //!< template K_THIS, //!< this K_THROW, //!< throw K_TRUE, //!< true K_TRY, //!< try K_TYPEDEF, //!< typedef K_TYPEID, //!< typeid K_TYPEOF, //!< typeof K_UBYTE, //!< ubyte K_UCENT, //!< ucent K_UINT, //!< uint K_ULONG, //!< ulong K_UNION, //!< union K_UNITTEST, //!< unittest K_USHORT, //!< ushort K_VERSION, //!< version K_VOID, //!< void K_VOLATILE, //!< volatile K_WCHAR, //!< wchar K_WHILE, //!< while K_WITH, //!< with K___FILE__, //!< __FILE__ K___FUNC__, //!< __FUNC__ K___LINE__, //!< __LINE__ K___GSHARED, //!< __gshared K___THREAD, //!< __thread K___TRAITS //!< __traits }; /** * キーワード情報 */ struct KeywordInfo { const Keyword keyword; const char *str; int len; const KeywordInfo *next; // constexpr コンストラクタ constexpr KeywordInfo(const Keyword k, const char *s, const KeywordInfo *n = nullptr) : keyword(k), str(s), len(constexpr_strlen(s)), next(n) {} }; namespace { // 最長一致検索するため、next のリンクは長い物から順にすること。 constexpr KeywordInfo knop = {Keyword::K_UNKNOWN, ""}; // a constexpr KeywordInfo a0 = {Keyword::K_ABSTRACT, "abstract"}; constexpr KeywordInfo a1 = {Keyword::K_ALIAS, "alias", &a0}; constexpr KeywordInfo a2 = {Keyword::K_ALIGN, "align", &a1}; constexpr KeywordInfo a3 = {Keyword::K_ASM, "asm", &a2}; constexpr KeywordInfo a4 = {Keyword::K_ASSERT, "assert", &a3}; constexpr KeywordInfo a5 = {Keyword::K_AUTO, "auto", &a4}; // b constexpr KeywordInfo b0 = {Keyword::K_BODY, "body"}; constexpr KeywordInfo b1 = {Keyword::K_BOOL, "bool", &b0}; constexpr KeywordInfo b2 = {Keyword::K_BREAK, "break", &b1}; constexpr KeywordInfo b3 = {Keyword::K_BYTE, "byte", &b2}; // c constexpr KeywordInfo c0 = {Keyword::K_CASE, "case"}; constexpr KeywordInfo c1 = {Keyword::K_CAST, "cast", &c0}; constexpr KeywordInfo c2 = {Keyword::K_CATCH, "catch", &c1}; constexpr KeywordInfo c3 = {Keyword::K_CDOUBLE, "cdouble", &c2}; constexpr KeywordInfo c4 = {Keyword::K_CENT, "cent", &c3}; constexpr KeywordInfo c5 = {Keyword::K_CFLOAT, "cfloat", &c4}; constexpr KeywordInfo c6 = {Keyword::K_CHAR, "char", &c5}; constexpr KeywordInfo c7 = {Keyword::K_CLASS, "class", &c6}; constexpr KeywordInfo c8 = {Keyword::K_CONST, "const", &c7}; constexpr KeywordInfo c9 = {Keyword::K_CONTINUE, "continue", &c8}; constexpr KeywordInfo c10 = {Keyword::K_CREAL, "creal", &c9}; // d constexpr KeywordInfo d0 = {Keyword::K_DCHAR, "dchar"}; constexpr KeywordInfo d1 = {Keyword::K_DEBUG, "debug", &d0}; constexpr KeywordInfo d2 = {Keyword::K_DEFAULT, "default", &d1}; constexpr KeywordInfo d3 = {Keyword::K_DELEGATE, "delegate", &d2}; constexpr KeywordInfo d4 = {Keyword::K_DELETE, "delete", &d3}; constexpr KeywordInfo d5 = {Keyword::K_DEPRECATED, "deprecated", &d4}; constexpr KeywordInfo d6 = {Keyword::K_DO, "do", &d5}; constexpr KeywordInfo d7 = {Keyword::K_DOUBLE, "double", &d6}; // e constexpr KeywordInfo e0 = {Keyword::K_ELSE, "else"}; constexpr KeywordInfo e1 = {Keyword::K_ENUM, "enum", &e0}; constexpr KeywordInfo e2 = {Keyword::K_EXPORT, "export", &e1}; constexpr KeywordInfo e3 = {Keyword::K_EXTERN, "extern", &e2}; // f constexpr KeywordInfo f0 = {Keyword::K_FALSE, "false"}; constexpr KeywordInfo f1 = {Keyword::K_FINAL, "final", &f0}; constexpr KeywordInfo f2 = {Keyword::K_FINALLY, "finally", &f1}; constexpr KeywordInfo f3 = {Keyword::K_FLOAT, "float", &f2}; constexpr KeywordInfo f4 = {Keyword::K_FOR, "for", &f3}; constexpr KeywordInfo f5 = {Keyword::K_FOREACH, "foreach", &f4}; constexpr KeywordInfo f6 = {Keyword::K_FUNCTION, "function", &f5}; constexpr KeywordInfo f7 = {Keyword::K_FOREACH_REVERSE, "foreach_reverse", &f6}; // g constexpr KeywordInfo g0 = {Keyword::K_GOTO, "goto"}; // i constexpr KeywordInfo i0 = {Keyword::K_IDOUBLE, "idouble"}; constexpr KeywordInfo i1 = {Keyword::K_IF, "if", &i0}; constexpr KeywordInfo i2 = {Keyword::K_IFLOAT, "ifloat", &i1}; constexpr KeywordInfo i3 = {Keyword::K_IMPORT, "import", &i2}; constexpr KeywordInfo i4 = {Keyword::K_IN, "in", &i3}; constexpr KeywordInfo i5 = {Keyword::K_INOUT, "inout", &i4}; constexpr KeywordInfo i6 = {Keyword::K_INT, "int", &i5}; constexpr KeywordInfo i7 = {Keyword::K_INTERFACE, "interface", &i6}; constexpr KeywordInfo i8 = {Keyword::K_INVARIANT, "invariant", &i7}; constexpr KeywordInfo i9 = {Keyword::K_IREAL, "ireal", &i8}; constexpr KeywordInfo i10 = {Keyword::K_IS, "is", &i9}; // l constexpr KeywordInfo l0 = {Keyword::K_LAZY, "lazy"}; constexpr KeywordInfo l1 = {Keyword::K_LONG, "long", &l0}; // m constexpr KeywordInfo m0 = {Keyword::K_MACRO, "macro"}; constexpr KeywordInfo m1 = {Keyword::K_MIXIN, "mixin", &m0}; constexpr KeywordInfo m2 = {Keyword::K_MODULE, "module", &m1}; // n constexpr KeywordInfo n0 = {Keyword::K_NEW, "new"}; constexpr KeywordInfo n1 = {Keyword::K_NOTHROW, "nothrow", &n0}; constexpr KeywordInfo n2 = {Keyword::K_NULL, "null", &n1}; constexpr KeywordInfo n3 = {Keyword::K_NULLPTR, "nullptr", &n2}; // n constexpr KeywordInfo o0 = {Keyword::K_OUT, "out"}; constexpr KeywordInfo o1 = {Keyword::K_OVERRIDE, "override", &o0}; // p constexpr KeywordInfo p0 = {Keyword::K_PACKAGE, "package"}; constexpr KeywordInfo p1 = {Keyword::K_PRAGMA, "pragma", &p0}; constexpr KeywordInfo p2 = {Keyword::K_PRIVATE, "private", &p1}; constexpr KeywordInfo p3 = {Keyword::K_PROTECTED, "protected", &p2}; constexpr KeywordInfo p4 = {Keyword::K_PUBLIC, "public", &p3}; constexpr KeywordInfo p5 = {Keyword::K_PURE, "pure", &p4}; // r constexpr KeywordInfo r0 = {Keyword::K_REAL, "real"}; constexpr KeywordInfo r1 = {Keyword::K_REF, "ref", &r0}; constexpr KeywordInfo r2 = {Keyword::K_RETURN, "return", &r1}; // s constexpr KeywordInfo s0 = {Keyword::K_SCOPE, "scope"}; constexpr KeywordInfo s1 = {Keyword::K_SHARED, "shared", &s0}; constexpr KeywordInfo s2 = {Keyword::K_SHORT, "short", &s1}; constexpr KeywordInfo s3 = {Keyword::K_STATIC, "static", &s2}; constexpr KeywordInfo s4 = {Keyword::K_STRUCT, "struct", &s3}; constexpr KeywordInfo s5 = {Keyword::K_SUPER, "super", &s4}; constexpr KeywordInfo s6 = {Keyword::K_SWITCH, "switch", &s5}; constexpr KeywordInfo s7 = {Keyword::K_SYNCHRONIZED, "synchronized", &s6}; // t constexpr KeywordInfo t0 = {Keyword::K_TEMPLATE, "template"}; constexpr KeywordInfo t1 = {Keyword::K_THIS, "this", &t0}; constexpr KeywordInfo t2 = {Keyword::K_THROW, "throw", &t1}; constexpr KeywordInfo t3 = {Keyword::K_TRUE, "true", &t2}; constexpr KeywordInfo t4 = {Keyword::K_TRY, "try", &t3}; constexpr KeywordInfo t5 = {Keyword::K_TYPEDEF, "typedef", &t4}; constexpr KeywordInfo t6 = {Keyword::K_TYPEID, "typeid", &t5}; constexpr KeywordInfo t7 = {Keyword::K_TYPEOF, "typeof", &t6}; // u constexpr KeywordInfo u0 = {Keyword::K_UBYTE, "ubyte"}; constexpr KeywordInfo u1 = {Keyword::K_UCENT, "ucent", &u0}; constexpr KeywordInfo u2 = {Keyword::K_UINT, "uint", &u1}; constexpr KeywordInfo u3 = {Keyword::K_ULONG, "ulong", &u2}; constexpr KeywordInfo u4 = {Keyword::K_UNION, "union", &u3}; constexpr KeywordInfo u5 = {Keyword::K_UNITTEST, "unittest", &u4}; constexpr KeywordInfo u6 = {Keyword::K_USHORT, "ushort", &u5}; // u constexpr KeywordInfo v0 = {Keyword::K_VERSION, "version"}; constexpr KeywordInfo v1 = {Keyword::K_VOID, "void", &v0}; constexpr KeywordInfo v2 = {Keyword::K_VOLATILE, "volatile", &v1}; // w constexpr KeywordInfo w0 = {Keyword::K_WCHAR, "wchar"}; constexpr KeywordInfo w1 = {Keyword::K_WHILE, "while", &w0}; constexpr KeywordInfo w2 = {Keyword::K_WITH, "with", &w1}; // _ constexpr KeywordInfo _0 = {Keyword::K___FILE__, "__FILE__"}; constexpr KeywordInfo _1 = {Keyword::K___FUNC__, "__FUNC__", &_0}; constexpr KeywordInfo _2 = {Keyword::K___LINE__, "__LINE__", &_1}; constexpr KeywordInfo _3 = {Keyword::K___GSHARED, "__gshared", &_2}; constexpr KeywordInfo _4 = {Keyword::K___THREAD, "__thread", &_3}; constexpr KeywordInfo _5 = {Keyword::K___TRAITS, "__traits", &_4}; constexpr KeywordInfo keywordInfoTable[] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, // 制御コード knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, knop, // 制御コード knop, // 0x20: SPA (空白文字) knop, // 0x21: ! knop, // 0x22: " knop, // 0x23: # knop, // 0x24: $ knop, // 0x25: % knop, // 0x26: & knop, // 0x27: ' knop, // 0x28: ( knop, // 0x29: ) knop, // 0x2A: * knop, // 0x2B: + knop, // 0x2C: , knop, // 0x2D: - knop, // 0x2E: . knop, // 0x2F: / knop, // 0x30: 0 knop, // 0x31: 1 knop, // 0x32: 2 knop, // 0x33: 3 knop, // 0x34: 4 knop, // 0x35: 5 knop, // 0x36: 6 knop, // 0x37: 7 knop, // 0x38: 8 knop, // 0x39: 9 knop, // 0x3A: : knop, // 0x3B: ; knop, // 0x3C: < knop, // 0x3D: = knop, // 0x3E: > knop, // 0x3F: ? knop, // 0x40: @ knop, // 0x41: A knop, // 0x42: B knop, // 0x43: C knop, // 0x44: D knop, // 0x45: E knop, // 0x46: F knop, // 0x47: G knop, // 0x48: H knop, // 0x49: I knop, // 0x4A: J knop, // 0x4B: K knop, // 0x4C: L knop, // 0x4D: M knop, // 0x4E: N knop, // 0x4F: O knop, // 0x50: P knop, // 0x51: Q knop, // 0x52: R knop, // 0x53: S knop, // 0x54: T knop, // 0x55: U knop, // 0x56: V knop, // 0x57: W knop, // 0x58: X knop, // 0x59: Y knop, // 0x5A: Z knop, // 0x5B: [ knop, // 0x5C: '\' knop, // 0x5D: ] knop, // 0x5E: ^ _5, // 0x5F: _ knop, // 0x60: ` a5, // 0x61: a b3, // 0x62: b c10, // 0x63: c d7, // 0x64: d e3, // 0x65: e f7, // 0x66: f g0, // 0x67: g knop, // 0x68: h i10, // 0x69: i knop, // 0x6A: j knop, // 0x6B: k l1, // 0x6C: l m2, // 0x6D: m n3, // 0x6E: n o1, // 0x6F: o p5, // 0x70: p knop, // 0x71: q r2, // 0x72: r s7, // 0x73: s t7, // 0x74: t u6, // 0x75: u v2, // 0x76: v w2, // 0x77: w knop, // 0x78: x knop, // 0x79: y knop, // 0x7A: z knop, // 0x7B: { knop, // 0x7C: | knop, // 0x7D: } knop, // 0x7E: } knop, // 0x7F: DEL(削除) }; } /** * 指定されたトークンがキーワードである場合、対象のキーワード情報を返します。 * * @param token トークン文字列 * @return キーワード情報 */ inline const KeywordInfo getKeywordInfo(const std::string &token) { const KeywordInfo *info = &keywordInfoTable[static_cast<uint8_t>(token[0])]; if (info == &knop) { // キーワードでない return knop; } while (info != nullptr) { if (token == info->str) { return *info; } info = info->next; } return knop; } } // namespcae xtokenizer #endif // XTOKENIZER_KEYWORD_HPP