Skip to content

Commit

Permalink
[Parse] Add a new Parse library, to hold some common parsing-related …
Browse files Browse the repository at this point in the history
…routines. Factor out common code from Xml and Json
  • Loading branch information
Whiteknight committed Apr 7, 2012
1 parent b893463 commit 389c66c
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 124 deletions.
12 changes: 8 additions & 4 deletions setup.winxed
Expand Up @@ -270,7 +270,7 @@ function setup_stable_libraries(var rosella)
);

// Random number generation and tools
setup_winxed_lib(rosella, "random", ["Math_Builtins", "String"],
setup_winxed_lib(rosella, "random", ["String", "Math_Builtins"],
"random/Includes",
"random/Random",
"random/RandomNumber",
Expand Down Expand Up @@ -380,7 +380,7 @@ function setup_experimental_libraries(var rosella)
"genetic/mutator/Generic"
);

setup_unstable_lib(rosella, "net", ["Core", "Ascii", "Math_Builtins", "String", "FileSystem", "Date", "Random"],
setup_unstable_lib(rosella, "net", ["Core", "Math_Builtins", "Ascii", "Parse_builtins", "Parse", "String", "FileSystem", "Date", "Random"],
"net/Includes",
"net/Net",
"net/Http",
Expand All @@ -399,7 +399,11 @@ function setup_experimental_libraries(var rosella)
"net/SocketFactory"
);

setup_unstable_lib(rosella, "xml", ["Core", "Ascii", "Parsing", "String", "FileSystem"],
setup_unstable_lib(rosella, "parse", ["Core", "Ascii", "Parse_builtins"],
"parse/Parse"
);

setup_unstable_lib(rosella, "xml", ["Core", "Ascii", "Parse_builtins", "Parse", "String", "FileSystem"],
"xml/Includes",
"xml/Xml",
"xml/Document",
Expand All @@ -408,7 +412,7 @@ function setup_experimental_libraries(var rosella)
"xml/Text"
);

setup_unstable_lib(rosella, "json", ["Core", "Ascii", "Parsing", "Dumper"],
setup_unstable_lib(rosella, "json", ["Core", "Ascii", "Parse_builtins", "Parse", "Dumper"],
"json/Includes",
"json/Json",
"json/Dumper",
Expand Down
11 changes: 11 additions & 0 deletions src/include/Parse.winxed
@@ -0,0 +1,11 @@
namespace Rosella.Parse {
extern function parse_string;
extern function parse_alphanumeric;
extern function parse_number;
extern function error_unknown_char;
}

function __include_parse [anon,init,load] ()
{
Rosella.load_bytecode_file('rosella/parse.pbc', 'load');
}
File renamed without changes.
81 changes: 4 additions & 77 deletions src/unstable/json/Parser.winxed
Expand Up @@ -13,9 +13,9 @@ namespace Rosella.Json.Parser
if (c == ASCII_OPEN_BRACKET)
return __parse_array(json, s, b, len);
if (c == ASCII_SINGLE_QUOTE || c == ASCII_DOUBLE_QUOTE)
return __parse_string(c, json, s, b, len);
return Rosella.Parse.parse_string(c, json, s, b, len);
if (codepoint_is_digit(c))
return __parse_number(c, json, s, b, len);
return Rosella.Parse.parse_number(c, json, s, b, len);
if (c == ASCII_t) {
if (get_next(s, b) == ASCII_r &&
get_next(s, b) == ASCII_u &&
Expand Down Expand Up @@ -50,7 +50,7 @@ namespace Rosella.Json.Parser
eat_whitespace(s, b);
int c = get_next(s, b);
if (c == ASCII_SINGLE_QUOTE || c == ASCII_DOUBLE_QUOTE) {
string str = __parse_string(c, json, s, b, len);
string str = Rosella.Parse.parse_string(c, json, s, b, len);
eat_whitespace(s, b);
c = get_next(s, b);
if (c != ASCII_COLON)
Expand All @@ -66,7 +66,7 @@ namespace Rosella.Json.Parser
}
else if (codepoint_is_alpha(c)) {
unshift_int(s, c);
string str = __parse_alphanumeric(json, s, b, len);
string str = Rosella.Parse.parse_alphanumeric(json, s, b, len);
eat_whitespace(s, b);
c = get_next(s, b);
if (c != ASCII_COLON)
Expand Down Expand Up @@ -110,77 +110,4 @@ namespace Rosella.Json.Parser
}
return a;
}

function __parse_string(int q, string json, var s, var b, int len)
{
var sb = new 'StringBuilder';
while(have_more_chars(s, b)) {
int c = get_next(s, b);
if (c == ASCII_BACKSLASH) {
push(sb, "\\");
c = get_next(s, b);
push(sb, chr(c));
continue;
}
if (c == q)
break;
push(sb, chr(c));
}
return sb;
}

function __parse_alphanumeric(string xml, var s, var b, int len)
{
var sb = new 'StringBuilder';
while(have_more_chars(s, b)) {
int c = get_next(s, b);
if (!codepoint_is_alphanumeric(c)) {
unshift_int(s, c);
break;
}
push(sb, chr(c));
}
string result = string(sb);
return result;
}

function __parse_number(int c, string json, var s, var b, int len)
{
int have_e = false;
int have_dot = false;
int have_sign = false;
var sb = new 'StringBuilder';
push(sb, codepoint_to_string(c));
while (have_more_chars(s, b)) {
int d = get_next(s, b);
if (!have_sign && (d == ASCII_PLUS|| d == ASCII_DASH)) {
have_sign = true;
push(sb, codepoint_to_string(d));
}
else if (codepoint_is_digit(d)) {
push(sb, codepoint_to_string(d));
continue;
}
else if (!have_e && (d == ASCII_e || d == ASCII_E)) {
have_e = true;
have_sign = false;
push(sb, 'e');
}
else if (!have_e && !have_dot && d == ASCII_PERIOD) {
have_dot = true;
push(sb, '.');
}
else {
unshift_int(s, d);
break;
}
}
if (have_dot) {
float f_value = float(string(sb));
return f_value;
} else {
int i_value = int(string(sb));
return i_value;
}
}
}
10 changes: 4 additions & 6 deletions src/unstable/net/Uri.winxed
Expand Up @@ -79,13 +79,11 @@ class Rosella.Net.Uri
// Get the Path and Query
function path_query() { return self.parts["Path_Query"]; }

// TODO: This
// Get the Query String
function query_string() { }
function query_string() { return self.parts["Query_String"]; }

// TODO: This
// Get the anchor
function anchor() { }
// Get the fragment/anchor
function fragment() { return self.parts["Fragment"]; }

/* Private Helper Methods
*/
Expand All @@ -101,7 +99,7 @@ class Rosella.Net.Uri
"Port": "",
"Path_Query": "",
"Query_String": "",
"Anchor": ""
"Fragment": ""
};
}

Expand Down
97 changes: 97 additions & 0 deletions src/unstable/parse/Parse.winxed
@@ -0,0 +1,97 @@
namespace Rosella.Parse
{
function parse_quoted(int q, string xml, var s, var b, int len)
{
var sb = new 'StringBuilder';
while (have_more_chars(s, b)) {
int c = get_next(s, b);
if (c == q)
break;
if (c == ASCII_BACKSLASH)
c = get_next(s, b);
push(sb, chr(c));
}
return sb;
}

function parse_string(int q, string _str, var s, var b, int len)
{
var sb = new 'StringBuilder';
while(have_more_chars(s, b)) {
int c = get_next(s, b);
if (c == ASCII_BACKSLASH) {
// TODO: Deal with common C-style escapes
push(sb, "\\");
c = get_next(s, b);
push(sb, chr(c));
continue;
}
if (c == q)
break;
push(sb, chr(c));
}
return sb;
}

function parse_alphanumeric(string _str, var s, var b, int len)
{
var sb = new 'StringBuilder';
while(have_more_chars(s, b)) {
int c = get_next(s, b);
if (!codepoint_is_alphanumeric(c)) {
unshift_int(s, c);
break;
}
push(sb, chr(c));
}
string result = string(sb);
return result;
}

function parse_number(int c, string _str, var s, var b, int len)
{
int have_e = false;
int have_dot = false;
int have_sign = false;
var sb = new 'StringBuilder';
push(sb, codepoint_to_string(c));
while (have_more_chars(s, b)) {
int d = get_next(s, b);
if (!have_sign && (d == ASCII_PLUS|| d == ASCII_DASH)) {
have_sign = true;
push(sb, codepoint_to_string(d));
}
else if (codepoint_is_digit(d)) {
push(sb, codepoint_to_string(d));
continue;
}
else if (!have_e && (d == ASCII_e || d == ASCII_E)) {
have_e = true;
have_sign = false;
push(sb, 'e');
}
else if (!have_e && !have_dot && d == ASCII_PERIOD) {
have_dot = true;
push(sb, '.');
}
else {
unshift_int(s, d);
break;
}
}
if (have_dot) {
float f_value = float(string(sb));
return f_value;
} else {
int i_value = int(string(sb));
return i_value;
}
}

function error_unknown_char(int c, string context, int pos)
{
if (c == ASCII_NULL)
Rosella.Error.error("Unexpected end of input while parsing %s at position %d", context, pos);
Rosella.Error.error("Unexpected token '%s' in %s at position %d", chr(c), context, pos);
}
}

0 comments on commit 389c66c

Please sign in to comment.