1use crate::token::{Tin, Token};
4use crate::value::Value;
5use crate::Lexer;
6use crate::{ActionError, Context, ContextAction};
7use std::cell::RefCell;
8use std::collections::HashMap;
9use std::fmt;
10use std::rc::Rc;
11use std::sync::Arc;
12
13pub type AltCondition = Arc<dyn Fn(&mut Rule, &mut Context) -> bool + Send + Sync>;
16
17pub type AltConditionWithMatch =
20 Arc<dyn Fn(&mut Rule, &mut Context, &mut AltMatch) -> bool + Send + Sync>;
21
22pub type AltConditionWithLexer =
25 Arc<dyn for<'source> Fn(&mut Rule, &mut Context, &mut Lexer<'source>) -> bool + Send + Sync>;
26
27pub type AltConditionWithLexerAndMatch = Arc<
30 dyn for<'source> Fn(&mut Rule, &mut Context, &mut AltMatch, &mut Lexer<'source>) -> bool
31 + Send
32 + Sync,
33>;
34
35pub type AltNext = Arc<dyn Fn(&mut Rule, &mut Context) -> Option<String> + Send + Sync>;
37pub type AltNextWithMatch =
38 Arc<dyn Fn(&mut Rule, &mut Context, &mut AltMatch) -> Option<String> + Send + Sync>;
39
40pub type AltBack = Arc<dyn Fn(&mut Rule, &mut Context) -> usize + Send + Sync>;
42pub type AltBackWithMatch =
43 Arc<dyn Fn(&mut Rule, &mut Context, &mut AltMatch) -> usize + Send + Sync>;
44
45pub type AltError = Arc<dyn Fn(&mut Rule, &mut Context) -> Option<Token> + Send + Sync>;
48pub type AltErrorWithMatch =
49 Arc<dyn Fn(&mut Rule, &mut Context, &mut AltMatch) -> Option<Token> + Send + Sync>;
50
51pub type AltModifier = Arc<dyn Fn(AltSpec, &mut Rule, &mut Context) -> AltSpec + Send + Sync>;
54
55pub type AltModifierWithMatch =
59 Arc<dyn Fn(AltMatch, &mut Rule, &mut Context, Option<&RuleSnapshot>) -> AltMatch + Send + Sync>;
60
61pub type AltAction = Arc<
65 dyn Fn(&mut Rule, &mut Context, &mut AltMatch) -> Result<Option<Token>, ActionError>
66 + Send
67 + Sync,
68>;
69
70#[derive(Clone)]
71pub enum AltActionBinding {
72 Named(String),
73 Context(ContextAction),
74 Matched(AltAction),
75}
76
77#[derive(Clone)]
82pub enum ActionBinding {
83 Named(String),
84 Callback(ContextAction),
85 State(StateAction),
86}
87
88pub type StateAction = Arc<
92 dyn Fn(
93 &mut Rule,
94 &mut Context,
95 Option<&RuleSnapshot>,
96 Option<Token>,
97 ) -> Result<Option<Token>, ActionError>
98 + Send
99 + Sync,
100>;
101
102#[derive(Clone, Default)]
106pub struct AltMatch {
107 pub p: Option<String>,
108 pub r: Option<String>,
109 pub b: usize,
110 pub n: HashMap<String, i32>,
111 pub u: HashMap<String, Value>,
112 pub k: HashMap<String, Value>,
113 pub g: Vec<String>,
114 pub e: Option<Box<Token>>,
120 pub h: Option<AltModifierWithMatch>,
124 pub actions: Vec<AltActionBinding>,
125 pub action_configs: HashMap<String, Value>,
126}
127
128impl AltMatch {
129 pub(crate) fn reset(&mut self) {
142 self.p = None;
143 self.r = None;
144 self.b = 0;
145 self.e = None;
146 self.h = None;
147 if !self.n.is_empty() {
148 self.n.clear();
149 }
150 if !self.u.is_empty() {
151 self.u.clear();
152 }
153 if !self.k.is_empty() {
154 self.k.clear();
155 }
156 if !self.g.is_empty() {
157 self.g.clear();
158 }
159 if !self.actions.is_empty() {
160 self.actions.clear();
161 }
162 if !self.action_configs.is_empty() {
163 self.action_configs.clear();
164 }
165 }
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq)]
169pub enum RuleState {
170 Open,
171 Close,
172}
173
174#[derive(Debug, Clone, PartialEq)]
175pub struct RuleDoneAlt {
176 pub b: usize,
177 pub g: Vec<String>,
178 pub p: String,
179 pub r: String,
180 pub err: Option<Token>,
181}
182
183#[derive(Debug, Clone, PartialEq)]
184pub struct RuleDone {
185 pub state: RuleState,
187 pub alt: Option<RuleDoneAlt>,
189 pub forced: bool,
191}
192
193#[derive(Debug, Clone, Copy, PartialEq, Eq)]
194pub enum CompareOp {
195 Eq,
196 Ne,
197 Lt,
198 Lte,
199 Gt,
200 Gte,
201 Exist,
202}
203
204#[derive(Debug, Clone, PartialEq)]
205pub struct Condition {
206 pub path: Vec<String>,
207 pub op: CompareOp,
208 pub value: Value,
209}
210
211#[derive(Clone, Default)]
212pub struct AltSpec {
213 pub s: Vec<Vec<Tin>>,
214 pub s_names: Vec<Vec<String>>,
222 pub s_bound: Vec<Vec<Tin>>,
226 pub p: Option<String>,
227 pub p_fn: Option<AltNext>,
228 pub p_match: Option<AltNextWithMatch>,
229 pub r: Option<String>,
230 pub r_fn: Option<AltNext>,
231 pub r_match: Option<AltNextWithMatch>,
232 pub b: usize,
233 pub b_fn: Option<AltBack>,
234 pub b_match: Option<AltBackWithMatch>,
235 pub a: Vec<String>,
236 pub action_fns: Vec<ContextAction>,
240 pub action_order: Vec<AltActionBinding>,
241 pub matched_action_fns: Vec<AltAction>,
242 pub action_configs: HashMap<String, Value>,
243 pub c: Vec<Condition>,
244 pub c_ref: Option<String>,
245 pub c_fn: Option<AltCondition>,
246 pub c_match: Option<AltConditionWithMatch>,
247 pub c_lex: Option<AltConditionWithLexer>,
248 pub c_lex_match: Option<AltConditionWithLexerAndMatch>,
249 pub n: HashMap<String, i32>,
250 pub u: HashMap<String, Value>,
251 pub k: HashMap<String, Value>,
252 pub g: String,
253 pub h: Option<AltModifier>,
254 pub h_match: Option<AltModifierWithMatch>,
255 pub e: Option<AltError>,
256 pub e_match: Option<AltErrorWithMatch>,
257}
258
259impl AltSpec {
260 pub fn new() -> Self {
261 Self::default()
262 }
263}
264
265#[derive(Clone)]
266pub struct RuleSpec {
267 pub name: String,
268 pub open: Vec<AltSpec>,
269 pub close: Vec<AltSpec>,
270 pub bo: Vec<String>,
271 pub ao: Vec<String>,
272 pub bc: Vec<String>,
273 pub ac: Vec<String>,
274 pub bo_fns: Vec<ContextAction>,
277 pub ao_fns: Vec<ContextAction>,
278 pub bc_fns: Vec<ContextAction>,
279 pub ac_fns: Vec<ContextAction>,
280 pub bo_state_fns: Vec<StateAction>,
281 pub ao_state_fns: Vec<StateAction>,
282 pub bc_state_fns: Vec<StateAction>,
283 pub ac_state_fns: Vec<StateAction>,
284 pub bo_order: Vec<ActionBinding>,
285 pub ao_order: Vec<ActionBinding>,
286 pub bc_order: Vec<ActionBinding>,
287 pub ac_order: Vec<ActionBinding>,
288}
289
290impl fmt::Debug for RuleSpec {
291 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
292 formatter
293 .debug_struct("RuleSpec")
294 .field("name", &self.name)
295 .field("open", &self.open.len())
296 .field("close", &self.close.len())
297 .field("bo", &self.bo.len())
298 .field("ao", &self.ao.len())
299 .field("bc", &self.bc.len())
300 .field("ac", &self.ac.len())
301 .finish_non_exhaustive()
302 }
303}
304
305impl RuleSpec {
306 pub fn new(name: impl Into<String>) -> Self {
307 RuleSpec {
308 name: name.into(),
309 open: Vec::new(),
310 close: Vec::new(),
311 bo: Vec::new(),
312 ao: Vec::new(),
313 bc: Vec::new(),
314 ac: Vec::new(),
315 bo_fns: Vec::new(),
316 ao_fns: Vec::new(),
317 bc_fns: Vec::new(),
318 ac_fns: Vec::new(),
319 bo_state_fns: Vec::new(),
320 ao_state_fns: Vec::new(),
321 bc_state_fns: Vec::new(),
322 ac_state_fns: Vec::new(),
323 bo_order: Vec::new(),
324 ao_order: Vec::new(),
325 bc_order: Vec::new(),
326 ac_order: Vec::new(),
327 }
328 }
329
330 pub fn clear(&mut self) -> &mut Self {
332 self.open.clear();
333 self.close.clear();
334 self.clear_actions(&[]);
335 self
336 }
337
338 pub fn add_open(&mut self, alt: AltSpec) -> &mut Self {
339 self.open.push(alt);
340 self
341 }
342
343 pub fn prepend_open(&mut self, alt: AltSpec) -> &mut Self {
344 self.open.insert(0, alt);
345 self
346 }
347
348 pub fn add_close(&mut self, alt: AltSpec) -> &mut Self {
349 self.close.push(alt);
350 self
351 }
352
353 pub fn prepend_close(&mut self, alt: AltSpec) -> &mut Self {
354 self.close.insert(0, alt);
355 self
356 }
357
358 pub fn clear_open(&mut self) -> &mut Self {
359 self.open.clear();
360 self
361 }
362
363 pub fn clear_close(&mut self) -> &mut Self {
364 self.close.clear();
365 self
366 }
367
368 pub fn modify_open(&mut self, mods: &crate::utility::ListMods<AltSpec>) -> &mut Self {
371 self.open = crate::utility::modlist(std::mem::take(&mut self.open), Some(mods));
372 self
373 }
374
375 pub fn modify_close(&mut self, mods: &crate::utility::ListMods<AltSpec>) -> &mut Self {
376 self.close = crate::utility::modlist(std::mem::take(&mut self.close), Some(mods));
377 self
378 }
379
380 pub fn add_bo(
381 &mut self,
382 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
383 ) -> &mut Self {
384 prepare_order(
385 &self.bo,
386 &self.bo_fns,
387 &self.bo_state_fns,
388 &mut self.bo_order,
389 );
390 let action = infallible_action(action);
391 self.bo_fns.push(action.clone());
392 self.bo_order.push(ActionBinding::Callback(action));
393 self
394 }
395
396 pub fn prepend_bo(
397 &mut self,
398 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
399 ) -> &mut Self {
400 prepare_order(
401 &self.bo,
402 &self.bo_fns,
403 &self.bo_state_fns,
404 &mut self.bo_order,
405 );
406 let action = infallible_action(action);
407 self.bo_fns.insert(0, action.clone());
408 self.bo_order.insert(0, ActionBinding::Callback(action));
409 self
410 }
411
412 pub fn add_ao(
413 &mut self,
414 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
415 ) -> &mut Self {
416 prepare_order(
417 &self.ao,
418 &self.ao_fns,
419 &self.ao_state_fns,
420 &mut self.ao_order,
421 );
422 let action = infallible_action(action);
423 self.ao_fns.push(action.clone());
424 self.ao_order.push(ActionBinding::Callback(action));
425 self
426 }
427
428 pub fn prepend_ao(
429 &mut self,
430 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
431 ) -> &mut Self {
432 prepare_order(
433 &self.ao,
434 &self.ao_fns,
435 &self.ao_state_fns,
436 &mut self.ao_order,
437 );
438 let action = infallible_action(action);
439 self.ao_fns.insert(0, action.clone());
440 self.ao_order.insert(0, ActionBinding::Callback(action));
441 self
442 }
443
444 pub fn add_bc(
445 &mut self,
446 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
447 ) -> &mut Self {
448 prepare_order(
449 &self.bc,
450 &self.bc_fns,
451 &self.bc_state_fns,
452 &mut self.bc_order,
453 );
454 let action = infallible_action(action);
455 self.bc_fns.push(action.clone());
456 self.bc_order.push(ActionBinding::Callback(action));
457 self
458 }
459
460 pub fn prepend_bc(
461 &mut self,
462 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
463 ) -> &mut Self {
464 prepare_order(
465 &self.bc,
466 &self.bc_fns,
467 &self.bc_state_fns,
468 &mut self.bc_order,
469 );
470 let action = infallible_action(action);
471 self.bc_fns.insert(0, action.clone());
472 self.bc_order.insert(0, ActionBinding::Callback(action));
473 self
474 }
475
476 pub fn add_ac(
477 &mut self,
478 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
479 ) -> &mut Self {
480 prepare_order(
481 &self.ac,
482 &self.ac_fns,
483 &self.ac_state_fns,
484 &mut self.ac_order,
485 );
486 let action = infallible_action(action);
487 self.ac_fns.push(action.clone());
488 self.ac_order.push(ActionBinding::Callback(action));
489 self
490 }
491
492 pub fn prepend_ac(
493 &mut self,
494 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
495 ) -> &mut Self {
496 prepare_order(
497 &self.ac,
498 &self.ac_fns,
499 &self.ac_state_fns,
500 &mut self.ac_order,
501 );
502 let action = infallible_action(action);
503 self.ac_fns.insert(0, action.clone());
504 self.ac_order.insert(0, ActionBinding::Callback(action));
505 self
506 }
507
508 pub fn add_bo_result(&mut self, action: ContextAction) -> &mut Self {
509 prepare_order(
510 &self.bo,
511 &self.bo_fns,
512 &self.bo_state_fns,
513 &mut self.bo_order,
514 );
515 self.bo_fns.push(action.clone());
516 self.bo_order.push(ActionBinding::Callback(action));
517 self
518 }
519
520 pub fn add_ao_result(&mut self, action: ContextAction) -> &mut Self {
521 prepare_order(
522 &self.ao,
523 &self.ao_fns,
524 &self.ao_state_fns,
525 &mut self.ao_order,
526 );
527 self.ao_fns.push(action.clone());
528 self.ao_order.push(ActionBinding::Callback(action));
529 self
530 }
531
532 pub fn add_bc_result(&mut self, action: ContextAction) -> &mut Self {
533 prepare_order(
534 &self.bc,
535 &self.bc_fns,
536 &self.bc_state_fns,
537 &mut self.bc_order,
538 );
539 self.bc_fns.push(action.clone());
540 self.bc_order.push(ActionBinding::Callback(action));
541 self
542 }
543
544 pub fn add_ac_result(&mut self, action: ContextAction) -> &mut Self {
545 prepare_order(
546 &self.ac,
547 &self.ac_fns,
548 &self.ac_state_fns,
549 &mut self.ac_order,
550 );
551 self.ac_fns.push(action.clone());
552 self.ac_order.push(ActionBinding::Callback(action));
553 self
554 }
555
556 pub fn add_bo_with_state(&mut self, action: StateAction) -> &mut Self {
557 prepare_order(
558 &self.bo,
559 &self.bo_fns,
560 &self.bo_state_fns,
561 &mut self.bo_order,
562 );
563 self.bo_state_fns.push(action.clone());
564 self.bo_order.push(ActionBinding::State(action));
565 self
566 }
567
568 pub fn prepend_bo_with_state(&mut self, action: StateAction) -> &mut Self {
569 prepare_order(
570 &self.bo,
571 &self.bo_fns,
572 &self.bo_state_fns,
573 &mut self.bo_order,
574 );
575 self.bo_state_fns.insert(0, action.clone());
576 self.bo_order.insert(0, ActionBinding::State(action));
577 self
578 }
579
580 pub fn add_ao_with_state(&mut self, action: StateAction) -> &mut Self {
581 prepare_order(
582 &self.ao,
583 &self.ao_fns,
584 &self.ao_state_fns,
585 &mut self.ao_order,
586 );
587 self.ao_state_fns.push(action.clone());
588 self.ao_order.push(ActionBinding::State(action));
589 self
590 }
591
592 pub fn prepend_ao_with_state(&mut self, action: StateAction) -> &mut Self {
593 prepare_order(
594 &self.ao,
595 &self.ao_fns,
596 &self.ao_state_fns,
597 &mut self.ao_order,
598 );
599 self.ao_state_fns.insert(0, action.clone());
600 self.ao_order.insert(0, ActionBinding::State(action));
601 self
602 }
603
604 pub fn add_bc_with_state(&mut self, action: StateAction) -> &mut Self {
605 prepare_order(
606 &self.bc,
607 &self.bc_fns,
608 &self.bc_state_fns,
609 &mut self.bc_order,
610 );
611 self.bc_state_fns.push(action.clone());
612 self.bc_order.push(ActionBinding::State(action));
613 self
614 }
615
616 pub fn prepend_bc_with_state(&mut self, action: StateAction) -> &mut Self {
617 prepare_order(
618 &self.bc,
619 &self.bc_fns,
620 &self.bc_state_fns,
621 &mut self.bc_order,
622 );
623 self.bc_state_fns.insert(0, action.clone());
624 self.bc_order.insert(0, ActionBinding::State(action));
625 self
626 }
627
628 pub fn add_ac_with_state(&mut self, action: StateAction) -> &mut Self {
629 prepare_order(
630 &self.ac,
631 &self.ac_fns,
632 &self.ac_state_fns,
633 &mut self.ac_order,
634 );
635 self.ac_state_fns.push(action.clone());
636 self.ac_order.push(ActionBinding::State(action));
637 self
638 }
639
640 pub fn prepend_ac_with_state(&mut self, action: StateAction) -> &mut Self {
641 prepare_order(
642 &self.ac,
643 &self.ac_fns,
644 &self.ac_state_fns,
645 &mut self.ac_order,
646 );
647 self.ac_state_fns.insert(0, action.clone());
648 self.ac_order.insert(0, ActionBinding::State(action));
649 self
650 }
651
652 pub fn add_bo_ref(&mut self, action: impl Into<String>) -> &mut Self {
653 add_named(
654 &mut self.bo,
655 &mut self.bo_fns,
656 &mut self.bo_state_fns,
657 &mut self.bo_order,
658 action.into(),
659 false,
660 );
661 self
662 }
663
664 pub fn prepend_bo_ref(&mut self, action: impl Into<String>) -> &mut Self {
665 add_named(
666 &mut self.bo,
667 &mut self.bo_fns,
668 &mut self.bo_state_fns,
669 &mut self.bo_order,
670 action.into(),
671 true,
672 );
673 self
674 }
675
676 pub fn add_ao_ref(&mut self, action: impl Into<String>) -> &mut Self {
677 add_named(
678 &mut self.ao,
679 &mut self.ao_fns,
680 &mut self.ao_state_fns,
681 &mut self.ao_order,
682 action.into(),
683 false,
684 );
685 self
686 }
687
688 pub fn prepend_ao_ref(&mut self, action: impl Into<String>) -> &mut Self {
689 add_named(
690 &mut self.ao,
691 &mut self.ao_fns,
692 &mut self.ao_state_fns,
693 &mut self.ao_order,
694 action.into(),
695 true,
696 );
697 self
698 }
699
700 pub fn add_bc_ref(&mut self, action: impl Into<String>) -> &mut Self {
701 add_named(
702 &mut self.bc,
703 &mut self.bc_fns,
704 &mut self.bc_state_fns,
705 &mut self.bc_order,
706 action.into(),
707 false,
708 );
709 self
710 }
711
712 pub fn prepend_bc_ref(&mut self, action: impl Into<String>) -> &mut Self {
713 add_named(
714 &mut self.bc,
715 &mut self.bc_fns,
716 &mut self.bc_state_fns,
717 &mut self.bc_order,
718 action.into(),
719 true,
720 );
721 self
722 }
723
724 pub fn add_ac_ref(&mut self, action: impl Into<String>) -> &mut Self {
725 add_named(
726 &mut self.ac,
727 &mut self.ac_fns,
728 &mut self.ac_state_fns,
729 &mut self.ac_order,
730 action.into(),
731 false,
732 );
733 self
734 }
735
736 pub fn prepend_ac_ref(&mut self, action: impl Into<String>) -> &mut Self {
737 add_named(
738 &mut self.ac,
739 &mut self.ac_fns,
740 &mut self.ac_state_fns,
741 &mut self.ac_order,
742 action.into(),
743 true,
744 );
745 self
746 }
747
748 pub fn clear_actions(&mut self, phases: &[&str]) -> &mut Self {
752 let clear_all = phases.is_empty();
753 for phase in ["bo", "ao", "bc", "ac"] {
754 if clear_all || phases.contains(&phase) {
755 match phase {
756 "bo" => {
757 self.bo.clear();
758 self.bo_fns.clear();
759 self.bo_state_fns.clear();
760 self.bo_order.clear();
761 }
762 "ao" => {
763 self.ao.clear();
764 self.ao_fns.clear();
765 self.ao_state_fns.clear();
766 self.ao_order.clear();
767 }
768 "bc" => {
769 self.bc.clear();
770 self.bc_fns.clear();
771 self.bc_state_fns.clear();
772 self.bc_order.clear();
773 }
774 "ac" => {
775 self.ac.clear();
776 self.ac_fns.clear();
777 self.ac_state_fns.clear();
778 self.ac_order.clear();
779 }
780 _ => unreachable!(),
781 }
782 }
783 }
784 self
785 }
786}
787
788fn infallible_action(
789 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
790) -> ContextAction {
791 Arc::new(move |rule, context| {
792 action(rule, context);
793 Ok::<(), ActionError>(())
794 })
795}
796
797impl AltSpec {
798 pub fn add_action(
800 &mut self,
801 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
802 ) -> &mut Self {
803 prepare_alt_order(
804 &self.a,
805 &self.action_fns,
806 &self.matched_action_fns,
807 &mut self.action_order,
808 );
809 let action = infallible_action(action);
810 self.action_fns.push(action.clone());
811 self.action_order.push(AltActionBinding::Context(action));
812 self
813 }
814
815 pub fn prepend_action(
818 &mut self,
819 action: impl Fn(&mut Rule, &mut Context) + Send + Sync + 'static,
820 ) -> &mut Self {
821 prepare_alt_order(
822 &self.a,
823 &self.action_fns,
824 &self.matched_action_fns,
825 &mut self.action_order,
826 );
827 let action = infallible_action(action);
828 self.action_fns.insert(0, action.clone());
829 self.action_order
830 .insert(0, AltActionBinding::Context(action));
831 self
832 }
833
834 pub fn add_action_result(&mut self, action: ContextAction) -> &mut Self {
836 prepare_alt_order(
837 &self.a,
838 &self.action_fns,
839 &self.matched_action_fns,
840 &mut self.action_order,
841 );
842 self.action_fns.push(action.clone());
843 self.action_order.push(AltActionBinding::Context(action));
844 self
845 }
846
847 pub fn prepend_action_result(&mut self, action: ContextAction) -> &mut Self {
848 prepare_alt_order(
849 &self.a,
850 &self.action_fns,
851 &self.matched_action_fns,
852 &mut self.action_order,
853 );
854 self.action_fns.insert(0, action.clone());
855 self.action_order
856 .insert(0, AltActionBinding::Context(action));
857 self
858 }
859
860 pub fn add_action_with_match(
862 &mut self,
863 action: impl Fn(&mut Rule, &mut Context, &AltMatch) -> Option<Token> + Send + Sync + 'static,
864 ) -> &mut Self {
865 self.add_action_with_match_result(Arc::new(move |rule, context, matched| {
866 Ok(action(rule, context, matched))
867 }))
868 }
869
870 pub fn prepend_action_with_match(
871 &mut self,
872 action: impl Fn(&mut Rule, &mut Context, &AltMatch) -> Option<Token> + Send + Sync + 'static,
873 ) -> &mut Self {
874 self.prepend_action_with_match_result(Arc::new(move |rule, context, matched| {
875 Ok(action(rule, context, matched))
876 }))
877 }
878
879 pub fn add_action_with_match_result(&mut self, action: AltAction) -> &mut Self {
880 prepare_alt_order(
881 &self.a,
882 &self.action_fns,
883 &self.matched_action_fns,
884 &mut self.action_order,
885 );
886 self.matched_action_fns.push(action.clone());
887 self.action_order.push(AltActionBinding::Matched(action));
888 self
889 }
890
891 pub fn prepend_action_with_match_result(&mut self, action: AltAction) -> &mut Self {
892 prepare_alt_order(
893 &self.a,
894 &self.action_fns,
895 &self.matched_action_fns,
896 &mut self.action_order,
897 );
898 self.matched_action_fns.insert(0, action.clone());
899 self.action_order
900 .insert(0, AltActionBinding::Matched(action));
901 self
902 }
903
904 pub fn add_action_ref(&mut self, action: impl Into<String>) -> &mut Self {
905 add_alt_named(
906 &mut self.a,
907 &mut self.action_fns,
908 &mut self.matched_action_fns,
909 &mut self.action_order,
910 action.into(),
911 false,
912 );
913 self
914 }
915
916 pub fn prepend_action_ref(&mut self, action: impl Into<String>) -> &mut Self {
917 add_alt_named(
918 &mut self.a,
919 &mut self.action_fns,
920 &mut self.matched_action_fns,
921 &mut self.action_order,
922 action.into(),
923 true,
924 );
925 self
926 }
927}
928
929fn alt_order_matches(
930 named: &[String],
931 callbacks: &[ContextAction],
932 matched: &[AltAction],
933 order: &[AltActionBinding],
934) -> bool {
935 if order.len() != named.len() + callbacks.len() + matched.len() {
936 return false;
937 }
938 let (mut next_name, mut next_callback, mut next_matched) = (0, 0, 0);
944 for binding in order {
945 match binding {
946 AltActionBinding::Named(name) => {
947 if named.get(next_name) != Some(name) {
948 return false;
949 }
950 next_name += 1;
951 }
952 AltActionBinding::Context(callback) => {
953 if !callbacks
954 .get(next_callback)
955 .is_some_and(|expected| Arc::ptr_eq(expected, callback))
956 {
957 return false;
958 }
959 next_callback += 1;
960 }
961 AltActionBinding::Matched(callback) => {
962 if !matched
963 .get(next_matched)
964 .is_some_and(|expected| Arc::ptr_eq(expected, callback))
965 {
966 return false;
967 }
968 next_matched += 1;
969 }
970 }
971 }
972 next_name == named.len() && next_callback == callbacks.len() && next_matched == matched.len()
973}
974
975fn prepare_alt_order(
976 named: &[String],
977 callbacks: &[ContextAction],
978 matched: &[AltAction],
979 order: &mut Vec<AltActionBinding>,
980) {
981 if !alt_order_matches(named, callbacks, matched, order) {
982 *order = named
983 .iter()
984 .cloned()
985 .map(AltActionBinding::Named)
986 .chain(callbacks.iter().cloned().map(AltActionBinding::Context))
987 .chain(matched.iter().cloned().map(AltActionBinding::Matched))
988 .collect();
989 }
990}
991
992fn add_alt_named(
993 named: &mut Vec<String>,
994 callbacks: &mut Vec<ContextAction>,
995 matched: &mut Vec<AltAction>,
996 order: &mut Vec<AltActionBinding>,
997 action: String,
998 prepend: bool,
999) {
1000 prepare_alt_order(named, callbacks, matched, order);
1001 if prepend {
1002 named.insert(0, action.clone());
1003 order.insert(0, AltActionBinding::Named(action));
1004 } else {
1005 named.push(action.clone());
1006 order.push(AltActionBinding::Named(action));
1007 }
1008}
1009
1010pub(crate) fn resolved_alt_action_order(
1011 named: &[String],
1012 callbacks: &[ContextAction],
1013 matched: &[AltAction],
1014 order: &[AltActionBinding],
1015) -> Vec<AltActionBinding> {
1016 if alt_order_matches(named, callbacks, matched, order) {
1017 order.to_vec()
1018 } else {
1019 named
1020 .iter()
1021 .cloned()
1022 .map(AltActionBinding::Named)
1023 .chain(callbacks.iter().cloned().map(AltActionBinding::Context))
1024 .chain(matched.iter().cloned().map(AltActionBinding::Matched))
1025 .collect()
1026 }
1027}
1028
1029fn order_matches(
1030 named: &[String],
1031 callbacks: &[ContextAction],
1032 states: &[StateAction],
1033 order: &[ActionBinding],
1034) -> bool {
1035 if order.len() != named.len() + callbacks.len() + states.len() {
1036 return false;
1037 }
1038 let (mut next_name, mut next_callback, mut next_state) = (0, 0, 0);
1040 for binding in order {
1041 match binding {
1042 ActionBinding::Named(name) => {
1043 if named.get(next_name) != Some(name) {
1044 return false;
1045 }
1046 next_name += 1;
1047 }
1048 ActionBinding::Callback(callback) => {
1049 if !callbacks
1050 .get(next_callback)
1051 .is_some_and(|expected| Arc::ptr_eq(expected, callback))
1052 {
1053 return false;
1054 }
1055 next_callback += 1;
1056 }
1057 ActionBinding::State(callback) => {
1058 if !states
1059 .get(next_state)
1060 .is_some_and(|expected| Arc::ptr_eq(expected, callback))
1061 {
1062 return false;
1063 }
1064 next_state += 1;
1065 }
1066 }
1067 }
1068 next_name == named.len() && next_callback == callbacks.len() && next_state == states.len()
1069}
1070
1071fn prepare_order(
1072 named: &[String],
1073 callbacks: &[ContextAction],
1074 states: &[StateAction],
1075 order: &mut Vec<ActionBinding>,
1076) {
1077 if !order_matches(named, callbacks, states, order) {
1078 *order = named
1079 .iter()
1080 .cloned()
1081 .map(ActionBinding::Named)
1082 .chain(callbacks.iter().cloned().map(ActionBinding::Callback))
1083 .chain(states.iter().cloned().map(ActionBinding::State))
1084 .collect();
1085 }
1086}
1087
1088fn add_named(
1089 named: &mut Vec<String>,
1090 callbacks: &mut Vec<ContextAction>,
1091 states: &mut Vec<StateAction>,
1092 order: &mut Vec<ActionBinding>,
1093 action: String,
1094 prepend: bool,
1095) {
1096 prepare_order(named, callbacks, states, order);
1097 if prepend {
1098 named.insert(0, action.clone());
1099 order.insert(0, ActionBinding::Named(action));
1100 } else {
1101 named.push(action.clone());
1102 order.push(ActionBinding::Named(action));
1103 }
1104}
1105
1106pub(crate) fn resolved_action_order(
1107 named: &[String],
1108 callbacks: &[ContextAction],
1109 states: &[StateAction],
1110 order: &[ActionBinding],
1111) -> Vec<ActionBinding> {
1112 if order_matches(named, callbacks, states, order) {
1113 order.to_vec()
1114 } else {
1115 named
1116 .iter()
1117 .cloned()
1118 .map(ActionBinding::Named)
1119 .chain(callbacks.iter().cloned().map(ActionBinding::Callback))
1120 .chain(states.iter().cloned().map(ActionBinding::State))
1121 .collect()
1122 }
1123}
1124
1125#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1133pub struct RuleName(Arc<str>);
1134
1135impl RuleName {
1136 pub fn as_str(&self) -> &str {
1137 &self.0
1138 }
1139}
1140
1141impl std::ops::Deref for RuleName {
1142 type Target = str;
1143
1144 fn deref(&self) -> &str {
1145 &self.0
1146 }
1147}
1148
1149impl AsRef<str> for RuleName {
1150 fn as_ref(&self) -> &str {
1151 &self.0
1152 }
1153}
1154
1155impl std::borrow::Borrow<str> for RuleName {
1158 fn borrow(&self) -> &str {
1159 &self.0
1160 }
1161}
1162
1163impl fmt::Debug for RuleName {
1166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1167 fmt::Debug::fmt(&*self.0, f)
1168 }
1169}
1170
1171impl fmt::Display for RuleName {
1172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1173 f.write_str(&self.0)
1174 }
1175}
1176
1177impl PartialEq<str> for RuleName {
1178 fn eq(&self, other: &str) -> bool {
1179 &*self.0 == other
1180 }
1181}
1182
1183impl PartialEq<&str> for RuleName {
1184 fn eq(&self, other: &&str) -> bool {
1185 &*self.0 == *other
1186 }
1187}
1188
1189impl PartialEq<String> for RuleName {
1190 fn eq(&self, other: &String) -> bool {
1191 &*self.0 == other.as_str()
1192 }
1193}
1194
1195impl PartialEq<RuleName> for str {
1196 fn eq(&self, other: &RuleName) -> bool {
1197 self == &*other.0
1198 }
1199}
1200
1201impl PartialEq<RuleName> for &str {
1202 fn eq(&self, other: &RuleName) -> bool {
1203 *self == &*other.0
1204 }
1205}
1206
1207impl PartialEq<RuleName> for String {
1208 fn eq(&self, other: &RuleName) -> bool {
1209 self.as_str() == &*other.0
1210 }
1211}
1212
1213impl From<&str> for RuleName {
1214 fn from(name: &str) -> Self {
1215 RuleName(Arc::from(name))
1216 }
1217}
1218
1219impl From<String> for RuleName {
1220 fn from(name: String) -> Self {
1221 RuleName(Arc::from(name.as_str()))
1222 }
1223}
1224
1225impl From<&String> for RuleName {
1226 fn from(name: &String) -> Self {
1227 RuleName(Arc::from(name.as_str()))
1228 }
1229}
1230
1231impl From<Arc<str>> for RuleName {
1232 fn from(name: Arc<str>) -> Self {
1233 RuleName(name)
1234 }
1235}
1236
1237impl From<RuleName> for String {
1238 fn from(name: RuleName) -> Self {
1239 name.0.to_string()
1240 }
1241}
1242
1243#[derive(Clone)]
1254pub struct Rule {
1255 shared: Rc<RuleSnapshot>,
1256 pub parent_node: Option<Rc<RefCell<Value>>>,
1258 pub child_node: Value,
1269 pub(crate) skip_befores: bool,
1270 pub(crate) child_node_is_self: bool,
1271 pub(crate) child_link_open: bool,
1298 pub(crate) child_cell: Option<Rc<RefCell<Value>>>,
1299 pub(crate) child_record: Option<Rc<RuleSnapshot>>,
1307 pub(crate) slot: usize,
1319}
1320
1321impl Drop for RuleSnapshot {
1322 fn drop(&mut self) {
1348 if self.parent_rule.is_none()
1352 && self.child_rule.is_none()
1353 && self.prev_rule.is_none()
1354 && self.next_rule.is_none()
1355 {
1356 return;
1357 }
1358
1359 fn unlink(
1366 snapshot: &mut RuleSnapshot,
1367 cursor: &mut Option<Rc<RuleSnapshot>>,
1368 pending: &mut Vec<Rc<RuleSnapshot>>,
1369 ) {
1370 let mut hold = |held: Option<Rc<RuleSnapshot>>| {
1371 if let Some(held) = held {
1372 if cursor.is_none() {
1373 *cursor = Some(held);
1374 } else {
1375 pending.push(held);
1376 }
1377 }
1378 };
1379 hold(snapshot.parent_rule.take());
1380 hold(snapshot.child_rule.take());
1381 hold(snapshot.prev_rule.take());
1382 hold(snapshot.next_rule.take());
1383 }
1384
1385 let mut cursor: Option<Rc<RuleSnapshot>> = None;
1386 let mut pending: Vec<Rc<RuleSnapshot>> = Vec::new();
1387 unlink(self, &mut cursor, &mut pending);
1388 while let Some(mut link) = cursor.take().or_else(|| pending.pop()) {
1389 if Rc::weak_count(&link) == 0 {
1390 if let Some(owned) = Rc::get_mut(&mut link) {
1395 unlink(owned, &mut cursor, &mut pending);
1396 }
1397 } else if let Ok(mut owned) = Rc::try_unwrap(link) {
1398 unlink(&mut owned, &mut cursor, &mut pending);
1406 }
1407 }
1410 }
1411}
1412
1413impl std::ops::Deref for Rule {
1414 type Target = RuleSnapshot;
1415
1416 fn deref(&self) -> &RuleSnapshot {
1417 &self.shared
1418 }
1419}
1420
1421impl std::ops::DerefMut for Rule {
1437 fn deref_mut(&mut self) -> &mut RuleSnapshot {
1438 Rc::make_mut(&mut self.shared)
1439 }
1440}
1441
1442#[derive(Debug, Clone)]
1443pub struct RuleSnapshot {
1444 pub i: usize,
1445 pub d: usize,
1446 pub name: RuleName,
1447 pub spec: Arc<RuleSpec>,
1448 pub state: RuleState,
1449 pub bo: bool,
1450 pub ao: bool,
1451 pub bc: bool,
1452 pub ac: bool,
1453 pub need: i32,
1454 pub node: Rc<RefCell<Value>>,
1455 pub parent_rule: Option<Rc<RuleSnapshot>>,
1456 pub child_rule: Option<Rc<RuleSnapshot>>,
1457 pub prev_rule: Option<Rc<RuleSnapshot>>,
1458 pub next_rule: Option<Rc<RuleSnapshot>>,
1459 pub next_rule_name: Option<RuleName>,
1460 pub n: Rc<HashMap<String, i32>>,
1461 pub u: Rc<HashMap<String, Value>>,
1462 pub k: Rc<HashMap<String, Value>>,
1463 pub o: Rc<Vec<Token>>,
1467 pub c: Rc<Vec<Token>>,
1468}
1469
1470fn empty_counters() -> Rc<HashMap<String, i32>> {
1474 thread_local! {
1475 static EMPTY: Rc<HashMap<String, i32>> = Rc::new(HashMap::new());
1476 }
1477 EMPTY.with(Rc::clone)
1478}
1479
1480fn empty_values() -> Rc<HashMap<String, Value>> {
1481 thread_local! {
1482 static EMPTY: Rc<HashMap<String, Value>> = Rc::new(HashMap::new());
1483 }
1484 EMPTY.with(Rc::clone)
1485}
1486
1487fn empty_tokens() -> Rc<Vec<Token>> {
1491 thread_local! {
1492 static EMPTY: Rc<Vec<Token>> = Rc::new(Vec::new());
1493 }
1494 EMPTY.with(Rc::clone)
1495}
1496
1497impl Rule {
1498 pub fn n_mut(&mut self) -> &mut HashMap<String, i32> {
1501 Rc::make_mut(&mut self.n)
1502 }
1503
1504 pub fn u_mut(&mut self) -> &mut HashMap<String, Value> {
1505 Rc::make_mut(&mut self.u)
1506 }
1507
1508 pub fn k_mut(&mut self) -> &mut HashMap<String, Value> {
1509 Rc::make_mut(&mut self.k)
1510 }
1511
1512 pub fn new(name: impl Into<RuleName>, initial_node: Value) -> Self {
1513 let name: RuleName = name.into();
1514 let spec = Arc::new(RuleSpec::new(name.as_str()));
1515 Rule {
1516 shared: Rc::new(RuleSnapshot {
1517 i: 0,
1518 d: 0,
1519 name,
1520 spec,
1521 state: RuleState::Open,
1522 bo: true,
1523 ao: true,
1524 bc: true,
1525 ac: true,
1526 need: 0,
1527 node: Rc::new(RefCell::new(initial_node)),
1528 parent_rule: None,
1529 child_rule: None,
1530 prev_rule: None,
1531 next_rule: None,
1532 next_rule_name: None,
1533 n: empty_counters(),
1534 u: empty_values(),
1535 k: empty_values(),
1536 o: empty_tokens(),
1537 c: empty_tokens(),
1538 }),
1539 parent_node: None,
1540 child_node: Value::Undefined,
1541 skip_befores: false,
1542 child_node_is_self: false,
1543 child_link_open: false,
1544 child_cell: None,
1545 child_record: None,
1546 slot: usize::MAX,
1547 }
1548 }
1549
1550 pub fn with_shared_node(name: impl Into<RuleName>, node: Rc<RefCell<Value>>) -> Self {
1551 Self::bound(name.into(), node, None, usize::MAX)
1552 }
1553
1554 pub(crate) fn bound(
1564 name: RuleName,
1565 node: Rc<RefCell<Value>>,
1566 installed: Option<&Arc<RuleSpec>>,
1567 slot: usize,
1568 ) -> Self {
1569 let spec = match installed {
1570 Some(spec) => Arc::clone(spec),
1571 None => Arc::new(RuleSpec::new(name.as_str())),
1572 };
1573 Rule {
1574 shared: Rc::new(RuleSnapshot {
1575 i: 0,
1576 d: 0,
1577 name,
1578 spec,
1579 state: RuleState::Open,
1580 bo: true,
1581 ao: true,
1582 bc: true,
1583 ac: true,
1584 need: 0,
1585 node,
1586 parent_rule: None,
1587 child_rule: None,
1588 prev_rule: None,
1589 next_rule: None,
1590 next_rule_name: None,
1591 n: empty_counters(),
1592 u: empty_values(),
1593 k: empty_values(),
1594 o: empty_tokens(),
1595 c: empty_tokens(),
1596 }),
1597 parent_node: None,
1598 child_node: Value::Undefined,
1599 skip_befores: false,
1600 child_node_is_self: false,
1601 child_link_open: false,
1602 child_cell: None,
1603 child_record: None,
1604 slot,
1605 }
1606 }
1607
1608 pub(crate) fn bind_spec(&mut self, spec: &Arc<RuleSpec>, name: RuleName, slot: usize) {
1614 self.name = name;
1615 self.spec = Arc::clone(spec);
1616 self.slot = slot;
1617 self.bo = true;
1620 self.ao = true;
1621 self.bc = true;
1622 self.ac = true;
1623 }
1624
1625 pub fn o0(&self) -> Option<&Token> {
1626 self.o.first()
1627 }
1628
1629 pub fn o1(&self) -> Option<&Token> {
1630 self.o.get(1)
1631 }
1632
1633 pub fn c0(&self) -> Option<&Token> {
1634 self.c.first()
1635 }
1636
1637 pub fn c1(&self) -> Option<&Token> {
1638 self.c.get(1)
1639 }
1640
1641 pub fn os(&self) -> usize {
1642 self.o.len()
1643 }
1644
1645 pub fn cs(&self) -> usize {
1646 self.c.len()
1647 }
1648
1649 pub fn resolve_open_value(&mut self, index: usize, context: &mut Context) -> Value {
1652 self.o
1653 .get(index)
1654 .cloned()
1655 .map_or(Value::Undefined, |token| token.resolve_val(self, context))
1656 }
1657
1658 pub fn resolve_close_value(&mut self, index: usize, context: &mut Context) -> Value {
1660 self.c
1661 .get(index)
1662 .cloned()
1663 .map_or(Value::Undefined, |token| token.resolve_val(self, context))
1664 }
1665
1666 pub fn eq(&self, counter: &str, limit: i32) -> bool {
1669 self.n.get(counter).copied().unwrap_or(0) == limit
1670 }
1671
1672 pub fn lt(&self, counter: &str, limit: i32) -> bool {
1673 self.n.get(counter).copied().unwrap_or(0) < limit
1674 }
1675
1676 pub fn gt(&self, counter: &str, limit: i32) -> bool {
1677 self.n.get(counter).copied().unwrap_or(0) > limit
1678 }
1679
1680 pub fn lte(&self, counter: &str, limit: i32) -> bool {
1681 self.n.get(counter).copied().unwrap_or(0) <= limit
1682 }
1683
1684 pub fn gte(&self, counter: &str, limit: i32) -> bool {
1685 self.n.get(counter).copied().unwrap_or(0) >= limit
1686 }
1687
1688 pub fn exist(&self, counter: &str) -> bool {
1689 self.n.contains_key(counter)
1690 }
1691
1692 pub fn snapshot(&self) -> Rc<RuleSnapshot> {
1695 Rc::clone(&self.shared)
1696 }
1697
1698 pub(crate) fn note_child_push(&mut self, child: &Rule) {
1701 self.child_link_open = true;
1702 self.child_cell = Some(Rc::clone(&child.node));
1703 self.child_record = Some(child.snapshot());
1704 }
1705
1706 pub(crate) fn freeze_child(&mut self, child: &Rule) {
1723 if self.child_link_open {
1724 self.child_cell = Some(Rc::clone(&child.node));
1725 self.child_record = Some(child.snapshot());
1726 self.child_link_open = false;
1727 }
1728 }
1729
1730 pub(crate) fn accept_child_node(&mut self, child: &Rule) {
1731 self.freeze_child(child);
1732 let cell = self
1733 .child_cell
1734 .clone()
1735 .unwrap_or_else(|| Rc::clone(&child.node));
1736 self.child_node_is_self = Rc::ptr_eq(&self.node, &cell);
1737 self.child_node = if self.child_node_is_self {
1749 Value::Undefined
1750 } else {
1751 cell.borrow().clone()
1752 };
1753 }
1754
1755 pub fn child_value(&self) -> Value {
1762 if self.child_node_is_self {
1763 self.node.borrow().clone()
1764 } else {
1765 self.child_node.clone()
1766 }
1767 }
1768
1769 pub fn has_child_value(&self) -> bool {
1771 if self.child_node_is_self {
1772 !self.node.borrow().is_undefined()
1773 } else {
1774 !self.child_node.is_undefined()
1775 }
1776 }
1777
1778 pub(crate) fn accept_child(&mut self, child: &Rule) {
1791 self.accept_child_node(child);
1792 self.child_rule = self.child_record.clone().or_else(|| Some(child.snapshot()));
1798 self.next_rule = self.child_rule.clone();
1799 }
1800
1801 pub(crate) fn park_child_node(&mut self) {
1837 if self.child_node_is_self {
1838 self.child_node = Value::Undefined;
1839 }
1840 }
1841}
1842
1843impl fmt::Display for Rule {
1844 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1845 write!(formatter, "[Rule {}~{}]", self.name, self.i)
1846 }
1847}
1848
1849#[cfg(test)]
1850mod tests {
1851 use super::*;
1852
1853 fn cell(text: &str) -> Rc<RefCell<Value>> {
1854 Rc::new(RefCell::new(Value::String(text.into())))
1855 }
1856
1857 #[test]
1865 fn freeze_child_takes_the_cell_the_child_ended_on() {
1866 let mut parent = Rule::new("parent", Value::Undefined);
1867 let mut child = Rule::new("child", Value::Undefined);
1868 parent.note_child_push(&child);
1869
1870 child.node = cell("done");
1871 parent.freeze_child(&child);
1872
1873 assert_eq!(
1874 *parent
1875 .child_cell
1876 .as_ref()
1877 .expect("a frozen child cell")
1878 .borrow(),
1879 Value::String("done".into()),
1880 "the freeze kept the push-time cell instead of the one the child ended on"
1881 );
1882 }
1883
1884 #[test]
1890 fn freeze_child_ignores_every_link_after_the_first() {
1891 let mut parent = Rule::new("parent", Value::Undefined);
1892 let mut pushed = Rule::new("pushed", Value::Undefined);
1893 parent.note_child_push(&pushed);
1894
1895 pushed.node = cell("pushed rule");
1896 parent.freeze_child(&pushed);
1897
1898 let mut tail = Rule::new("tail", Value::Undefined);
1901 tail.node = cell("chain tail");
1902 parent.freeze_child(&tail);
1903
1904 assert_eq!(
1905 *parent
1906 .child_cell
1907 .as_ref()
1908 .expect("a frozen child cell")
1909 .borrow(),
1910 Value::String("pushed rule".into()),
1911 "a later link of the replacement chain overwrote the child link"
1912 );
1913 }
1914
1915 #[test]
1926 fn a_callback_replacing_the_whole_child_rule_does_not_break_the_link() {
1927 let mut parent = Rule::new("parent", Value::Undefined);
1928 let mut child = Rule::new("child", Value::Undefined);
1929 parent.note_child_push(&child);
1930
1931 child = Rule::new("child", Value::Undefined);
1933 child.node = cell("done");
1934
1935 parent.freeze_child(&child);
1936
1937 assert_eq!(
1938 *parent
1939 .child_cell
1940 .as_ref()
1941 .expect("a frozen child cell")
1942 .borrow(),
1943 Value::String("done".into()),
1944 "replacing the rule value cost the parent its child link"
1945 );
1946 }
1947}