difftreelog
fix(parser) use precedence climbing for suffixes
in: master
1 file changed
crates/jsonnet-parser/src/lib.rsdiffbeforeafterboth9pub use expr::*;9pub use expr::*;10pub use peg;10pub use peg;1112enum Suffix {13 String(String),14 Slice(SliceDesc),15 Expression(LocExpr),16 Apply(expr::ArgsDesc),17 Extend(expr::ObjBody),18}19struct LocSuffix(Suffix, ExprLocation);201121pub struct ParserSettings {12pub struct ParserSettings {22 pub loc_data: bool,13 pub loc_data: bool,41 rule digit() -> char = d:$(['0'..='9']) {d.chars().next().unwrap()}32 rule digit() -> char = d:$(['0'..='9']) {d.chars().next().unwrap()}42 rule end_of_ident() = !['0'..='9' | '_' | 'a'..='z' | 'A'..='Z']33 rule end_of_ident() = !['0'..='9' | '_' | 'a'..='z' | 'A'..='Z']43 /// Sequence of digits34 /// Sequence of digits44 rule uint() -> u32 = a:$(digit()+) { a.parse().unwrap() }35 rule uint() -> u64 = a:$(digit()+) { a.parse().unwrap() }45 /// Number in scientific notation format36 /// Number in scientific notation format46 rule number() -> f64 = quiet!{a:$(uint() ("." uint())? (['e'|'E'] (s:['+'|'-'])? uint())?) { a.parse().unwrap() }} / expected!("<number>")37 rule number() -> f64 = quiet!{a:$(uint() ("." uint())? (['e'|'E'] (s:['+'|'-'])? uint())?) { a.parse().unwrap() }} / expected!("<number>")4738184175185 / l(s,<keyword("error") _ expr:expr(s) { Expr::Error(expr) }>)176 / l(s,<keyword("error") _ expr:expr(s) { Expr::Error(expr) }>)186187 rule expr_basic_with_suffix(s: &ParserSettings) -> LocExpr188 = a:expr_basic(s) suffixes:(_ suffix:l_expr_suffix(s) {suffix})* {189 let mut cur = a;190 for suffix in suffixes {191 let LocSuffix(suffix, location) = suffix;192 cur = LocExpr(Rc::new(match suffix {193 Suffix::String(index) => Expr::Index(cur, loc_expr!(Expr::Str(index), s.loc_data, (s.file_name.clone(), location.1, location.2))),194 Suffix::Slice(desc) => Expr::Slice(cur, desc),195 Suffix::Expression(index) => Expr::Index(cur, index),196 Suffix::Apply(args) => Expr::Apply(cur, args),197 Suffix::Extend(body) => Expr::ObjExtend(cur, body),198 }), if s.loc_data { Some(Rc::new(location)) } else { None })199 }200 cur201 }202177203 pub rule slice_desc(s: &ParserSettings) -> SliceDesc178 pub rule slice_desc(s: &ParserSettings) -> SliceDesc204 = start:expr(s)? _ ":" _ pair:(end:expr(s)? _ step:(":" _ e:expr(s) {e})? {(end, step)})? {179 = start:expr(s)? _ ":" _ pair:(end:expr(s)? _ step:(":" _ e:expr(s) {e})? {(end, step)})? {209 }184 }210 }185 }211186212 rule expr_suffix(s: &ParserSettings) -> Suffix187 rule expr(s: &ParserSettings) -> LocExpr213 = "." _ s:id() { Suffix::String(s) }214 / "[" _ s:slice_desc(s) _ "]" { Suffix::Slice(s) }215 / "[" _ s:expr(s) _ "]" { Suffix::Expression(s) }216 / "(" _ args:args(s) _ ")" (_ keyword("tailstrict"))? { Suffix::Apply(args) }217 / "{" _ body:objinside(s) _ "}" { Suffix::Extend(body) }218 rule l_expr_suffix(s: &ParserSettings) -> LocSuffix219 = start:position!() suffix:expr_suffix(s) end:position!() {LocSuffix(suffix, ExprLocation(s.file_name.clone(), start, end))}220221 rule expr(s: &ParserSettings) -> LocExpr222 = start:position!() a:precedence! {188 = start:position!() a:precedence! {223 a:(@) _ "||" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Or, b))}189 a:(@) _ "||" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Or, b))}224 --190 --267 "!" _ b:@ {loc_expr_todo!(Expr::UnaryOp(UnaryOpType::Not, b))}233 "!" _ b:@ {loc_expr_todo!(Expr::UnaryOp(UnaryOpType::Not, b))}268 "~" _ b:@ { loc_expr_todo!(Expr::UnaryOp(UnaryOpType::BitNot, b)) }234 "~" _ b:@ { loc_expr_todo!(Expr::UnaryOp(UnaryOpType::BitNot, b)) }269 --235 --236 a:(@) _ "[" _ s:slice_desc(s) _ "]" {loc_expr_todo!(Expr::Slice(a, s))}237 a:(@) _ "." _ s:id() {loc_expr_todo!(Expr::Index(a, el!(Expr::Str(s))))}238 a:(@) _ "[" _ s:expr(s) _ "]" {loc_expr_todo!(Expr::Index(a, s))}239 a:(@) _ "(" _ args:args(s) _ ")" (_ keyword("tailstrict"))? {loc_expr_todo!(Expr::Apply(a, args))}240 a:(@) _ "{" _ body:objinside(s) _ "}" {loc_expr_todo!(Expr::ObjExtend(a, body))}241 --270 e:expr_basic_with_suffix(s) {e}242 e:expr_basic(s) {e}271 "(" _ e:expr(s) _ ")" {loc_expr_todo!(Expr::Parened(e))}243 "(" _ e:expr(s) _ ")" {loc_expr_todo!(Expr::Parened(e))}272 } end:position!() {244 } end:position!() {273 let LocExpr(e, _) = a;245 let LocExpr(e, _) = a;277 None249 None278 })250 })279 }251 }280 / e:expr_basic_with_suffix(s) {e}252 / e:expr_basic(s) {e}281253282 pub rule jsonnet(s: &ParserSettings) -> LocExpr = _ e:expr(s) _ {e}254 pub rule jsonnet(s: &ParserSettings) -> LocExpr = _ e:expr(s) _ {e}283 }255 }398 );370 );399 }371 }372373 #[test]374 fn suffix() {375 // assert_eq!(parse!("std.test"), el!(Expr::Num(2.2)));376 // assert_eq!(parse!("std(2)"), el!(Expr::Num(2.2)));377 // assert_eq!(parse!("std.test(2)"), el!(Expr::Num(2.2)));378 // assert_eq!(parse!("a[b]"), el!(Expr::Num(2.2)))379 }400380401 #[test]381 #[test]402 fn array_comp() {382 fn array_comp() {