u8_custom_parser/
u8_custom_parser.rs1use nom::branch::*;
2use nom::character::complete::*;
3use nom::{IResult, InputIter, Needed, Slice};
4use nom_locate::LocatedSpan;
5use nom_tracable::{cumulative_histogram, histogram, tracable_parser, TracableInfo};
6#[cfg(feature = "trace")]
7use nom_tracable::{HasTracableInfo, Tracable};
8
9#[derive(Clone)]
10pub struct Span<'a>(LocatedSpan<&'a [u8], TracableInfo>);
11
12#[cfg(feature = "trace")]
13impl<'a> HasTracableInfo for Span<'a> {
14 fn get_tracable_info(&self) -> TracableInfo {
15 self.0.get_tracable_info()
16 }
17
18 fn set_tracable_info(mut self, info: TracableInfo) -> Self {
19 self.0 = self.0.set_tracable_info(info);
20 self
21 }
22}
23#[cfg(feature = "trace")]
24impl<'a> Tracable for Span<'a> {
25 fn inc_depth(mut self) -> Self {
26 self.0 = self.0.inc_depth();
27 self
28 }
29
30 fn dec_depth(mut self) -> Self {
31 self.0 = self.0.dec_depth();
32 self
33 }
34
35 fn format(&self) -> String {
37 let info = self.get_tracable_info();
38 let fragment: String = String::from_utf8_lossy(self.0.fragment())
39 .lines()
40 .next()
41 .unwrap_or_else(|| "")
42 .chars()
43 .take(info.fragment_width)
44 .collect();
45 format!("{:<8} : {}", self.0.location_offset(), fragment)
46 }
47
48 fn header(&self) -> String {
49 self.0.header()
50 }
51}
52impl<'a> InputIter for Span<'a> {
53 type Item = u8;
54 type Iter = std::iter::Enumerate<Self::IterElem>;
55 type IterElem = std::iter::Copied<std::slice::Iter<'a, Self::Item>>;
56 #[inline]
57 fn iter_indices(&self) -> Self::Iter {
58 self.0.iter_indices()
59 }
60 #[inline]
61 fn iter_elements(&self) -> Self::IterElem {
62 self.0.iter_elements()
63 }
64 #[inline]
65 fn position<P>(&self, predicate: P) -> Option<usize>
66 where
67 P: Fn(Self::Item) -> bool,
68 {
69 self.0.position(predicate)
70 }
71 #[inline]
72 fn slice_index(&self, count: usize) -> Result<usize, Needed> {
73 self.0.slice_index(count)
74 }
75}
76impl<'a> Slice<std::ops::RangeFrom<usize>> for Span<'a> {
77 fn slice(&self, range: std::ops::RangeFrom<usize>) -> Self {
78 Span(self.0.slice(range))
79 }
80}
81
82#[tracable_parser]
84pub fn expr(s: Span) -> IResult<Span, String> {
85 alt((expr_plus, expr_minus, term))(s)
86}
87
88#[tracable_parser]
89pub fn expr_plus(s: Span) -> IResult<Span, String> {
90 let (s, x) = term(s)?;
91 let (s, y) = char('+')(s)?;
92 let (s, z) = expr(s)?;
93 let ret = format!("{}{}{}", x, y, z);
94 Ok((s, ret))
95}
96
97#[tracable_parser]
98pub fn expr_minus(s: Span) -> IResult<Span, String> {
99 let (s, x) = term(s)?;
100 let (s, y) = char('-')(s)?;
101 let (s, z) = expr(s)?;
102 let ret = format!("{}{}{}", x, y, z);
103 Ok((s, ret))
104}
105
106#[tracable_parser]
107pub fn term(s: Span) -> IResult<Span, String> {
108 let (s, x) = term_internal(s)?;
109 Ok((s, x))
110}
111
112#[tracable_parser]
113pub fn term_internal(s: Span) -> IResult<Span, String> {
114 let (s, x) = char('1')(s)?;
115 Ok((s, x.to_string()))
116}
117
118fn main() {
119 let info = TracableInfo::new()
121 .parser_width(64)
122 .fragment_width(20)
123 .fold("term");
124 let _ret = expr(Span(LocatedSpan::new_extra("1-1+1+1-1".as_bytes(), info)));
125
126 histogram();
128 cumulative_histogram();
129}