Skip to content
This repository was archived by the owner on May 17, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"presets": [
["es2015", { "modules": false }]
],
"plugins": [
"syntax-object-rest-spread",
"transform-object-rest-spread"
]
}
2 changes: 0 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

var parser = require('./parser');

module.exports = {
Expand Down
2,658 changes: 1,920 additions & 738 deletions lib/parser.js

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"test": "mocha --require babel-core/register",
"fmt": "mongodb-js-fmt ./*.js ./test/*.js",
"compile": "npm run babel & npm run pegjs",
"babel": "babel ./src --out-dir ./lib --presets es2015",
"babel": "babel ./src --out-dir ./lib",
"pegjs": "pegjs -o ./lib/parser.js < ./src/grammar.pegjs",
"check": "mongodb-js-precommit ./src ./test",
"prepublish": "npm run compile",
Expand All @@ -48,11 +48,13 @@
},
"devDependencies": {
"babel-cli": "^6.10.1",
"babel-plugin-syntax-object-rest-spread": "^6.13.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-es2015": "^6.14.0",
"eslint-config-mongodb-js": "^2.2.0",
"mocha": "^6.0.1",
"mongodb-js-fmt": "^0.0.3",
"mongodb-js-precommit": "^0.2.9",
"pre-commit": "^1.1.2",
"mocha": "^6.0.1"
"pre-commit": "^1.1.2"
}
}
150 changes: 130 additions & 20 deletions src/grammar.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,97 @@ operator
// operator-expression-operator
/ quotation_mark operator:operator_expression_operator quotation_mark name_separator opobject:operator_expression
{ return { pos: "operator-expression-operator", operator: operator, operators: opobject.operators } }
// geo-operator
// geo-within-operator
/ quotation_mark "$geoWithin" quotation_mark name_separator shape:shape
{ return { pos: "geo-within-operator", operator: "$geoWithin", shape: shape }; }

// geo-intersects-operator
/ quotation_mark "$geoIntersects" quotation_mark name_separator geometry:geometry
{ return { pos: "geo-intersects-operator", operator: "$geoIntersects", geometry: geometry }; }
// near-operator
/ quotation_mark near_operator:("$nearSphere" / "$near") quotation_mark name_separator value:(geometry_point / legacy_coordinates)
{ return { pos: "near-operator", operator: near_operator, value: value }; }
// min-distance-operator
/ quotation_mark operator:distance_operator quotation_mark name_separator value:number_positive
{ return { pos: "distance-operator", operator: operator, value: value }; }

/* --- Geo Operators --- */
distance_operator
= "$minDistance" / "$maxDistance"

shape
= geometry
/ legacy_shape

geometry
= begin_object
quotation_mark "$geometry" quotation_mark name_separator json:$ JSON // @todo replace with GeoJSON
quotation_mark "$geometry" quotation_mark name_separator
begin_object
members:(
type:(
quotation_mark "type" quotation_mark
name_separator quotation_mark type:geometry_type quotation_mark
{ return type; }
)
coordinates:(
value_separator quotation_mark "coordinates" quotation_mark
name_separator coordinates:geometry_coordinates
{ return coordinates; }
)
{ return { "type": type, "coordinates": coordinates }; }
)
end_object
end_object
{ return {"$geometry": JSON.parse(json) }; }
{ return { "$geometry": members }; }

geometry_point
= begin_object
quotation_mark "$geometry" quotation_mark name_separator
begin_object
geometry:(
type:(
quotation_mark "type" quotation_mark
name_separator quotation_mark type:"Point" quotation_mark
{ return type; }
)
coordinates:(
value_separator quotation_mark "coordinates" quotation_mark
name_separator coordinates:legacy_coordinates
{ return coordinates; }
)
{ return { "type": type, "coordinates": coordinates }; }
)
end_object
distance:(
value_separator quotation_mark operator:distance_operator quotation_mark
name_separator value:number_positive
{ return { [operator]: value }; }
)*
end_object
{
return {
"$geometry": geometry,
...(distance ? distance : {})
};
}

geometry_type
= "Polygon"
/ "MultiPolygon"

