Author: ruschein
Date: 2011-09-23 08:59:00 -0700 (Fri, 23 Sep 2011)
New Revision: 26944

Added:
   csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScanner.cc
   csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScanner.h
   csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScannerTest.cc
Log:
Work in progress.

Added: csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScanner.cc
===================================================================
--- csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScanner.cc                     
        (rev 0)
+++ csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScanner.cc     2011-09-23 
15:59:00 UTC (rev 26944)
@@ -0,0 +1,189 @@
+#include "JSONScanner.h"
+#include <iostream>
+#include <stdexcept>
+#include <cctype>
+#include <cstdlib>
+
+
+void JSONScanner::ungetToken() {
+       if (pushed_back_)
+               throw std::runtime_error("can't unget two tokens in a row!");
+
+       pushed_back_ = true;
+}
+
+
+// Assumes that "ch" points to the first character of the string.
+static bool ParseString(std::string::const_iterator &ch, const 
std::string::const_iterator &end, std::string * const value) {
+       value->clear();
+
+       for (;;) {
+               if (ch == end)
+                       return false;
+
+               if (*ch == '"') {
+                       ++ch;
+                       return true;
+               }
+                       
+               if (*ch == '\\') { // escaped character (we're ignoring unicode 
values for now
+                       ++ch;
+                       if (*ch == 'u') {
+                               std::cerr << "*** unicode char support not 
implemented!\n";
+                               return false;
+                       }
+                       *value += *ch;
+                       ++ch;
+               } else {
+                       *value += *ch;
+                       ++ch;
+               }
+       }
+}
+
+
+static bool ParseInteger(std::string::const_iterator &ch, const 
std::string::const_iterator &end, int64_t * const value) {
+       std::string s;
+       if (*ch == '-') {
+               s += '-';
+               ++ch;
+       }
+
+       while (ch != end and isdigit(*ch)) {
+               s += *ch;
+               ++ch;
+       }
+
+       char *end_ptr;
+       *value = ::strtoll(s.c_str(), &end_ptr, 10);
+
+       return end_ptr != s.c_str();
+}
+
+
+static bool Expect(std::string::const_iterator &ch, const 
std::string::const_iterator &end, const char * const expected_string) {
+       const char *next_expected_char = expected_string;
+       while (*next_expected_char != '\0') {
+               if (ch == end)
+                       return false;
+               if (*ch != *next_expected_char)
+                       return false;
+               ++ch, ++next_expected_char;
+       }
+
+       return true;
+}
+
+
+static bool ParseBoolean(std::string::const_iterator &ch, const 
std::string::const_iterator &end, bool * const value) {
+       if (*ch != 't' && *ch != 'f')
+               return false;
+
+       if (*ch == 't') {
+               if (!Expect(ch, end, "true"))
+                       return false;
+               *value = true;
+       } else {
+               if (!Expect(ch, end, "false"))
+                       return false;
+               *value = false;
+       }
+
+       return true;
+}
+
+
+JSONScanner::TokenType JSONScanner::getToken() {
+       if (pushed_back_) {
+               pushed_back_ = false;
+               return last_token_;
+       }
+
+       skipWhitespace();
+
+       if (ch == end) {
+               last_token_ = END_OF_INPUT;
+               return END_OF_INPUT;
+       }
+
+       if (*ch == '{') {
+               ++ch;
+               last_token_ = OPEN_BRACE;
+               return OPEN_BRACE;
+       }
+
+       if (*ch == '}') {
+               ++ch;
+               last_token_ = CLOSE_BRACE;
+               return CLOSE_BRACE;
+       }
+
+       if (*ch == '[') {
+               ++ch;
+               last_token_ = OPEN_BRACKET;
+               return OPEN_BRACKET;
+       }
+
+       if (*ch == ']') {
+               ++ch;
+               last_token_ = CLOSE_BRACKET;
+               return CLOSE_BRACKET;
+       }
+
+       if (*ch == ':') {
+               ++ch;
+               last_token_ = COLON;
+               return COLON;
+       }
+
+       if (*ch == ',') {
+               ++ch;
+               last_token_ = COMMA;
+               return COMMA;
+       }
+
+       if (*ch == '"') {
+               ++ch;
+               if (!ParseString(ch, end, &last_string_)) {
+                       last_error_message_ = "error parsing a string 
constant!";
+                       last_token_ = ERROR;
+                       return ERROR;
+               }
+               last_token_ = STRING_CONSTANT;
+               return STRING_CONSTANT;
+       }
+
+       if (isdigit(*ch) or *ch == '-') {
+               if (!ParseInteger(ch, end, &last_int_)) {
+                       last_error_message_ = "error parsing an integer 
constant!";
+                       last_token_ = ERROR;
+                       return ERROR;
+               }
+               last_token_ = INTEGER_CONSTANT;
+               return INTEGER_CONSTANT;
+       }
+
+       if (*ch == 't' or *ch == 'f') {
+               if (!ParseBoolean(ch, end, &last_bool_)) {
+                       last_error_message_ = "error parsing a boolean 
constant!";
+                       last_token_ = ERROR;
+                       return ERROR;
+               }
+               last_token_ = BOOLEAN_CONSTANT;
+               return BOOLEAN_CONSTANT;
+       }
+
+       last_error_message_ = "unexpected input character '" + std::string(1, 
*ch) + "'!";
+       last_token_ = ERROR;
+       return ERROR;
+}
+
+
+void JSONScanner::skipWhitespace() {
+       for (;;) {
+               if (ch == end or !isspace(*ch))
+                       return;
+
+               ++ch;
+       }
+}

