Move JSON parser source to standalone file
This commit is contained in:
parent
3057173370
commit
e2100f6ccd
179
spec/json_parser.propane
Normal file
179
spec/json_parser.propane
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
<<
|
||||||
|
import std.math;
|
||||||
|
import json_types;
|
||||||
|
private string string_value;
|
||||||
|
>>
|
||||||
|
|
||||||
|
ptype JSONValue;
|
||||||
|
ptype array = JSONValue[];
|
||||||
|
ptype dict = JSONValue[string];
|
||||||
|
ptype string = string;
|
||||||
|
|
||||||
|
drop /\s+/;
|
||||||
|
token lbrace /\{/;
|
||||||
|
token rbrace /\}/;
|
||||||
|
token lbracket /\[/;
|
||||||
|
token rbracket /\]/;
|
||||||
|
token comma /,/;
|
||||||
|
token colon /:/;
|
||||||
|
token number /-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][-+]?[0-9]+)?/ <<
|
||||||
|
double n;
|
||||||
|
bool negative;
|
||||||
|
size_t i = 0u;
|
||||||
|
if (match[i] == '-')
|
||||||
|
{
|
||||||
|
negative = true;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while ('0' <= match[i] && match[i] <= '9')
|
||||||
|
{
|
||||||
|
n *= 10.0;
|
||||||
|
n += (match[i] - '0');
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (match[i] == '.')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
double mult = 0.1;
|
||||||
|
while ('0' <= match[i] && match[i] <= '9')
|
||||||
|
{
|
||||||
|
n += mult * (match[i] - '0');
|
||||||
|
mult /= 10.0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match[i] == 'e' || match[i] == 'E')
|
||||||
|
{
|
||||||
|
bool exp_negative;
|
||||||
|
i++;
|
||||||
|
if (match[i] == '-')
|
||||||
|
{
|
||||||
|
exp_negative = true;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (match[i] == '+')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
long exp;
|
||||||
|
while ('0' <= match[i] && match[i] <= '9')
|
||||||
|
{
|
||||||
|
exp *= 10;
|
||||||
|
exp += (match[i] - '0');
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (exp_negative)
|
||||||
|
{
|
||||||
|
exp = -exp;
|
||||||
|
}
|
||||||
|
n = pow(n, exp);
|
||||||
|
}
|
||||||
|
if (negative)
|
||||||
|
{
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
$$ = new JSONNumber(n);
|
||||||
|
>>
|
||||||
|
token true <<
|
||||||
|
$$ = new JSONTrue();
|
||||||
|
>>
|
||||||
|
token false <<
|
||||||
|
$$ = new JSONFalse();
|
||||||
|
>>
|
||||||
|
token null <<
|
||||||
|
$$ = new JSONNull();
|
||||||
|
>>
|
||||||
|
/"/ <<
|
||||||
|
$mode(string);
|
||||||
|
string_value = "";
|
||||||
|
>>
|
||||||
|
string: token string (string) /"/ <<
|
||||||
|
$$ = string_value;
|
||||||
|
$mode(default);
|
||||||
|
>>
|
||||||
|
string: /\\"/ <<
|
||||||
|
string_value ~= "\"";
|
||||||
|
>>
|
||||||
|
string: /\\\\/ <<
|
||||||
|
string_value ~= "\\";
|
||||||
|
>>
|
||||||
|
string: /\\\// <<
|
||||||
|
string_value ~= "/";
|
||||||
|
>>
|
||||||
|
string: /\\b/ <<
|
||||||
|
string_value ~= "\b";
|
||||||
|
>>
|
||||||
|
string: /\\f/ <<
|
||||||
|
string_value ~= "\f";
|
||||||
|
>>
|
||||||
|
string: /\\n/ <<
|
||||||
|
string_value ~= "\n";
|
||||||
|
>>
|
||||||
|
string: /\\r/ <<
|
||||||
|
string_value ~= "\r";
|
||||||
|
>>
|
||||||
|
string: /\\t/ <<
|
||||||
|
string_value ~= "\t";
|
||||||
|
>>
|
||||||
|
string: /\\u[0-9a-fA-F]{4}/ <<
|
||||||
|
/* Not actually going to encode the code point for this example... */
|
||||||
|
string_value ~= "{" ~ match[2..6] ~ "}";
|
||||||
|
>>
|
||||||
|
string: /[^\\]/ <<
|
||||||
|
string_value ~= match;
|
||||||
|
>>
|
||||||
|
Start -> Value <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
Value -> string <<
|
||||||
|
$$ = new JSONString($1);
|
||||||
|
>>
|
||||||
|
Value -> number <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
Value -> Object <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
Value -> Array <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
Value -> true <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
Value -> false <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
Value -> null <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
Object -> lbrace rbrace <<
|
||||||
|
$$ = new JSONObject();
|
||||||
|
>>
|
||||||
|
Object -> lbrace KeyValues rbrace <<
|
||||||
|
$$ = new JSONObject($2);
|
||||||
|
>>
|
||||||
|
KeyValues (dict) -> KeyValue <<
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
KeyValues -> KeyValues comma KeyValue <<
|
||||||
|
foreach (key, value; $3)
|
||||||
|
{
|
||||||
|
$1[key] = value;
|
||||||
|
}
|
||||||
|
$$ = $1;
|
||||||
|
>>
|
||||||
|
KeyValue (dict) -> string colon Value <<
|
||||||
|
$$ = [$1: $3];
|
||||||
|
>>
|
||||||
|
Array -> lbracket rbracket <<
|
||||||
|
$$ = new JSONArray();
|
||||||
|
>>
|
||||||
|
Array -> lbracket Values rbracket <<
|
||||||
|
$$ = new JSONArray($2);
|
||||||
|
>>
|
||||||
|
Values (array) -> Value <<
|
||||||
|
$$ = [$1];
|
||||||
|
>>
|
||||||
|
Values -> Values comma Value <<
|
||||||
|
$$ = $1 ~ [$3];
|
||||||
|
>>
|
@ -336,187 +336,7 @@ EOF
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "allows creating a JSON parser" do
|
it "allows creating a JSON parser" do
|
||||||
write_grammar <<EOF
|
write_grammar(File.read("spec/json_parser.propane"))
|
||||||
<<
|
|
||||||
import std.math;
|
|
||||||
import json_types;
|
|
||||||
string string_value;
|
|
||||||
>>
|
|
||||||
|
|
||||||
ptype JSONValue;
|
|
||||||
ptype array = JSONValue[];
|
|
||||||
ptype dict = JSONValue[string];
|
|
||||||
ptype string = string;
|
|
||||||
|
|
||||||
drop /\\s+/;
|
|
||||||
token lbrace /\\{/;
|
|
||||||
token rbrace /\\}/;
|
|
||||||
token lbracket /\\[/;
|
|
||||||
token rbracket /\\]/;
|
|
||||||
token comma /,/;
|
|
||||||
token colon /:/;
|
|
||||||
token number /-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][-+]?[0-9]+)?/ <<
|
|
||||||
double n;
|
|
||||||
bool negative;
|
|
||||||
size_t i = 0u;
|
|
||||||
if (match[i] == '-')
|
|
||||||
{
|
|
||||||
negative = true;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while ('0' <= match[i] && match[i] <= '9')
|
|
||||||
{
|
|
||||||
n *= 10.0;
|
|
||||||
n += (match[i] - '0');
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (match[i] == '.')
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
double mult = 0.1;
|
|
||||||
while ('0' <= match[i] && match[i] <= '9')
|
|
||||||
{
|
|
||||||
n += mult * (match[i] - '0');
|
|
||||||
mult /= 10.0;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (match[i] == 'e' || match[i] == 'E')
|
|
||||||
{
|
|
||||||
bool exp_negative;
|
|
||||||
i++;
|
|
||||||
if (match[i] == '-')
|
|
||||||
{
|
|
||||||
exp_negative = true;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else if (match[i] == '+')
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
long exp;
|
|
||||||
while ('0' <= match[i] && match[i] <= '9')
|
|
||||||
{
|
|
||||||
exp *= 10;
|
|
||||||
exp += (match[i] - '0');
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (exp_negative)
|
|
||||||
{
|
|
||||||
exp = -exp;
|
|
||||||
}
|
|
||||||
n = pow(n, exp);
|
|
||||||
}
|
|
||||||
if (negative)
|
|
||||||
{
|
|
||||||
n = -n;
|
|
||||||
}
|
|
||||||
$$ = new JSONNumber(n);
|
|
||||||
>>
|
|
||||||
token true <<
|
|
||||||
$$ = new JSONTrue();
|
|
||||||
>>
|
|
||||||
token false <<
|
|
||||||
$$ = new JSONFalse();
|
|
||||||
>>
|
|
||||||
token null <<
|
|
||||||
$$ = new JSONNull();
|
|
||||||
>>
|
|
||||||
/"/ <<
|
|
||||||
$mode(string);
|
|
||||||
string_value = "";
|
|
||||||
>>
|
|
||||||
string: token string (string) /"/ <<
|
|
||||||
$$ = string_value;
|
|
||||||
$mode(default);
|
|
||||||
>>
|
|
||||||
string: /\\\\"/ <<
|
|
||||||
string_value ~= "\\"";
|
|
||||||
>>
|
|
||||||
string: /\\\\\\\\/ <<
|
|
||||||
string_value ~= "\\\\";
|
|
||||||
>>
|
|
||||||
string: /\\\\\\// <<
|
|
||||||
string_value ~= "/";
|
|
||||||
>>
|
|
||||||
string: /\\\\b/ <<
|
|
||||||
string_value ~= "\\b";
|
|
||||||
>>
|
|
||||||
string: /\\\\f/ <<
|
|
||||||
string_value ~= "\\f";
|
|
||||||
>>
|
|
||||||
string: /\\\\n/ <<
|
|
||||||
string_value ~= "\\n";
|
|
||||||
>>
|
|
||||||
string: /\\\\r/ <<
|
|
||||||
string_value ~= "\\r";
|
|
||||||
>>
|
|
||||||
string: /\\\\t/ <<
|
|
||||||
string_value ~= "\\t";
|
|
||||||
>>
|
|
||||||
string: /\\\\u[0-9a-fA-F]{4}/ <<
|
|
||||||
/* Not actually going to encode the code point for this example... */
|
|
||||||
string_value ~= "{" ~ match[2..6] ~ "}";
|
|
||||||
>>
|
|
||||||
string: /[^\\\\]/ <<
|
|
||||||
string_value ~= match;
|
|
||||||
>>
|
|
||||||
Start -> Value <<
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
Value -> string <<
|
|
||||||
$$ = new JSONString($1);
|
|
||||||
>>
|
|
||||||
Value -> number <<
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
Value -> Object <<
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
Value -> Array <<
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
Value -> true <<
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
Value -> false <<
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
Value -> null <<
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
Object -> lbrace rbrace <<
|
|
||||||
$$ = new JSONObject();
|
|
||||||
>>
|
|
||||||
Object -> lbrace KeyValues rbrace <<
|
|
||||||
$$ = new JSONObject($2);
|
|
||||||
>>
|
|
||||||
KeyValues (dict) -> KeyValue <<
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
KeyValues -> KeyValues comma KeyValue <<
|
|
||||||
foreach (key, value; $3)
|
|
||||||
{
|
|
||||||
$1[key] = value;
|
|
||||||
}
|
|
||||||
$$ = $1;
|
|
||||||
>>
|
|
||||||
KeyValue (dict) -> string colon Value <<
|
|
||||||
$$ = [$1: $3];
|
|
||||||
>>
|
|
||||||
Array -> lbracket rbracket <<
|
|
||||||
$$ = new JSONArray();
|
|
||||||
>>
|
|
||||||
Array -> lbracket Values rbracket <<
|
|
||||||
$$ = new JSONArray($2);
|
|
||||||
>>
|
|
||||||
Values (array) -> Value <<
|
|
||||||
$$ = [$1];
|
|
||||||
>>
|
|
||||||
Values -> Values comma Value <<
|
|
||||||
$$ = $1 ~ [$3];
|
|
||||||
>>
|
|
||||||
EOF
|
|
||||||
build_parser
|
build_parser
|
||||||
compile("spec/test_parsing_json.d", "spec/json_types.d")
|
compile("spec/test_parsing_json.d", "spec/json_types.d")
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user