diff --git a/cparser/cparser.vcxproj b/cparser/cparser.vcxproj index ea5442f..e542818 100644 --- a/cparser/cparser.vcxproj +++ b/cparser/cparser.vcxproj @@ -20,6 +20,7 @@ + diff --git a/cparser/cparser.vcxproj.filters b/cparser/cparser.vcxproj.filters index fdc0505..b220af6 100644 --- a/cparser/cparser.vcxproj.filters +++ b/cparser/cparser.vcxproj.filters @@ -44,5 +44,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/cparser/main.cpp b/cparser/main.cpp index a8c6ed2..102da58 100644 --- a/cparser/main.cpp +++ b/cparser/main.cpp @@ -10,13 +10,17 @@ #include "stringutils.h" #include "testfiles.h" +#define MAKE_OP_TRIPLE(ch1, ch2, ch3) (ch3 << 16 | ch2 << 8 | ch1) +#define MAKE_OP_DOUBLE(ch1, ch2) (ch2 << 8 | ch1) +#define MAKE_OP_SINGLE(ch1) (ch1) + using namespace std; struct Lexer { explicit Lexer() { - SetupKeywordMap(); + SetupTokenMaps(); } enum Token @@ -33,7 +37,16 @@ struct Lexer //others tok_identifier, //[a-zA-Z_][a-zA-Z0-9_] tok_number, //(0x[0-9a-fA-F]+)|([0-9]+) - tok_stringlit //"([^\\"\r\n]|\\[\\"abfnrtv])*" + tok_stringlit, //"([^\\"\r\n]|\\[\\"abfnrtv])*" + + //operators +#define DEF_OP_TRIPLE(enumval, ch1, ch2, ch3) enumval, +#define DEF_OP_DOUBLE(enumval, ch1, ch2) enumval, +#define DEF_OP_SINGLE(enumval, ch1) enumval, +#include "operators.h" +#undef DEF_OP_TRIPLE +#undef DEF_OP_DOUBLE +#undef DEF_OP_SINGLE }; vector Input; @@ -62,16 +75,39 @@ struct Lexer } unordered_map KeywordMap; - unordered_map ReverseKeywordMap; + unordered_map ReverseTokenMap; + unordered_map OpTripleMap; + unordered_map OpDoubleMap; + unordered_map OpSingleMap; - void SetupKeywordMap() + void SetupTokenMaps() { + //setup keyword map #define DEF_KEYWORD(keyword) KeywordMap[#keyword] = tok_##keyword; #include "keywords.h" #undef DEF_KEYWORD -#define DEF_KEYWORD(keyword) ReverseKeywordMap[tok_##keyword] = "tok_" #keyword; + + //setup token maps +#define DEF_OP_TRIPLE(enumval, ch1, ch2, ch3) OpTripleMap[MAKE_OP_TRIPLE(ch1, ch2, ch3)] = enumval; +#define DEF_OP_DOUBLE(enumval, ch1, ch2) OpDoubleMap[MAKE_OP_DOUBLE(ch1, ch2)] = enumval; +#define DEF_OP_SINGLE(enumval, ch1) OpSingleMap[MAKE_OP_SINGLE(ch1)] = enumval; +#include "operators.h" +#undef DEF_OP_TRIPLE +#undef DEF_OP_DOUBLE +#undef DEF_OP_SINGLE + + //setup reverse token maps +#define DEF_KEYWORD(keyword) ReverseTokenMap[tok_##keyword] = "tok_" #keyword; #include "keywords.h" #undef DEF_KEYWORD + +#define DEF_OP_TRIPLE(enumval, ch1, ch2, ch3) ReverseTokenMap[enumval] = #enumval; +#define DEF_OP_DOUBLE(enumval, ch1, ch2) ReverseTokenMap[enumval] = #enumval; +#define DEF_OP_SINGLE(enumval, ch1) ReverseTokenMap[enumval] = #enumval; +#include "operators.h" +#undef DEF_OP_TRIPLE +#undef DEF_OP_DOUBLE +#undef DEF_OP_SINGLE } Token ReportError(const String & error) @@ -96,8 +132,8 @@ struct Lexer case tok_stringlit: return StringUtils::sprintf("tok_stringlit \"%s\"", StringUtils::Escape(StringLit).c_str()); default: { - auto found = ReverseKeywordMap.find(Token(tok)); - if (found != ReverseKeywordMap.end()) + auto found = ReverseTokenMap.find(Token(tok)); + if (found != ReverseTokenMap.end()) return found->second; if (tok > 0 && tok < 265) { diff --git a/cparser/operators.h b/cparser/operators.h new file mode 100644 index 0000000..931ad0f --- /dev/null +++ b/cparser/operators.h @@ -0,0 +1,63 @@ +#ifndef DEF_OP_TRIPLE +#define DEF_OP_TRIPLE(enumval, ch1, ch2, ch3) +#endif //DEF_OP_TRIPLE +#ifndef DEF_OP_DOUBLE +#define DEF_OP_DOUBLE(enumval, ch1, ch2) +#endif //DEF_OP_DOUBLE +#ifndef DEF_OP_SINGLE +#define DEF_OP_SINGLE(enumval, ch1) +#endif //DEF_OP_SINGLE + +DEF_OP_TRIPLE(tok_assign_shl, '<', '<', '=') +DEF_OP_TRIPLE(tok_assign_shr, '>', '>', '=') + +DEF_OP_DOUBLE(tok_op_inc, '+', '+') +DEF_OP_DOUBLE(tok_op_dec, '-', '-') +DEF_OP_DOUBLE(tok_op_shl, '<', '<') +DEF_OP_DOUBLE(tok_op_shr, '>', '>') + +DEF_OP_DOUBLE(tok_lop_less_equal, '<', '=') +DEF_OP_DOUBLE(tok_lop_greater_equal, '>', '=') +DEF_OP_DOUBLE(tok_lop_equal, '=', '=') +DEF_OP_DOUBLE(tok_lop_not_equal, '!', '=') +DEF_OP_DOUBLE(tok_lop_and, '&', '&') +DEF_OP_DOUBLE(tok_lop_or, '|', '|') + +DEF_OP_DOUBLE(tok_assign_plus, '+', '=') +DEF_OP_DOUBLE(tok_assign_min, '-', '=') +DEF_OP_DOUBLE(tok_assign_mul, '*', '=') +DEF_OP_DOUBLE(tok_assign_div, '/', '=') +DEF_OP_DOUBLE(tok_assign_mod, '%', '=') +DEF_OP_DOUBLE(tok_assign_and, '&', '=') +DEF_OP_DOUBLE(tok_assign_xor, '^', '=') +DEF_OP_DOUBLE(tok_assign_or, '|', '=') + +DEF_OP_SINGLE(tok_parenopen, '(') +DEF_OP_SINGLE(tok_parenclose, ')') +DEF_OP_SINGLE(tok_blockopen, '{') +DEF_OP_SINGLE(tok_blockclose, '}') +DEF_OP_SINGLE(tok_annotopen, '<') +DEF_OP_SINGLE(tok_annotclose, '>') +DEF_OP_SINGLE(tok_subopen, '[') +DEF_OP_SINGLE(tok_subclose, ']') +DEF_OP_SINGLE(tok_memberaccess, '.') +DEF_OP_SINGLE(tok_comma, ',') +DEF_OP_SINGLE(tok_tenary1, '?') +DEF_OP_SINGLE(tok_tenary2, ':') +DEF_OP_SINGLE(tok_assign, '=') + +DEF_OP_SINGLE(tok_op_mul, '*') +DEF_OP_SINGLE(tok_op_div, '/') +DEF_OP_SINGLE(tok_op_mod, '%') +DEF_OP_SINGLE(tok_op_plus, '+') +DEF_OP_SINGLE(tok_op_min, '-') +DEF_OP_SINGLE(tok_op_neg, '~') +DEF_OP_SINGLE(tok_op_xor, '^') +DEF_OP_SINGLE(tok_op_and, '&') +DEF_OP_SINGLE(tok_op_or, '|') + +DEF_OP_SINGLE(tok_lop_less, '<') +DEF_OP_SINGLE(tok_lop_greater, '>') +DEF_OP_SINGLE(tok_lop_not, '!') + +