geometry_coordinates
= begin_array
values:(
// number or "recursive" geometry_coordinates
head:(number/geometry_coordinates) tail:(value_separator v:(number/geometry_coordinates) { return v; })*
{ return [head].concat(tail); }
)?
end_array

legacy_coordinates
= begin_array
number_longitude value_separator
number_latitude
end_array

legacy_shape
= center_shape
Expand All @@ -135,8 +210,8 @@ center_shape
= begin_object
quotation_mark center_operator:("$centerSphere" / "$center") quotation_mark name_separator
parameters:$(begin_array
begin_array
number value_separator number
begin_array
number value_separator number
end_array
value_separator
number
Expand All @@ -152,13 +227,13 @@ box_shape
= begin_object
quotation_mark "$box" quotation_mark name_separator
parameters:$(begin_array
begin_array
number value_separator number
begin_array
number value_separator number
end_array
value_separator
begin_array
number value_separator number
end_array
end_array
end_array)
end_object
{ return {"$box": JSON.parse(parameters)}; }
Expand All @@ -168,19 +243,18 @@ polygon_shape
= begin_object
quotation_mark "$polygon" quotation_mark name_separator
parameters:$(begin_array
head:(begin_array
number value_separator number
head:(begin_array
number value_separator number
end_array)
tail:(value_separator
begin_array
number value_separator number
end_array)*
end_array)*
end_array
{ return [head].concat(tail); })
end_object
{ return {"$polygon": JSON.parse(parameters)}; }


where_operator = "$where"

text_operator = "$text"
Expand Down Expand Up @@ -333,9 +407,9 @@ ejson_undefined

ejson_dbref
= begin_object
members:(
members:(
ref:(
quotation_mark "$ref" quotation_mark
quotation_mark "$ref" quotation_mark
name_separator string:string
{ return string; }
)
Expand All @@ -352,17 +426,17 @@ ejson_dbref
{
var result = {"$ref": ref, "$id": id};
if (db !== null) result["$db"] = db;
return result;
return result;
}
)
end_object
{ return members; }

ejson_regex
= begin_object
members:(
members:(
regex:(
quotation_mark "$regex" quotation_mark
quotation_mark "$regex" quotation_mark
name_separator string:string
{ return string; }
)
Expand All @@ -378,9 +452,9 @@ ejson_regex

ejson_binary
= begin_object
members:(
members:(
binary:(
quotation_mark "$binary" quotation_mark
quotation_mark "$binary" quotation_mark
name_separator string:string
{ return string; }
)
Expand Down Expand Up @@ -439,11 +513,47 @@ array
end_array
{ return values !== null ? values : []; }

array_number
= begin_array
values:(
head:number tail:(value_separator v:number { return v; })*
{ return [head].concat(tail); }
)?
end_array
{ return values !== null ? values : []; }

/* ----- 6. Numbers ----- */

number "number"
= minus? int frac? exp? { return parseFloat(text()); }

number_positive
= int frac? exp? { return parseFloat(text()); }

// A numeric value that represents a longitude coordinate (to any precision between -180.0 and 180.0, inclusive)
// Converted to PEG syntax from this regex: ^-?(180(\.0)?|(1[0-7]\d|[1-9]?\d)(\.(0|\d*[1-9]))?)$
// Taking into account PEG's greedy behaviour and lack of backtracking.
number_longitude
= minus? (
"180"(decimal_point zero)?
/ (
(("1" [0-7] DIGIT / digit1_9 DIGIT / DIGIT) decimal_point int*)
/ (("1" [0-7] DIGIT / digit1_9 DIGIT / DIGIT))
)
)

// A numeric value that represents a latitude coordinate (to any precision between -90.0 and 90.0, inclusive)
// Converted to PEG syntax from regex: ^-?(90(\.0)?|([1-8]?\d)(\.(0|\d*[1-9]))?)$
// Taking into account PEG's greedy behaviour and lack of backtracking.
number_latitude
= minus? (
"90"(decimal_point zero)?
/ (
((digit1_9 DIGIT / DIGIT) decimal_point int*)
/ ((digit1_9 DIGIT / DIGIT))
)
)

decimal_point = "."
digit1_9 = [1-9]
e = [eE]
Expand Down
Loading