From d3c0914cf149c7cbc178ff0f5a42c5a1f6e149a2 Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Mon, 5 Mar 2018 16:24:04 -0800 Subject: [PATCH] Clean up duplicate position tracking code. This turns out to have little performance impact, but makes the grammar much cleaner. --- edn/src/edn.rustpeg | 198 ++++++++++---------------------------------- 1 file changed, 46 insertions(+), 152 deletions(-) diff --git a/edn/src/edn.rustpeg b/edn/src/edn.rustpeg index 3848a0fa..15603f10 100644 --- a/edn/src/edn.rustpeg +++ b/edn/src/edn.rustpeg @@ -34,43 +34,15 @@ use types::{SpannedValue, Span, ValueAndSpan}; // TODO: Support tagged elements // TODO: Support discard -pub nil -> ValueAndSpan = - start:#position "nil" end:#position { - ValueAndSpan { - inner: SpannedValue::Nil, - span: Span::new(start, end) - } - } +nil -> SpannedValue = "nil" { SpannedValue::Nil } +nan -> SpannedValue = "#f" whitespace+ "NaN" { SpannedValue::Float(OrderedFloat(NAN)) } -pub nan -> ValueAndSpan = - start:#position "#f" whitespace+ "NaN" end:#position { - ValueAndSpan { - inner: SpannedValue::Float(OrderedFloat(NAN)), - span: Span::new(start, end) - } - } +infinity -> SpannedValue = "#f" whitespace+ s:$(sign) "Infinity" + { SpannedValue::Float(OrderedFloat(if s == "+" { INFINITY } else { NEG_INFINITY })) } -pub infinity -> ValueAndSpan = - start:#position "#f" whitespace+ s:$(sign) "Infinity" end:#position { - ValueAndSpan { - inner: SpannedValue::Float(OrderedFloat(if s == "+" { INFINITY } else { NEG_INFINITY })), - span: Span::new(start, end) - } - } - -pub boolean -> ValueAndSpan = - start:#position "true" end:#position { - ValueAndSpan { - inner: SpannedValue::Boolean(true), - span: Span::new(start, end) - } - } / - start:#position "false" end:#position { - ValueAndSpan { - inner: SpannedValue::Boolean(false), - span: Span::new(start, end) - } - } +boolean -> SpannedValue + = "true" { SpannedValue::Boolean(true) } + / "false" { SpannedValue::Boolean(false) } digit = [0-9] alphanumeric = [0-9a-zA-Z] @@ -79,54 +51,21 @@ validbase = [3][0-6] / [12][0-9] / [2-9] hex = [0-9a-fA-F] sign = [+-] -pub bigint -> ValueAndSpan = - start:#position b:$( sign? digit+ ) "N" end:#position { - ValueAndSpan { - inner: SpannedValue::BigInteger(b.parse::().unwrap()), - span: Span::new(start, end) - } - } +bigint -> SpannedValue = b:$( sign? digit+ ) "N" + { SpannedValue::BigInteger(b.parse::().unwrap()) } +octalinteger -> SpannedValue = "0" i:$( octaldigit+ ) + { SpannedValue::Integer(i64::from_str_radix(i, 8).unwrap()) } +hexinteger -> SpannedValue = "0x" i:$( hex+ ) + { SpannedValue::Integer(i64::from_str_radix(i, 16).unwrap()) } -pub octalinteger -> ValueAndSpan = - start:#position "0" i:$( octaldigit+ ) end:#position { - ValueAndSpan { - inner: SpannedValue::Integer(i64::from_str_radix(i, 8).unwrap()), - span: Span::new(start, end) - } - } +basedinteger -> SpannedValue = b:$( validbase ) "r" i:$( alphanumeric+ ) + { SpannedValue::Integer(i64::from_str_radix(i, b.parse::().unwrap()).unwrap()) } -pub hexinteger -> ValueAndSpan = - start:#position "0x" i:$( hex+ ) end:#position { - ValueAndSpan { - inner: SpannedValue::Integer(i64::from_str_radix(i, 16).unwrap()), - span: Span::new(start, end) - } - } +integer -> SpannedValue = i:$( sign? digit+ ) + { SpannedValue::Integer(i.parse::().unwrap()) } -pub basedinteger -> ValueAndSpan = - // Only allow values 2-36 - start:#position b:$( validbase ) "r" i:$( alphanumeric+ ) end:#position { - ValueAndSpan { - inner: SpannedValue::Integer(i64::from_str_radix(i, b.parse::().unwrap()).unwrap()), - span: Span::new(start, end) - } - } - -pub integer -> ValueAndSpan = - start:#position i:$( sign? digit+ ) end:#position { - ValueAndSpan { - inner: SpannedValue::Integer(i.parse::().unwrap()), - span: Span::new(start, end) - } - } - -pub float -> ValueAndSpan = - start:#position f:$(sign? digit+ ("." digit+)? (("e" / "E") sign? digit+)?) end:#position { - ValueAndSpan { - inner: SpannedValue::Float(OrderedFloat(f.parse::().unwrap())), - span: Span::new(start, end) - } - } +float -> SpannedValue = f:$(sign? digit+ ("." digit+)? (("e" / "E") sign? digit+)?) + { SpannedValue::Float(OrderedFloat(f.parse::().unwrap())) } // TODO: \newline, \return, \space and \tab special_char = quote / tab @@ -134,19 +73,13 @@ quote = "\\\"" tab = "\\tab" char = [^"] / special_char -pub text -> ValueAndSpan = - start:#position "\"" t:$( char* ) "\"" end:#position { - ValueAndSpan { - inner: SpannedValue::Text(t.to_string()), - span: Span::new(start, end) - } - } - +text -> SpannedValue = "\"" t:$( char* ) "\"" + { SpannedValue::Text(t.to_string()) } // RFC 3339 timestamps. #inst "1985-04-12T23:20:50.52Z" // We accept an arbitrary depth of decimals. // Note that we discard the timezone information -- all times are translated to UTC. -pub inst_string -> DateTime = +inst_string -> DateTime = "#inst" whitespace+ "\"" d:$( [0-9]*<4> "-" [0-2][0-9] "-" [0-3][0-9] "T" [0-2][0-9] ":" [0-5][0-9] ":" [0-6][0-9] @@ -159,7 +92,7 @@ pub inst_string -> DateTime = .map_err(|_| "invalid datetime") // Oh, rustpeg. } -pub inst_micros -> DateTime = +inst_micros -> DateTime = "#instmicros" whitespace+ d:$( digit+ ) { let micros = d.parse::().unwrap(); let seconds: i64 = micros / 1000000; @@ -167,7 +100,7 @@ pub inst_micros -> DateTime = Utc.timestamp(seconds, nanos) } -pub inst_millis -> DateTime = +inst_millis -> DateTime = "#instmillis" whitespace+ d:$( digit+ ) { let millis = d.parse::().unwrap(); let seconds: i64 = millis / 1000; @@ -175,26 +108,16 @@ pub inst_millis -> DateTime = Utc.timestamp(seconds, nanos) } -pub inst -> ValueAndSpan = - start:#position t:(inst_millis / inst_micros / inst_string) end:#position { - ValueAndSpan { - inner: SpannedValue::Instant(t), - span: Span::new(start, end) - } - } +inst -> SpannedValue = t:(inst_millis / inst_micros / inst_string) + { SpannedValue::Instant(t) } -pub uuid_string -> Uuid = +uuid_string -> Uuid = "\"" u:$( [a-f0-9]*<8> "-" [a-f0-9]*<4> "-" [a-f0-9]*<4> "-" [a-f0-9]*<4> "-" [a-f0-9]*<12> ) "\"" { Uuid::parse_str(u).expect("this is a valid UUID string") } -pub uuid -> ValueAndSpan = - start:#position "#uuid" whitespace+ u:(uuid_string) end:#position { - ValueAndSpan { - inner: SpannedValue::Uuid(u), - span: Span::new(start, end) - } - } +uuid -> SpannedValue = "#uuid" whitespace+ u:uuid_string + { SpannedValue::Uuid(u) } namespace_divider = "." namespace_separator = "/" @@ -211,71 +134,42 @@ plain_symbol_name = symbol_name / "..." / "." keyword_prefix = ":" -pub symbol -> ValueAndSpan = - start:#position +symbol -> SpannedValue = ns:( sns:$(symbol_namespace) namespace_separator { sns })? n:$(plain_symbol_name) - end:#position { - ValueAndSpan { - inner: SpannedValue::from_symbol(ns, n), - span: Span::new(start, end) - } - } + { SpannedValue::from_symbol(ns, n) } -pub keyword -> ValueAndSpan = - start:#position +keyword -> SpannedValue = keyword_prefix ns:( sns:$(symbol_namespace) namespace_separator { sns })? n:$(symbol_name) - end:#position { - ValueAndSpan { - inner: SpannedValue::from_keyword(ns, n), - span: Span::new(start, end) - } - } + { SpannedValue::from_keyword(ns, n) } -pub list -> ValueAndSpan = - start:#position "(" __ v:(value)* __ ")" end:#position { - ValueAndSpan { - inner: SpannedValue::List(LinkedList::from_iter(v)), - span: Span::new(start, end) - } - } +list -> SpannedValue = "(" __ v:(value)* __ ")" + { SpannedValue::List(LinkedList::from_iter(v)) } -pub vector -> ValueAndSpan = - start:#position "[" __ v:(value)* __ "]" end:#position { - ValueAndSpan { - inner: SpannedValue::Vector(v), - span: Span::new(start, end) - } - } +vector -> SpannedValue = "[" __ v:(value)* __ "]" + { SpannedValue::Vector(v) } -pub set -> ValueAndSpan = - start:#position "#{" __ v:(value)* __ "}" end:#position { - ValueAndSpan { - inner: SpannedValue::Set(BTreeSet::from_iter(v)), - span: Span::new(start, end) - } - } +set -> SpannedValue = "#{" __ v:(value)* __ "}" + { SpannedValue::Set(BTreeSet::from_iter(v)) } pair -> (ValueAndSpan, ValueAndSpan) = k:(value) v:(value) { (k, v) } -pub map -> ValueAndSpan = - start:#position "{" __ v:(pair)* __ "}" end:#position { - ValueAndSpan { - inner: SpannedValue::Map(BTreeMap::from_iter(v)), - span: Span::new(start, end) - } - } +map -> SpannedValue = "{" __ v:(pair)* __ "}" + { SpannedValue::Map(BTreeMap::from_iter(v)) } // It's important that float comes before integer or the parser assumes that // floats are integers and fails to parse pub value -> ValueAndSpan = - __ v:(nil / nan / infinity / boolean / float / octalinteger / hexinteger / basedinteger / inst / uuid / bigint / integer / text / keyword / symbol / list / vector / map / set) __ { - v + __ start:#position v:(nil / nan / infinity / boolean / float / octalinteger / hexinteger / basedinteger / inst / uuid / bigint / integer / text / keyword / symbol / list / vector / map / set) end:#position __ { + ValueAndSpan { + inner: v, + span: Span::new(start, end) + } } // Clojure (and thus EDN) regards commas as whitespace, and thus the two-element vectors [1 2] and