git.delta.rocks / jrsonnet / refs/commits / b99878e17f6e

difftreelog

fix(parser) move suffixes to expr_basic, function parsing BREAKING CHANGE: Renamed: Args => ArgsDesc Params => ParamsDesc

Лач2020-05-16parent: #9b267d5.patch.diff
in: master

2 files changed

modifiedcrates/jsonnet-parser/src/expr.rsdiffbeforeafterboth
29 },29 },
30 Function {30 Function {
31 name: FieldName,31 name: FieldName,
32 params: Params,32 params: ParamsDesc,
33 visibility: Visibility,33 visibility: Visibility,
34 value: Expr,34 value: Expr,
35 },35 },
7474
75 BitAnd,75 BitAnd,
76 BitOr,76 BitOr,
77 BitXor,
78
77 And,79 And,
78 Or,80 Or,
79
80 BitXor,
81}81}
8282
83#[derive(Debug, Clone, PartialEq)]83#[derive(Debug, Clone, PartialEq)]
87}87}
8888
89#[derive(Debug, Clone, PartialEq)]89#[derive(Debug, Clone, PartialEq)]
90pub struct Params(pub Vec<Param>);90pub struct ParamsDesc(pub Vec<Param>);
9191
92#[derive(Debug, Clone, PartialEq)]92#[derive(Debug, Clone, PartialEq)]
93pub enum Arg {93pub enum Arg {
96}96}
9797
98#[derive(Debug, Clone, PartialEq)]98#[derive(Debug, Clone, PartialEq)]
99pub struct Args(pub Vec<Arg>);99pub struct ArgsDesc(pub Vec<Arg>);
100100
101#[derive(Debug, Clone, PartialEq)]101#[derive(Debug, Clone, PartialEq)]
102pub enum Bind {102pub enum Bind {
103 Value(String, Box<Expr>),103 Value(String, Box<Expr>),
104 Function(String, Params, Box<Expr>),104 Function(String, ParamsDesc, Box<Expr>),
105}105}
106106
107#[derive(Debug, Clone, PartialEq)]107#[derive(Debug, Clone, PartialEq)]
179 /// (obj)179 /// (obj)
180 Parened(Box<Expr>),180 Parened(Box<Expr>),
181181
182 Params(Params),182 Params(ParamsDesc),
183 Args(Args),183 Args(ArgsDesc),
184184
185 UnaryOp(UnaryOpType, Box<Expr>),185 UnaryOp(UnaryOpType, Box<Expr>),
186 BinaryOp(Box<Expr>, BinaryOpType, Box<Expr>),186 BinaryOp(Box<Expr>, BinaryOpType, Box<Expr>),
191 Import(String),191 Import(String),
192 ImportStr(String),192 ImportStr(String),
193 Error(Box<Expr>),193 Error(Box<Expr>),
194 Apply(Box<Expr>, Args),194 Apply(Box<Expr>, ArgsDesc),
195 Select(Box<Expr>, String),195 Select(Box<Expr>, String),
196 Index(Box<Expr>, Box<Expr>),196 Index(Box<Expr>, Box<Expr>),
197 Slice {197 Slice {
200 end: Option<Box<Expr>>,200 end: Option<Box<Expr>>,
201 step: Option<Box<Expr>>,201 step: Option<Box<Expr>>,
202 },202 },
203 Function(Params, Box<Expr>),203 Function(ParamsDesc, Box<Expr>),
204 IfElse {204 IfElse {
205 cond: IfSpec,205 cond: IfSpec,
206 cond_then: Box<Expr>,206 cond_then: Box<Expr>,
modifiedcrates/jsonnet-parser/src/lib.rsdiffbeforeafterboth
1#![feature(box_syntax)]
2
1use peg::parser;3use peg::parser;
24
6enum Suffix {8enum Suffix {
7 String(String),9 String(String),
8 Expression(Expr),10 Expression(Expr),
9 Apply(expr::Args),11 Apply(expr::ArgsDesc),
10}12}
1113
12parser! {14parser! {
18 rule digit() -> char = d:$(['0'..='9']) {d.chars().nth(0).unwrap()}20 rule digit() -> char = d:$(['0'..='9']) {d.chars().nth(0).unwrap()}
19 rule int() -> u32 = a:$(digit()+) { a.parse().unwrap() }21 rule int() -> u32 = a:$(digit()+) { a.parse().unwrap() }
20 rule number() -> f64 = quiet!{a:$((['-'|'+'])? int() ("." int())? (['e'|'E'] (s:['+'|'-'])? int())?) { a.parse().unwrap() }} / expected!("<number>")22 rule number() -> f64 = quiet!{a:$((['-'|'+'])? int() ("." int())? (['e'|'E'] (s:['+'|'-'])? int())?) { a.parse().unwrap() }} / expected!("<number>")
21 rule id() -> String = quiet!{ !("local" / "super" / "self" / "true" / "false" / "null" / "$" / "if" / "then" / "else") s:$(alpha() (alpha() / digit())*) {s.to_owned()}} / expected!("<identifier>")23 rule id() -> String = quiet!{ !("local" / "super" / "self" / "true" / "false" / "null" / "$" / "if" / "then" / "else" / "function") s:$(alpha() (alpha() / digit())*) {s.to_owned()}} / expected!("<identifier>")
2224
23 pub rule positional_param() -> expr::Param = name:id() {expr::Param::Positional(name)}25 pub rule positional_param() -> expr::Param = name:id() {expr::Param::Positional(name)}
24 pub rule named_param() -> expr::Param = name:id() __() "=" __() expr:boxed_expr() {expr::Param::Named(name, expr)}26 pub rule named_param() -> expr::Param = name:id() __() "=" __() expr:boxed_expr() {expr::Param::Named(name, expr)}
25 pub rule params() -> expr::Params27 pub rule params() -> expr::ParamsDesc
26 = positionals:(positional_param() ** delimiter()) delimiter() named:(named_param() ** delimiter()) {28 = positionals:(positional_param() ** delimiter()) named: (delimiter() named:(named_param() ** delimiter()) {named})? {
29 if named.is_some() {
27 expr::Params([&positionals[..], &named[..]].concat())30 expr::ParamsDesc([&positionals[..], &named.unwrap()[..]].concat())
28 }31 } else {
29 / named:(named_param() ** delimiter()) {expr::Params(named)}32 expr::ParamsDesc(positionals)
33 }
34 }
30 / positionals:(positional_param() ** delimiter()) {expr::Params(positionals)}35 / named:(named_param() ** delimiter()) {expr::ParamsDesc(named)}
31 / {expr::Params(Vec::new())}36 / {expr::ParamsDesc(Vec::new())}
3237
33 pub rule positional_arg() -> expr::Arg = quiet!{name:boxed_expr() {expr::Arg::Positional(name)}}/expected!("<positional arg>")38 pub rule positional_arg() -> expr::Arg = quiet!{name:boxed_expr() {expr::Arg::Positional(name)}}/expected!("<positional arg>")
34 pub rule named_arg() -> expr::Arg = quiet!{name:id() __() "=" __() expr:boxed_expr() {expr::Arg::Named(name, expr)}}/expected!("<named arg>")39 pub rule named_arg() -> expr::Arg = quiet!{name:id() __() "=" __() expr:boxed_expr() {expr::Arg::Named(name, expr)}}/expected!("<named arg>")
35 pub rule args() -> expr::Args40 pub rule args() -> expr::ArgsDesc
36 = positionals:(positional_arg() ** delimiter()) delimiter() named:(named_arg() ** delimiter()) {41 = positionals:(positional_arg() ** delimiter()) named: (delimiter() named:(named_arg() ** delimiter()) {named})? {
42 if named.is_some() {
37 expr::Args([&positionals[..], &named[..]].concat())43 expr::ArgsDesc([&positionals[..], &named.unwrap()[..]].concat())
38 }44 } else {
39 / named:(named_arg() ** delimiter()) {expr::Args(named)}45 expr::ArgsDesc(positionals)
46 }
47 }
40 / positionals:(positional_arg() ** delimiter()) {expr::Args(positionals)}48 / named:(named_arg() ** delimiter()) {expr::ArgsDesc(named)}
41 / {expr::Args(Vec::new())}49 / {expr::ArgsDesc(Vec::new())}
4250
43 pub rule bind() -> expr::Bind51 pub rule bind() -> expr::Bind
44 = name:id() __() "=" __() expr:boxed_expr() {expr::Bind::Value(name, expr)}52 = name:id() __() "=" __() expr:boxed_expr() {expr::Bind::Value(name, expr)}
118 / if_then_else_expr()126 / if_then_else_expr()
119 / local_expr()127 / local_expr()
128
129 / "function" __() "(" __() params:params() __() ")" __() expr:boxed_expr() {Expr::Function(params, expr)}
130
131 rule expr_basic_with_suffix() -> Expr
132 = a:expr_basic() suffixes:(__() suffix:expr_suffix() {suffix})* {
133 let mut cur = a;
134 for suffix in suffixes {
135 match suffix {
136 Suffix::String(index) => {
137 cur = Expr::Index(Box::new(cur), Box::new(Expr::Str(index)))
138 },
139 Suffix::Expression(index) => {
140 cur = Expr::Index(Box::new(cur), Box::new(index))
141 },
142 Suffix::Apply(args) => {
143 cur = Expr::Apply(Box::new(cur), args)
144 }
145 }
146 }
147 cur
148 }
120149
121 rule expr_suffix() -> Suffix150 rule expr_suffix() -> Suffix
122 = "." __() s:id() { Suffix::String(s) }151 = "." __() s:id() { Suffix::String(s) }
153 a:(@) __() "/" __() b:@ {Expr::BinaryOp(Box::new(a), expr::BinaryOpType::Div, Box::new(b))}182 a:(@) __() "/" __() b:@ {Expr::BinaryOp(Box::new(a), expr::BinaryOpType::Div, Box::new(b))}
154 a:(@) __() "%" __() b:@ {Expr::BinaryOp(Box::new(a), expr::BinaryOpType::Mod, Box::new(b))}183 a:(@) __() "%" __() b:@ {Expr::BinaryOp(Box::new(a), expr::BinaryOpType::Mod, Box::new(b))}
155 --184 --
156 e:expr_basic() {e}185 e:expr_basic_with_suffix() {e}
157 "(" __() e:boxed_expr() __() ")" {Expr::Parened(e)}186 "(" __() e:boxed_expr() __() ")" {Expr::Parened(e)}
158 } suffixes:(__() suffix:expr_suffix() {suffix})* {187 }
159 let mut cur = a;
160 for suffix in suffixes {
161 match suffix {
162 Suffix::String(index) => {
163 cur = Expr::Index(Box::new(cur), Box::new(Expr::Str(index)))
164 },
165 Suffix::Expression(index) => {
166 cur = Expr::Index(Box::new(cur), Box::new(index))
167 },
168 Suffix::Apply(args) => {
169 cur = Expr::Apply(Box::new(cur), args)
170 }
171 }
172 }
173 cur
174 }
175 / e:expr_basic() {e}188 / e:expr_basic_with_suffix() {e}
176189
177 pub rule boxed_expr() -> Box<Expr> = e:expr() {Box::new(e)}190 pub rule boxed_expr() -> Box<Expr> = e:expr() {Box::new(e)}
178 pub rule jsonnet() -> Expr = __() e:expr() __() {e}191 pub rule jsonnet() -> Expr = __() e:expr() __() {e}
207 );220 );
208 }221 }
222
223 #[test]
224 fn suffix_comparsion() {
225 use Expr::*;
226 assert_eq!(
227 parse("std.type(a) == \"string\"").unwrap(),
228 BinaryOp(
229 box Apply(
230 box Index(box Var("std".to_owned()), box Str("type".to_owned())),
231 ArgsDesc(vec![Arg::Positional(box Var("a".to_owned()))])
232 ),
233 BinaryOpType::Eq,
234 box Str("string".to_owned())
235 )
236 );
237 }
209}238}
210239