git.delta.rocks / jrsonnet / refs/commits / 0444432f3e21

difftreelog

feat(parser) serializable AST

Лач2020-06-04parent: #3302a3d.patch.diff
in: master

3 files changed

modifiedcrates/jsonnet-parser/Cargo.tomldiffbeforeafterboth
--- a/crates/jsonnet-parser/Cargo.toml
+++ b/crates/jsonnet-parser/Cargo.toml
@@ -8,9 +8,13 @@
 default = []
 # Trace peg token parsing
 trace = ["peg/trace"]
+# TODO:
+# serialize = ["serde"]
 
 [dependencies]
 peg = "0.6.2"
+serde = { version = "1.0.111", features = ["derive", "rc"] }
 
 [dev-dependencies]
 jsonnet-stdlib = { version = "0.1.0", path = "../jsonnet-stdlib" }
+bincode = "1.2.1"
modifiedcrates/jsonnet-parser/src/expr.rsdiffbeforeafterboth
--- a/crates/jsonnet-parser/src/expr.rs
+++ b/crates/jsonnet-parser/src/expr.rs
@@ -1,6 +1,7 @@
+use serde::{Deserialize, Serialize};
 use std::{fmt::Debug, rc::Rc};
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum FieldName {
 	/// {fixed: 2}
 	Fixed(String),
@@ -8,7 +9,7 @@
 	Dyn(LocExpr),
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum Visibility {
 	/// :
 	Normal,
@@ -18,10 +19,10 @@
 	Unhide,
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct FieldMember {
 	pub name: FieldName,
 	pub plus: bool,
@@ -30,14 +31,14 @@
 	pub value: LocExpr,
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum Member {
 	Field(FieldMember),
 	BindStmt(BindSpec),
 	AssertStmt(AssertStmt),
 }
 
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
 pub enum UnaryOpType {
 	Plus,
 	Minus,
@@ -45,7 +46,7 @@
 	Not,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
 pub enum BinaryOpType {
 	Mul,
 	Div,
@@ -76,10 +77,10 @@
 }
 
 /// name, default value
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct Param(pub String, pub Option<LocExpr>);
 /// Defined function parameters
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct ParamsDesc(pub Vec<Param>);
 impl ParamsDesc {
 	pub fn with_defaults(&self) -> Vec<Param> {
@@ -87,30 +88,30 @@
 	}
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct Arg(pub Option<String>, pub LocExpr);
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct ArgsDesc(pub Vec<Arg>);
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct BindSpec {
 	pub name: String,
 	pub params: Option<ParamsDesc>,
 	pub value: LocExpr,
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct IfSpecData(pub LocExpr);
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct ForSpecData(pub String, pub LocExpr);
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum CompSpec {
 	IfSpec(IfSpecData),
 	ForSpec(ForSpecData),
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum ObjBody {
 	MemberList(Vec<Member>),
 	ObjComp {
@@ -123,7 +124,7 @@
 	},
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum LiteralType {
 	This,
 	Super,
@@ -133,7 +134,7 @@
 	False,
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct SliceDesc {
 	pub start: Option<LocExpr>,
 	pub end: Option<LocExpr>,
@@ -141,7 +142,7 @@
 }
 
 /// Syntax base
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum Expr {
 	Literal(LiteralType),
 
@@ -222,7 +223,7 @@
 }
 
 /// file, begin offset, end offset
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Serialize, Deserialize)]
 pub struct ExprLocation(pub String, pub usize, pub usize);
 impl Debug for ExprLocation {
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -231,7 +232,7 @@
 }
 
 /// Holds AST expression and its location in source file+
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Serialize, Deserialize)]
 pub struct LocExpr(pub Rc<Expr>, pub Option<Rc<ExprLocation>>);
 impl Debug for LocExpr {
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -242,7 +243,7 @@
 /// Creates LocExpr from Expr and ExprLocation components
 #[macro_export]
 macro_rules! loc_expr {
-	($expr:expr, $need_loc:expr, ($name:expr, $start:expr, $end:expr)) => {
+	($expr:expr, $need_loc:expr,($name:expr, $start:expr, $end:expr)) => {
 		LocExpr(
 			std::rc::Rc::new($expr),
 			if $need_loc {
modifiedcrates/jsonnet-parser/src/lib.rsdiffbeforeafterboth
1#![feature(box_syntax)]1#![feature(box_syntax)]
2#![feature(test)]
3
4extern crate test;
25
3use peg::parser;6use peg::parser;
4use std::rc::Rc;7use std::rc::Rc;
4346
44 rule keyword(id: &'static str) = ##parse_string_literal(id) end_of_ident()47 rule keyword(id: &'static str)
48 = ##parse_string_literal(id) end_of_ident()
49 // Adds location data information to existing expression
45 rule l(s: &ParserSettings, x: rule<Expr>) -> LocExpr = start:position!() v:x() end:position!() {loc_expr!(v, s.loc_data, (s.file_name.clone(), start, end))}50 rule l(s: &ParserSettings, x: rule<Expr>) -> LocExpr
51 = start:position!() v:x() end:position!() {loc_expr!(v, s.loc_data, (s.file_name.clone(), start, end))}
4652
76 pub rule assertion(s: &ParserSettings) -> expr::AssertStmt = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }82 pub rule assertion(s: &ParserSettings) -> expr::AssertStmt
83 = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }
77 pub rule string() -> String84 pub rule string() -> String
78 = "\"" str:$(("\\\"" / !['"'][_])*) "\"" {str.to_owned()}85 = v:("\"" str:$(("\\\"" / !['"'][_])*) "\"" {str.to_owned()}
79 / "'" str:$((!['\''][_])*) "'" {str.to_owned()}86 / "'" str:$((!['\''][_])*) "'" {str.to_owned()}) {v.replace("\\n", "\n")}
80 pub rule field_name(s: &ParserSettings) -> expr::FieldName87 pub rule field_name(s: &ParserSettings) -> expr::FieldName
81 = name:id() {expr::FieldName::Fixed(name)}88 = name:id() {expr::FieldName::Fixed(name)}
82 / name:string() {expr::FieldName::Fixed(name)}89 / name:string() {expr::FieldName::Fixed(name)}
244 }262 }
245}263}
246264
247// TODO: impl FromStr from Expr
248pub fn parse(265pub fn parse(
249 str: &str,266 str: &str,
250 settings: &ParserSettings,267 settings: &ParserSettings,
462 parse!(jsonnet_stdlib::STDLIB_STR);479 parse!(jsonnet_stdlib::STDLIB_STR);
463 }480 }
481
482 use test::Bencher;
483
484 // From source code
485 #[bench]
486 fn bench_parse_peg(b: &mut Bencher) {
487 b.iter(|| parse!(jsonnet_stdlib::STDLIB_STR))
488 }
489
490 // From serialized blob
491 #[bench]
492 fn bench_parse_serde_bincode(b: &mut Bencher) {
493 let serialized = bincode::serialize(&parse!(jsonnet_stdlib::STDLIB_STR)).unwrap();
494 b.iter(|| bincode::deserialize::<LocExpr>(&serialized))
495 }
464}496}
465497