summaryrefslogtreecommitdiff
path: root/src/libs/lex/lex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/lex/lex.cpp')
-rw-r--r--src/libs/lex/lex.cpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/libs/lex/lex.cpp b/src/libs/lex/lex.cpp
new file mode 100644
index 0000000..84891f1
--- /dev/null
+++ b/src/libs/lex/lex.cpp
@@ -0,0 +1,167 @@
+// BEGIN_COPYRIGHT
+//
+// Copyright (C) 1999 Allen Akin All Rights Reserved.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the
+// Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+// KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// END_COPYRIGHT
+
+
+
+
+// lex.cpp: Implementation of simple lexical analyzer
+
+#include <ctype.h>
+#include <stdlib.h>
+#include "lex.h"
+
+namespace GLEAN {
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructor:
+///////////////////////////////////////////////////////////////////////////////
+Lex::Lex(const char* s, bool ignoreCase/* = false */) {
+ input = s;
+ p = input;
+ ignoringCase = ignoreCase;
+} // Lex::Lex
+
+///////////////////////////////////////////////////////////////////////////////
+// next - Fetch next token from the input string
+///////////////////////////////////////////////////////////////////////////////
+void
+Lex::next() {
+ while (isspace(*p))
+ ++p;
+
+ if (isalpha(*p) || *p == '_') {
+ id = "";
+ if (ignoringCase)
+ while (isalnum(*p) || *p == '_')
+ id += tolower(*p++);
+ else
+ while (isalnum(*p) || *p == '_')
+ id += *p++;
+ token = ID;
+ return;
+ }
+
+ if (isdigit(*p)) {
+ iValue = strtol(p, const_cast<char**>(&p), 0);
+ token = ICONST;
+ return;
+ }
+
+ char nextC = 0;
+ char c = *p++;
+ if (c)
+ nextC = *p;
+ switch (c) {
+ case '|':
+ if (nextC == '|') {
+ ++p;
+ token = OR_OR;
+ }
+ else
+ token = OR;
+ break;
+ case '&':
+ if (nextC == '&') {
+ ++p;
+ token = AND_AND;
+ }
+ else
+ token = AND;
+ break;
+ case '<':
+ if (nextC == '=') {
+ ++p;
+ token = LE;
+ }
+ else
+ token = LT;
+ break;
+ case '>':
+ if (nextC == '=') {
+ ++p;
+ token = GE;
+ }
+ else
+ token = GT;
+ break;
+ case '=':
+ if (nextC == '=') {
+ ++p;
+ token = EQ;
+ }
+ else
+ token = ASSIGN;
+ break;
+ case '!':
+ if (nextC == '=') {
+ ++p;
+ token = NE;
+ }
+ else
+ token = BANG;
+ break;
+ case '+':
+ token = PLUS;
+ break;
+ case '-':
+ token = MINUS;
+ break;
+ case '*':
+ token = STAR;
+ break;
+ case '/':
+ token = SLASH;
+ break;
+ case '%':
+ token = PERCENT;
+ break;
+ case ',':
+ token = COMMA;
+ break;
+ case '(':
+ token = LPAREN;
+ break;
+ case ')':
+ token = RPAREN;
+ break;
+ case '.':
+ token = DOT;
+ break;
+ case '\0':
+ token = END;
+ --p; // push back '\0' so that token will always be END
+ break;
+ default:
+ throw Lexical("unrecognized symbol", p - input);
+ }
+
+ return;
+} // Lex::next
+
+} // namespace GLEAN