From 65f07aa2de0fa24430a6deccc72334dfe883174f Mon Sep 17 00:00:00 2001
From: Roberto Raggi <qtc-committer@nokia.com>
Date: Wed, 10 Dec 2008 13:27:59 +0100
Subject: [PATCH] Implemented support for C++ and iso646 operators.

---
 shared/cplusplus/Keywords.cpp | 137 ++++++++++++++++++++++++++++++++++
 shared/cplusplus/Lexer.cpp    |   9 ++-
 shared/cplusplus/Lexer.h      |   1 +
 shared/cplusplus/Token.h      |  14 +++-
 4 files changed, 158 insertions(+), 3 deletions(-)

diff --git a/shared/cplusplus/Keywords.cpp b/shared/cplusplus/Keywords.cpp
index 0e19b6b1d4f..d5ec6b5d432 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 af6f09f74d2..2e9ae98c1e0 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 1d85a58eb9f..57f9d3e1362 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 e172fea5680..f017bbc8e7e 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,
 
-- 
GitLab