Added: csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScanner.h
===================================================================
--- csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScanner.h                      
        (rev 0)
+++ csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScanner.h      2011-09-23 
15:59:00 UTC (rev 26944)
@@ -0,0 +1,35 @@
+#ifndef JSON_SCANNER_H
+#define JSON_SCANNER_H
+
+
+#include <string>
+#include <inttypes.h>
+
+
+class JSONScanner {
+       std::string last_string_;
+       int64_t last_int_;
+       bool last_bool_;
+       const std::string::const_iterator end;
+       std::string::const_iterator ch;
+       std::string last_error_message_;
+       bool pushed_back_;
+public:
+       enum TokenType { ERROR, OPEN_BRACE, CLOSE_BRACE, OPEN_BRACKET, 
CLOSE_BRACKET, COMMA, COLON, STRING_CONSTANT, INTEGER_CONSTANT, 
BOOLEAN_CONSTANT, END_OF_INPUT };
+private:
+       TokenType last_token_;
+public:
+
+ JSONScanner(const std::string &document): end(document.end()), 
ch(document.begin()), pushed_back_(false) { } 
+       TokenType getToken();
+       void ungetToken(); // Can only be called once after a call to 
getToken().
+       inline std::string getLastString() { return last_string_; }
+       inline int64_t getLastInteger() { return last_int_; }
+       inline bool getLastBoolean() { return last_bool_; }
+       inline std::string getLastErrorMsg() { return last_error_message_; }
+private:
+       void skipWhitespace();
+};
+
+
+#endif // ifndef JSON_SCANNER_H

Added: csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScannerTest.cc
===================================================================
--- csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScannerTest.cc                 
        (rev 0)
+++ csplugins/trunk/ucsd/ruschein/GSFS/progs/JSONScannerTest.cc 2011-09-23 
15:59:00 UTC (rev 26944)
@@ -0,0 +1,63 @@
+#include <iostream>
+#include <cstdlib>
+#include <FileUtil.h>
+#include "JSONScanner.h"
+
+
+void Usage() {
+       std::cerr << "usage: JSONScannerTest JSON_document\n";
+       std::exit(EXIT_FAILURE);
+}
+
+
+int main(int argc, char *argv[]) {
+       if (argc != 2)
+               Usage();
+
+
+       std::string json_directory_listing;
+       if (!FileUtil::ReadFile(argv[1], &json_directory_listing)) {
+               std::cerr << "*** Failed to read a directory listing from \"" 
<< argv[1] << "\"!";
+               std::exit(EXIT_FAILURE);
+       }
+
+       JSONScanner scanner(json_directory_listing);
+       for (;;) {
+               const JSONScanner::TokenType token = scanner.getToken();
+               switch (token) {
+               case JSONScanner::END_OF_INPUT:
+                       return EXIT_SUCCESS;
+               case JSONScanner::ERROR:
+                       std::cerr << "*** parse error (" << 
scanner.getLastErrorMsg() << ")\n";
+                       return EXIT_FAILURE;
+               case JSONScanner::OPEN_BRACE:
+                       std::cout << "{\n";
+                       break;
+               case JSONScanner::CLOSE_BRACE:
+                       std::cout << "}\n";
+                       break;
+               case JSONScanner::OPEN_BRACKET:
+                       std::cout << "[\n";
+                       break;
+               case JSONScanner::CLOSE_BRACKET:
+                       std::cout << "]\n";
+                       break;
+               case JSONScanner::COMMA:
+                       std::cout << ",\n";
+                       break;
+               case JSONScanner::COLON:
+                       std::cout << ":\n";
+                       break;
+               case JSONScanner::STRING_CONSTANT:
+                       std::cout << "string(" << scanner.getLastString() << 
")\n";
+                       break;
+               case JSONScanner::INTEGER_CONSTANT:
+                       std::cout << "integer(" << scanner.getLastInteger() << 
")\n";
+                       break;
+               case JSONScanner::BOOLEAN_CONSTANT:
+                       std::cout << "bool(" << scanner.getLastBoolean() << 
")\n";
+                       break;
+               }
+       }
+}
+

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to