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.