diff --git a/shared/cplusplus/Keywords.cpp b/shared/cplusplus/Keywords.cpp
index 0e19b6b1d4f1be79f24c048cc18adbe41e71068e..d5ec6b5d432ead6b2454c6f92ac2f58a6591471b 100644
--- a/shared/cplusplus/Keywords.cpp
+++ b/shared/cplusplus/Keywords.cpp
@@ -1208,4 +1208,141 @@ int Lexer::classify(const char *s, int n, bool q) {
   } // switch
 }
 
+static inline int classifyOperator2(const char *s) {
+  if (s[0] == 'o') {
+    if (s[1] == 'r') {
+      return T_OR;
+    }
+  }
+  return T_IDENTIFIER;
+}
+
+static inline int classifyOperator3(const char *s) {
+  if (s[0] == 'a') {
+    if (s[1] == 'n') {
+      if (s[2] == 'd') {
+        return T_AND;
+      }
+    }
+  }
+  else if (s[0] == 'n') {
+    if (s[1] == 'o') {
+      if (s[2] == 't') {
+        return T_NOT;
+      }
+    }
+  }
+  else if (s[0] == 'x') {
+    if (s[1] == 'o') {
+      if (s[2] == 'r') {
+        return T_XOR;
+      }
+    }
+  }
+  return T_IDENTIFIER;
+}
+
+static inline int classifyOperator5(const char *s) {
+  if (s[0] == 'b') {
+    if (s[1] == 'i') {
+      if (s[2] == 't') {
+        if (s[3] == 'o') {
+          if (s[4] == 'r') {
+            return T_BITOR;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'c') {
+    if (s[1] == 'o') {
+      if (s[2] == 'm') {
+        if (s[3] == 'p') {
+          if (s[4] == 'l') {
+            return T_COMPL;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'o') {
+    if (s[1] == 'r') {
+      if (s[2] == '_') {
+        if (s[3] == 'e') {
+          if (s[4] == 'q') {
+            return T_OR_EQ;
+          }
+        }
+      }
+    }
+  }
+  return T_IDENTIFIER;
+}
+
+static inline int classifyOperator6(const char *s) {
+  if (s[0] == 'a') {
+    if (s[1] == 'n') {
+      if (s[2] == 'd') {
+        if (s[3] == '_') {
+          if (s[4] == 'e') {
+            if (s[5] == 'q') {
+              return T_AND_EQ;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'b') {
+    if (s[1] == 'i') {
+      if (s[2] == 't') {
+        if (s[3] == 'a') {
+          if (s[4] == 'n') {
+            if (s[5] == 'd') {
+              return T_BITAND;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'n') {
+    if (s[1] == 'o') {
+      if (s[2] == 't') {
+        if (s[3] == '_') {
+          if (s[4] == 'e') {
+            if (s[5] == 'q') {
+              return T_NOT_EQ;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'x') {
+    if (s[1] == 'o') {
+      if (s[2] == 'r') {
+        if (s[3] == '_') {
+          if (s[4] == 'e') {
+            if (s[5] == 'q') {
+              return T_XOR_EQ;
+            }
+          }
+        }
+      }
+    }
+  }
+  return T_IDENTIFIER;
+}
+
+int Lexer::classifyOperator(const char *s, int n) {
+  switch (n) {
+    case 2: return classifyOperator2(s);
+    case 3: return classifyOperator3(s);
+    case 5: return classifyOperator5(s);
+    case 6: return classifyOperator6(s);
+    default: return T_IDENTIFIER;
+  } // switch
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/shared/cplusplus/Lexer.cpp b/shared/cplusplus/Lexer.cpp
index af6f09f74d211d285249c8601829bd2af4cee89f..2e9ae98c1e0c90aac35c1f44387903a9650b52eb 100644
--- a/shared/cplusplus/Lexer.cpp
+++ b/shared/cplusplus/Lexer.cpp
@@ -589,8 +589,13 @@ void Lexer::scan_helper(Token *tok)
                 tok->kind = classify(yytext, yylen, _qtMocRunEnabled);
             else
                 tok->kind = T_IDENTIFIER;
-            if (tok->kind == T_IDENTIFIER && control())
-                tok->identifier = control()->findOrInsertIdentifier(yytext, yylen);
+
+            if (tok->kind == T_IDENTIFIER) {
+                tok->kind = classifyOperator(yytext, yylen);
+
+                if (control())
+                    tok->identifier = control()->findOrInsertIdentifier(yytext, yylen);
+            }
             break;
         } else if (std::isdigit(ch)) {
             const char *yytext = _currentChar - 1;
diff --git a/shared/cplusplus/Lexer.h b/shared/cplusplus/Lexer.h
index 1d85a58eb9fb41664b4b21de4f2c66e32b1e4f6b..57f9d3e1362244dff7456957410fd97ad4977404 100644
--- a/shared/cplusplus/Lexer.h
+++ b/shared/cplusplus/Lexer.h
@@ -112,6 +112,7 @@ private:
     void scan_helper(Token *tok);
     void setSource(const char *firstChar, const char *lastChar);
     static int classify(const char *string, int length, bool q);
+    static int classifyOperator(const char *string, int length);
 
     inline void yyinp()
     {
diff --git a/shared/cplusplus/Token.h b/shared/cplusplus/Token.h
index e172fea568059b365014a66c28a972136b57babd..f017bbc8e7ed9a3acdfa54b48ee3052fee34baa3 100644
--- a/shared/cplusplus/Token.h
+++ b/shared/cplusplus/Token.h
@@ -209,7 +209,19 @@ enum Kind {
 
     T_LAST_KEYWORD = T_SLOTS,
 
-    // ### aliases
+    // aliases
+    T_OR = T_PIPE_PIPE,
+    T_AND = T_AMPER_AMPER,
+    T_NOT = T_EXCLAIM,
+    T_XOR = T_CARET,
+    T_BITOR = T_PIPE,
+    T_COMPL = T_TILDE,
+    T_OR_EQ = T_PIPE_EQUAL,
+    T_AND_EQ = T_AMPER_EQUAL,
+    T_BITAND = T_AMPER,
+    T_NOT_EQ = T_EXCLAIM_EQUAL,
+    T_XOR_EQ = T_CARET_EQUAL,
+
     T___ASM = T_ASM,
     T___ASM__ = T_ASM,