difftreelog
feat(parser) serializable AST
in: master
3 files changed
crates/jsonnet-parser/Cargo.tomldiffbeforeafterboth8default = []8default = []9# Trace peg token parsing9# Trace peg token parsing10trace = ["peg/trace"]10trace = ["peg/trace"]11# TODO:12# serialize = ["serde"]111312[dependencies]14[dependencies]13peg = "0.6.2"15peg = "0.6.2"16serde = { version = "1.0.111", features = ["derive", "rc"] }141715[dev-dependencies]18[dev-dependencies]16jsonnet-stdlib = { version = "0.1.0", path = "../jsonnet-stdlib" }19jsonnet-stdlib = { version = "0.1.0", path = "../jsonnet-stdlib" }20bincode = "1.2.1"1721crates/jsonnet-parser/src/expr.rsdiffbeforeafterboth1use serde::{Deserialize, Serialize};1use std::{fmt::Debug, rc::Rc};2use std::{fmt::Debug, rc::Rc};233#[derive(Debug, Clone, PartialEq)]4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]4pub enum FieldName {5pub enum FieldName {5 /// {fixed: 2}6 /// {fixed: 2}6 Fixed(String),7 Fixed(String),7 /// {["dyn"+"amic"]: 3}8 /// {["dyn"+"amic"]: 3}8 Dyn(LocExpr),9 Dyn(LocExpr),9}10}101111#[derive(Debug, Clone, PartialEq)]12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]12pub enum Visibility {13pub enum Visibility {13 /// :14 /// :14 Normal,15 Normal,18 Unhide,19 Unhide,19}20}202121#[derive(Debug, Clone, PartialEq)]22#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]22pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);23pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);232424#[derive(Debug, Clone, PartialEq)]25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]25pub struct FieldMember {26pub struct FieldMember {26 pub name: FieldName,27 pub name: FieldName,27 pub plus: bool,28 pub plus: bool,30 pub value: LocExpr,31 pub value: LocExpr,31}32}323333#[derive(Debug, Clone, PartialEq)]34#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]34pub enum Member {35pub enum Member {35 Field(FieldMember),36 Field(FieldMember),36 BindStmt(BindSpec),37 BindStmt(BindSpec),37 AssertStmt(AssertStmt),38 AssertStmt(AssertStmt),38}39}394040#[derive(Debug, Clone, Copy, PartialEq)]41#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]41pub enum UnaryOpType {42pub enum UnaryOpType {42 Plus,43 Plus,43 Minus,44 Minus,44 BitNot,45 BitNot,45 Not,46 Not,46}47}474848#[derive(Debug, Clone, Copy, PartialEq)]49#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]49pub enum BinaryOpType {50pub enum BinaryOpType {50 Mul,51 Mul,51 Div,52 Div,76}77}777878/// name, default value79/// name, default value79#[derive(Debug, Clone, PartialEq)]80#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]80pub struct Param(pub String, pub Option<LocExpr>);81pub struct Param(pub String, pub Option<LocExpr>);81/// Defined function parameters82/// Defined function parameters82#[derive(Debug, Clone, PartialEq)]83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]83pub struct ParamsDesc(pub Vec<Param>);84pub struct ParamsDesc(pub Vec<Param>);84impl ParamsDesc {85impl ParamsDesc {85 pub fn with_defaults(&self) -> Vec<Param> {86 pub fn with_defaults(&self) -> Vec<Param> {86 self.0.iter().filter(|e| e.1.is_some()).cloned().collect()87 self.0.iter().filter(|e| e.1.is_some()).cloned().collect()87 }88 }88}89}899090#[derive(Debug, Clone, PartialEq)]91#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]91pub struct Arg(pub Option<String>, pub LocExpr);92pub struct Arg(pub Option<String>, pub LocExpr);92#[derive(Debug, Clone, PartialEq)]93#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]93pub struct ArgsDesc(pub Vec<Arg>);94pub struct ArgsDesc(pub Vec<Arg>);949595#[derive(Debug, Clone, PartialEq)]96#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]96pub struct BindSpec {97pub struct BindSpec {97 pub name: String,98 pub name: String,98 pub params: Option<ParamsDesc>,99 pub params: Option<ParamsDesc>,99 pub value: LocExpr,100 pub value: LocExpr,100}101}101102102#[derive(Debug, Clone, PartialEq)]103#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]103pub struct IfSpecData(pub LocExpr);104pub struct IfSpecData(pub LocExpr);104#[derive(Debug, Clone, PartialEq)]105#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]105pub struct ForSpecData(pub String, pub LocExpr);106pub struct ForSpecData(pub String, pub LocExpr);106107107#[derive(Debug, Clone, PartialEq)]108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]108pub enum CompSpec {109pub enum CompSpec {109 IfSpec(IfSpecData),110 IfSpec(IfSpecData),110 ForSpec(ForSpecData),111 ForSpec(ForSpecData),111}112}112113113#[derive(Debug, Clone, PartialEq)]114#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]114pub enum ObjBody {115pub enum ObjBody {115 MemberList(Vec<Member>),116 MemberList(Vec<Member>),116 ObjComp {117 ObjComp {123 },124 },124}125}125126126#[derive(Debug, Clone, PartialEq)]127#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]127pub enum LiteralType {128pub enum LiteralType {128 This,129 This,129 Super,130 Super,133 False,134 False,134}135}135136136#[derive(Debug, Clone, PartialEq)]137#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]137pub struct SliceDesc {138pub struct SliceDesc {138 pub start: Option<LocExpr>,139 pub start: Option<LocExpr>,139 pub end: Option<LocExpr>,140 pub end: Option<LocExpr>,140 pub step: Option<LocExpr>,141 pub step: Option<LocExpr>,141}142}142143143/// Syntax base144/// Syntax base144#[derive(Debug, Clone, PartialEq)]145#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]145pub enum Expr {146pub enum Expr {146 Literal(LiteralType),147 Literal(LiteralType),147148222}223}223224224/// file, begin offset, end offset225/// file, begin offset, end offset225#[derive(Clone, PartialEq)]226#[derive(Clone, PartialEq, Serialize, Deserialize)]226pub struct ExprLocation(pub String, pub usize, pub usize);227pub struct ExprLocation(pub String, pub usize, pub usize);227impl Debug for ExprLocation {228impl Debug for ExprLocation {228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {229 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {231}232}232233233/// Holds AST expression and its location in source file+234/// Holds AST expression and its location in source file+234#[derive(Clone, PartialEq)]235#[derive(Clone, PartialEq, Serialize, Deserialize)]235pub struct LocExpr(pub Rc<Expr>, pub Option<Rc<ExprLocation>>);236pub struct LocExpr(pub Rc<Expr>, pub Option<Rc<ExprLocation>>);236impl Debug for LocExpr {237impl Debug for LocExpr {237 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {238 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {crates/jsonnet-parser/src/lib.rsdiffbeforeafterboth1#![feature(box_syntax)]1#![feature(box_syntax)]2#![feature(test)]34extern crate test;253use peg::parser;6use peg::parser;4use std::rc::Rc;7use std::rc::Rc;434644 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 expression45 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>) -> LocExpr51 = start:position!() v:x() end:position!() {loc_expr!(v, s.loc_data, (s.file_name.clone(), start, end))}465276 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::AssertStmt83 = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }77 pub rule string() -> String84 pub rule string() -> String78 = "\"" 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::FieldName81 = 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}246264247// TODO: impl FromStr from Expr248pub 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 }481482 use test::Bencher;483484 // From source code485 #[bench]486 fn bench_parse_peg(b: &mut Bencher) {487 b.iter(|| parse!(jsonnet_stdlib::STDLIB_STR))488 }489490 // From serialized blob491 #[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