Support a limited set of '.'-prefixed non-keyword symbols. (#352) r=nalexander
This commit allows `.` and `...` to parse correctly as `PlainSymbol`. Tests in edn, query-translator, and the top level have been added.
This commit is contained in:
parent
70b112801c
commit
85f3b79f75
4 changed files with 24 additions and 4 deletions
|
@ -152,14 +152,15 @@ symbol_char_initial = [a-z] / [A-Z] / [0-9] / [*!_?$%&=<>]
|
||||||
symbol_char_subsequent = [a-z] / [A-Z] / [0-9] / [-*!_?$%&=<>]
|
symbol_char_subsequent = [a-z] / [A-Z] / [0-9] / [-*!_?$%&=<>]
|
||||||
|
|
||||||
symbol_namespace = symbol_char_initial symbol_char_subsequent* (namespace_divider symbol_char_subsequent+)*
|
symbol_namespace = symbol_char_initial symbol_char_subsequent* (namespace_divider symbol_char_subsequent+)*
|
||||||
symbol_name = ( symbol_char_initial+ / "." ) ( symbol_char_subsequent* / "." )
|
symbol_name = ( symbol_char_initial+ symbol_char_subsequent* )
|
||||||
|
plain_symbol_name = symbol_name / "..." / "."
|
||||||
|
|
||||||
keyword_prefix = ":"
|
keyword_prefix = ":"
|
||||||
|
|
||||||
pub symbol -> ValueAndSpan =
|
pub symbol -> ValueAndSpan =
|
||||||
start:#position
|
start:#position
|
||||||
ns:( sns:$(symbol_namespace) namespace_separator { sns })?
|
ns:( sns:$(symbol_namespace) namespace_separator { sns })?
|
||||||
n:$(symbol_name)
|
n:$(plain_symbol_name)
|
||||||
end:#position {
|
end:#position {
|
||||||
ValueAndSpan {
|
ValueAndSpan {
|
||||||
inner: SpannedValue::from_symbol(ns, n),
|
inner: SpannedValue::from_symbol(ns, n),
|
||||||
|
|
|
@ -313,6 +313,7 @@ fn test_span_text() {
|
||||||
fn test_symbol() {
|
fn test_symbol() {
|
||||||
assert_eq!(symbol("$").unwrap(), s_plain("$"));
|
assert_eq!(symbol("$").unwrap(), s_plain("$"));
|
||||||
assert_eq!(symbol(".").unwrap(), s_plain("."));
|
assert_eq!(symbol(".").unwrap(), s_plain("."));
|
||||||
|
assert_eq!(symbol("...").unwrap(), s_plain("..."));
|
||||||
|
|
||||||
assert_eq!(symbol("hello/world").unwrap(), s_ns("hello", "world"));
|
assert_eq!(symbol("hello/world").unwrap(), s_ns("hello", "world"));
|
||||||
assert_eq!(symbol("foo-bar/baz-boz").unwrap(), s_ns("foo-bar", "baz-boz"));
|
assert_eq!(symbol("foo-bar/baz-boz").unwrap(), s_ns("foo-bar", "baz-boz"));
|
||||||
|
|
|
@ -42,7 +42,6 @@ fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "parse failed")]
|
|
||||||
fn test_coll() {
|
fn test_coll() {
|
||||||
let mut schema = Schema::default();
|
let mut schema = Schema::default();
|
||||||
associate_ident(&mut schema, NamespacedKeyword::new("foo", "bar"), 99);
|
associate_ident(&mut schema, NamespacedKeyword::new("foo", "bar"), 99);
|
||||||
|
|
|
@ -137,6 +137,25 @@ fn test_tuple() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_coll() {
|
fn test_coll() {
|
||||||
// We can't test Coll yet, because the EDN parser is incomplete.
|
let mut c = new_connection("").expect("Couldn't open conn.");
|
||||||
|
let db = mentat_db::db::ensure_current_version(&mut c).expect("Couldn't open DB.");
|
||||||
|
|
||||||
|
// Coll.
|
||||||
|
let start = time::PreciseTime::now();
|
||||||
|
let results = q_once(&c, &db.schema,
|
||||||
|
"[:find [?e ...] :where [?e :db/ident _]]", None)
|
||||||
|
.expect("Query failed");
|
||||||
|
let end = time::PreciseTime::now();
|
||||||
|
|
||||||
|
assert_eq!(37, results.len());
|
||||||
|
|
||||||
|
if let QueryResults::Coll(ref coll) = results {
|
||||||
|
assert!(coll.iter().all(|item| item.matches_type(ValueType::Ref)));
|
||||||
|
} else {
|
||||||
|
panic!("Expected coll.");
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:?}", results);
|
||||||
|
println!("Coll took {}µs", start.to(end).num_microseconds().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue