Struct Parser

Source
pub struct Parser<'a, I, O> {
    pub method: Box<dyn Fn(&'a [I], usize) -> Result<(O, usize)> + 'a>,
}
Expand description

Parser combinator.

Fields§

§method: Box<dyn Fn(&'a [I], usize) -> Result<(O, usize)> + 'a>

Implementations§

Source§

impl<'a, I, O> Parser<'a, I, O>

Source

pub fn new<P>(parse: P) -> Parser<'a, I, O>
where P: Fn(&'a [I], usize) -> Result<(O, usize)> + 'a,

Create new parser.

Source

pub fn parse(&self, input: &'a [I]) -> Result<O>

Apply the parser to parse input.

Examples found in repository?
examples/simple.rs (line 6)
3fn main() {
4	let input = b"abcde";
5	let parser = sym(b'a') * none_of(b"AB") - sym(b'c') + seq(b"de");
6	let output = parser.parse(input);
7	// assert_eq!(output, Ok( (b'b', &b"de"[..]) ) );
8	println!("{:?}", output);
9}
More examples
Hide additional examples
examples/duration.rs (line 77)
75fn main() {
76	let input = "P3Y6M4DT12H30M5S";
77	let result = parser().parse(input.as_bytes());
78
79	assert_eq!(
80		Duration {
81			years: Some(3f32),
82			months: Some(6f32),
83			weeks: None,
84			days: Some(4f32),
85			hours: Some(12f32),
86			minutes: Some(30f32),
87			seconds: Some(5f32)
88		},
89		result.unwrap()
90	);
91}
examples/whitespace.rs (line 72)
57fn container<'a>() -> Parser<'a, u8, Container> {
58	seq(b"Container\n") *
59	(
60		indented() |
61		empty().map(|()| vec![])
62	).repeat(1..).map(
63		|lines| lines.into_iter().filter(
64			|line| line.len() > 0
65		).fold(
66			vec![],
67			|accum, line| accum.into_iter().chain(
68				line.into_iter().chain(vec![b'\n'].into_iter())
69			).collect()
70		)
71	).map(|deden| {
72		subcontainer().parse(&deden).expect("subcont")
73	}).map(|(containers, contents)| Container { containers, contents })
74}
75
76fn mylang<'a>() -> Parser<'a, u8, Vec<Container>> {
77	(
78		whitespace() *
79		list(
80			call(container),
81			whitespace()
82		)
83	)
84}
85
86fn main() -> Result<(), ()> {
87	let input = br#"
88Container
89	Container
90		a
91		b
92		c
93
94	1
95	2
96	3
97
98	Container
99		q
100
101Container
102	foo
103	bar
104
105	Container
106		baz
107		quux
108		"#;
109
110	assert_eq!(
111		mylang().parse(input),
112		Ok(
113			vec![
114				Container {
115					containers: vec![
116						Container {
117							containers: vec![],
118							contents: vec![
119								"a".into(),
120								"b".into(),
121								"c".into(),
122							]
123						},
124						Container {
125							containers: vec![],
126							contents: vec![
127								"q".into(),
128							]
129						}
130					],
131					contents: vec![
132						"1".into(),
133						"2".into(),
134						"3".into(),
135					]
136				},
137				Container {
138					containers: vec![
139						Container {
140							contents: vec![
141								"baz".into(),
142								"quux".into(),
143							],
144							containers: vec![],
145						},
146					],
147					contents: vec![
148						"foo".into(),
149						"bar".into(),
150					]
151				},
152			]
153		)
154	);
155
156	Ok(())
157}
examples/json.rs (line 88)
70fn main() {
71	let input = br#"
72	{
73        "Image": {
74            "Width":  800,
75            "Height": 600,
76            "Title":  "View from 15th Floor",
77            "Thumbnail": {
78                "Url":    "http://www.example.com/image/481989943",
79                "Height": 125,
80                "Width":  100
81            },
82            "Animated" : false,
83            "IDs": [116, 943, 234, 38793]
84        },
85        "escaped characters": "\u2192\uD83D\uDE00\"\t\uD834\uDD1E"
86    }"#;
87
88	println!("{:?}", json().parse(input));
89}
examples/json_char.rs (line 106)
87fn main() {
88	let test = r#"
89	{
90        "Image": {
91            "Width":  800,
92            "Height": 600,
93            "Title":  "View from 15th Floor",
94            "Thumbnail": {
95                "Url":    "http://www.example.com/image/481989943",
96                "Height": 125,
97                "Width":  100
98            },
99            "Animated" : false,
100            "IDs": [116, 943, 234, 38793]
101        },
102        "escaped characters": "\u2192\uD83D\uDE00\"\t\uD834\uDD1E"
103    }"#;
104
105	let input: Vec<char> = test.chars().collect();
106	println!("{:?}", json().parse(&input));
107}
Source

pub fn parse_at(&self, input: &'a [I], start: usize) -> Result<(O, usize)>

Parse input at specified position.

Source

pub fn map<U, F>(self, f: F) -> Parser<'a, I, U>
where F: Fn(O) -> U + 'a, I: 'a, O: 'a, U: 'a,

Convert parser result to desired value.

Examples found in repository?
examples/duration.rs (line 37)
32fn date_part() -> Parser<u8, (Option<f32>, Option<f32>, Option<f32>, Option<f32>)> {
33	((number() - sym(b'Y')).opt()
34		+ (number() - sym(b'M')).opt()
35		+ (number() - sym(b'W')).opt()
36		+ (number() - sym(b'D')).opt())
37	.map(|(((years, months), weeks), days)| (years, months, weeks, days))
38}
39
40fn time_part() -> Parser<u8, (Option<f32>, Option<f32>, Option<f32>)> {
41	sym(b'T')
42		* ((number() - sym(b'H')).opt()
43			+ (number() - sym(b'M')).opt()
44			+ (number() - sym(b'S')).opt())
45		.map(|((hours, minutes), seconds)| (hours, minutes, seconds))
46}
47
48fn parser() -> Parser<u8, Duration> {
49	sym(b'P')
50		* (time_part().map(|(hours, minutes, seconds)| Duration {
51			years: None,
52			months: None,
53			weeks: None,
54			days: None,
55			hours,
56			minutes,
57			seconds,
58		}) | (date_part() + time_part()).map(|(date_elements, time_elements)| {
59			let (years, months, weeks, days) = date_elements;
60			let (hours, minutes, seconds) = time_elements;
61			Duration {
62				years,
63				months,
64				weeks,
65				days,
66				hours,
67				minutes,
68				seconds,
69			}
70		}))
71}
More examples
Hide additional examples
examples/json_char.rs (line 29)
22fn number<'a>() -> Parser<'a, char, f64> {
23	let integer = one_of("123456789") - one_of("0123456789").repeat(0..) | sym('0');
24	let frac = sym('.') + one_of("0123456789").repeat(1..);
25	let exp = one_of("eE") + one_of("+-").opt() + one_of("0123456789").repeat(1..);
26	let number = sym('-').opt() + integer + frac.opt() + exp.opt();
27	number
28		.collect()
29		.map(String::from_iter)
30		.convert(|s| f64::from_str(&s))
31}
32
33fn string<'a>() -> Parser<'a, char, String> {
34	let special_char = sym('\\')
35		| sym('/')
36		| sym('"')
37		| sym('b').map(|_| '\x08')
38		| sym('f').map(|_| '\x0C')
39		| sym('n').map(|_| '\n')
40		| sym('r').map(|_| '\r')
41		| sym('t').map(|_| '\t');
42	let escape_sequence = sym('\\') * special_char;
43	let char_string = (none_of("\\\"") | escape_sequence)
44		.repeat(1..)
45		.map(String::from_iter);
46	let utf16_char = tag("\\u") * is_a(|c: char| c.is_digit(16))
47		.repeat(4)
48		.map(String::from_iter)
49		.convert(|digits| u16::from_str_radix(&digits, 16));
50	let utf16_string = utf16_char.repeat(1..).map(|chars| {
51		decode_utf16(chars)
52			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
53			.collect::<String>()
54	});
55	let string = sym('"') * (char_string | utf16_string).repeat(0..) - sym('"');
56	string.map(|strings| strings.concat())
57}
58
59fn array<'a>() -> Parser<'a, char, Vec<JsonValue>> {
60	let elems = list(call(value), sym(',') * space());
61	sym('[') * space() * elems - sym(']')
62}
63
64fn object<'a>() -> Parser<'a, char, HashMap<String, JsonValue>> {
65	let member = string() - space() - sym(':') - space() + call(value);
66	let members = list(member, sym(',') * space());
67	let obj = sym('{') * space() * members - sym('}');
68	obj.map(|members| members.into_iter().collect::<HashMap<_, _>>())
69}
70
71fn value<'a>() -> Parser<'a, char, JsonValue> {
72	(tag("null").map(|_| JsonValue::Null)
73		| tag("true").map(|_| JsonValue::Bool(true))
74		| tag("false").map(|_| JsonValue::Bool(false))
75		| number().map(|num| JsonValue::Num(num))
76		| string().map(|text| JsonValue::Str(text))
77		| array().map(|arr| JsonValue::Array(arr))
78		| object().map(|obj| JsonValue::Object(obj)))
79		- space()
80}
examples/whitespace.rs (line 36)
34fn subcontainer<'a>() -> Parser<'a, u8, (Vec<Container>, Vec<String>)> {
35	(
36		call(container).map(|ctr| TmpContainerOrContent::Container(ctr)) |
37		content().map(|ctn| TmpContainerOrContent::Content(ctn))
38	).repeat(1..).map(
39		|tmp| {
40			tmp.into_iter().fold(
41				(vec![], vec![]),
42				|acc, x| match x {
43					TmpContainerOrContent::Container(ct) => (
44						acc.0.into_iter().chain(vec![ct].into_iter()).collect(),
45						acc.1,
46					),
47					TmpContainerOrContent::Content(cn) => (
48						acc.0,
49						acc.1.into_iter().chain(vec![cn].into_iter()).collect(),
50					),
51				}
52			)
53		}
54	)
55}
56
57fn container<'a>() -> Parser<'a, u8, Container> {
58	seq(b"Container\n") *
59	(
60		indented() |
61		empty().map(|()| vec![])
62	).repeat(1..).map(
63		|lines| lines.into_iter().filter(
64			|line| line.len() > 0
65		).fold(
66			vec![],
67			|accum, line| accum.into_iter().chain(
68				line.into_iter().chain(vec![b'\n'].into_iter())
69			).collect()
70		)
71	).map(|deden| {
72		subcontainer().parse(&deden).expect("subcont")
73	}).map(|(containers, contents)| Container { containers, contents })
74}
examples/json.rs (line 32)
30fn string<'a>() -> Parser<'a, u8, String> {
31	let special_char = sym(b'\\') | sym(b'/') | sym(b'"')
32		| sym(b'b').map(|_|b'\x08') | sym(b'f').map(|_|b'\x0C')
33		| sym(b'n').map(|_|b'\n') | sym(b'r').map(|_|b'\r') | sym(b't').map(|_|b'\t');
34	let escape_sequence = sym(b'\\') * special_char;
35	let char_string = (none_of(b"\\\"") | escape_sequence).repeat(1..).convert(String::from_utf8);
36	let utf16_char = seq(b"\\u") * is_a(hex_digit).repeat(4).convert(String::from_utf8).convert(|digits|u16::from_str_radix(&digits, 16));
37	let utf16_string = utf16_char.repeat(1..).map(|chars|decode_utf16(chars).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect::<String>());
38	let string = sym(b'"') * (char_string | utf16_string).repeat(0..) - sym(b'"');
39	string.map(|strings| strings.concat())
40}
41
42fn array<'a>() -> Parser<'a, u8, Vec<JsonValue>> {
43	let elems = list(call(value), sym(b',') * space());
44	sym(b'[') * space() * elems - sym(b']')
45}
46
47fn object<'a>() -> Parser<'a, u8, HashMap<String, JsonValue>> {
48	let member = string() - space() - sym(b':') - space() + call(value);
49	let members = list(member, sym(b',') * space());
50	let obj = sym(b'{') * space() * members - sym(b'}');
51	obj.map(|members| members.into_iter().collect::<HashMap<_, _>>())
52}
53
54fn value<'a>() -> Parser<'a, u8, JsonValue> {
55	( seq(b"null").map(|_|JsonValue::Null)
56	| seq(b"true").map(|_|JsonValue::Bool(true))
57	| seq(b"false").map(|_|JsonValue::Bool(false))
58	| number().map(|num|JsonValue::Num(num))
59	| string().map(|text|JsonValue::Str(text))
60	| array().map(|arr|JsonValue::Array(arr))
61	| object().map(|obj|JsonValue::Object(obj))
62	) - space()
63}
Source

pub fn convert<U, E, F>(self, f: F) -> Parser<'a, I, U>
where F: Fn(O) -> Result<U, E> + 'a, E: Debug, O: 'a, U: 'a,

Convert parser result to desired value, fail in case of conversion error.

Examples found in repository?
examples/whitespace.rs (line 31)
30fn content<'a>() -> Parser<'a, u8, String> {
31	none_of(b" \t\r\n").repeat(1..).convert(String::from_utf8) - linebreak()
32}
More examples
Hide additional examples
examples/duration.rs (line 28)
22fn number() -> Parser<u8, f32> {
23	let integer = one_of(b"0123456789").repeat(0..);
24	let frac = number_separator() + one_of(b"0123456789").repeat(1..);
25	let number = integer + frac.opt();
26	number
27		.collect()
28		.convert(str::from_utf8)
29		.convert(f32::from_str)
30}
examples/json.rs (line 27)
22fn number<'a>() -> Parser<'a, u8, f64> {
23	let integer = one_of(b"123456789") - one_of(b"0123456789").repeat(0..) | sym(b'0');
24	let frac = sym(b'.') + one_of(b"0123456789").repeat(1..);
25	let exp = one_of(b"eE") + one_of(b"+-").opt() + one_of(b"0123456789").repeat(1..);
26	let number = sym(b'-').opt() + integer + frac.opt() + exp.opt();
27	number.collect().convert(str::from_utf8).convert(f64::from_str)
28}
29
30fn string<'a>() -> Parser<'a, u8, String> {
31	let special_char = sym(b'\\') | sym(b'/') | sym(b'"')
32		| sym(b'b').map(|_|b'\x08') | sym(b'f').map(|_|b'\x0C')
33		| sym(b'n').map(|_|b'\n') | sym(b'r').map(|_|b'\r') | sym(b't').map(|_|b'\t');
34	let escape_sequence = sym(b'\\') * special_char;
35	let char_string = (none_of(b"\\\"") | escape_sequence).repeat(1..).convert(String::from_utf8);
36	let utf16_char = seq(b"\\u") * is_a(hex_digit).repeat(4).convert(String::from_utf8).convert(|digits|u16::from_str_radix(&digits, 16));
37	let utf16_string = utf16_char.repeat(1..).map(|chars|decode_utf16(chars).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect::<String>());
38	let string = sym(b'"') * (char_string | utf16_string).repeat(0..) - sym(b'"');
39	string.map(|strings| strings.concat())
40}
examples/json_char.rs (line 30)
22fn number<'a>() -> Parser<'a, char, f64> {
23	let integer = one_of("123456789") - one_of("0123456789").repeat(0..) | sym('0');
24	let frac = sym('.') + one_of("0123456789").repeat(1..);
25	let exp = one_of("eE") + one_of("+-").opt() + one_of("0123456789").repeat(1..);
26	let number = sym('-').opt() + integer + frac.opt() + exp.opt();
27	number
28		.collect()
29		.map(String::from_iter)
30		.convert(|s| f64::from_str(&s))
31}
32
33fn string<'a>() -> Parser<'a, char, String> {
34	let special_char = sym('\\')
35		| sym('/')
36		| sym('"')
37		| sym('b').map(|_| '\x08')
38		| sym('f').map(|_| '\x0C')
39		| sym('n').map(|_| '\n')
40		| sym('r').map(|_| '\r')
41		| sym('t').map(|_| '\t');
42	let escape_sequence = sym('\\') * special_char;
43	let char_string = (none_of("\\\"") | escape_sequence)
44		.repeat(1..)
45		.map(String::from_iter);
46	let utf16_char = tag("\\u") * is_a(|c: char| c.is_digit(16))
47		.repeat(4)
48		.map(String::from_iter)
49		.convert(|digits| u16::from_str_radix(&digits, 16));
50	let utf16_string = utf16_char.repeat(1..).map(|chars| {
51		decode_utf16(chars)
52			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
53			.collect::<String>()
54	});
55	let string = sym('"') * (char_string | utf16_string).repeat(0..) - sym('"');
56	string.map(|strings| strings.concat())
57}
Source

pub fn cache(self) -> Parser<'a, I, O>
where O: Clone + 'a,

Cache parser output result to speed up backtracking.

Source

pub fn pos(self) -> Parser<'a, I, usize>
where O: 'a,

Get input position after matching parser.

Source

pub fn collect(self) -> Parser<'a, I, &'a [I]>
where O: 'a,

Collect all matched input symbols.

Examples found in repository?
examples/duration.rs (line 27)
22fn number() -> Parser<u8, f32> {
23	let integer = one_of(b"0123456789").repeat(0..);
24	let frac = number_separator() + one_of(b"0123456789").repeat(1..);
25	let number = integer + frac.opt();
26	number
27		.collect()
28		.convert(str::from_utf8)
29		.convert(f32::from_str)
30}
More examples
Hide additional examples
examples/json.rs (line 27)
22fn number<'a>() -> Parser<'a, u8, f64> {
23	let integer = one_of(b"123456789") - one_of(b"0123456789").repeat(0..) | sym(b'0');
24	let frac = sym(b'.') + one_of(b"0123456789").repeat(1..);
25	let exp = one_of(b"eE") + one_of(b"+-").opt() + one_of(b"0123456789").repeat(1..);
26	let number = sym(b'-').opt() + integer + frac.opt() + exp.opt();
27	number.collect().convert(str::from_utf8).convert(f64::from_str)
28}
examples/json_char.rs (line 28)
22fn number<'a>() -> Parser<'a, char, f64> {
23	let integer = one_of("123456789") - one_of("0123456789").repeat(0..) | sym('0');
24	let frac = sym('.') + one_of("0123456789").repeat(1..);
25	let exp = one_of("eE") + one_of("+-").opt() + one_of("0123456789").repeat(1..);
26	let number = sym('-').opt() + integer + frac.opt() + exp.opt();
27	number
28		.collect()
29		.map(String::from_iter)
30		.convert(|s| f64::from_str(&s))
31}
Source

pub fn discard(self) -> Parser<'a, I, ()>
where O: 'a,

Discard parser output.

Examples found in repository?
examples/json.rs (line 19)
18fn space<'a>() -> Parser<'a, u8, ()> {
19	one_of(b" \t\r\n").repeat(0..).discard()
20}
More examples
Hide additional examples
examples/json_char.rs (line 19)
18fn space<'a>() -> Parser<'a, char, ()> {
19	one_of(" \t\r\n").repeat(0..).discard()
20}
examples/whitespace.rs (line 15)
14fn whitespace<'a>() -> Parser<'a, u8, ()> {
15	one_of(b" \t\r\n").repeat(0..).discard()
16}
17
18fn linebreak<'a>() -> Parser<'a, u8, ()> {
19	sym(b'\r').opt() * sym(b'\n').discard()
20}
21
22fn indented<'a>() -> Parser<'a, u8, Vec<u8>> {
23	sym(b'\t') * none_of(b"\n\r").repeat(1..) - linebreak()
24}
25
26fn empty<'a>() -> Parser<'a, u8, ()> {
27	one_of(b" \t").repeat(0..).discard() - linebreak()
28}
examples/duration.rs (line 19)
17fn number_separator() -> Parser<u8, ()> {
18	// either '.' or ',' can be used as a separator between the whole and decimal part of a number
19	one_of(b".,").discard()
20}
Source

pub fn opt(self) -> Parser<'a, I, Option<O>>
where O: 'a,

Make parser optional.

Examples found in repository?
examples/whitespace.rs (line 19)
18fn linebreak<'a>() -> Parser<'a, u8, ()> {
19	sym(b'\r').opt() * sym(b'\n').discard()
20}
More examples
Hide additional examples
examples/duration.rs (line 25)
22fn number() -> Parser<u8, f32> {
23	let integer = one_of(b"0123456789").repeat(0..);
24	let frac = number_separator() + one_of(b"0123456789").repeat(1..);
25	let number = integer + frac.opt();
26	number
27		.collect()
28		.convert(str::from_utf8)
29		.convert(f32::from_str)
30}
31
32fn date_part() -> Parser<u8, (Option<f32>, Option<f32>, Option<f32>, Option<f32>)> {
33	((number() - sym(b'Y')).opt()
34		+ (number() - sym(b'M')).opt()
35		+ (number() - sym(b'W')).opt()
36		+ (number() - sym(b'D')).opt())
37	.map(|(((years, months), weeks), days)| (years, months, weeks, days))
38}
39
40fn time_part() -> Parser<u8, (Option<f32>, Option<f32>, Option<f32>)> {
41	sym(b'T')
42		* ((number() - sym(b'H')).opt()
43			+ (number() - sym(b'M')).opt()
44			+ (number() - sym(b'S')).opt())
45		.map(|((hours, minutes), seconds)| (hours, minutes, seconds))
46}
examples/json.rs (line 25)
22fn number<'a>() -> Parser<'a, u8, f64> {
23	let integer = one_of(b"123456789") - one_of(b"0123456789").repeat(0..) | sym(b'0');
24	let frac = sym(b'.') + one_of(b"0123456789").repeat(1..);
25	let exp = one_of(b"eE") + one_of(b"+-").opt() + one_of(b"0123456789").repeat(1..);
26	let number = sym(b'-').opt() + integer + frac.opt() + exp.opt();
27	number.collect().convert(str::from_utf8).convert(f64::from_str)
28}
examples/json_char.rs (line 25)
22fn number<'a>() -> Parser<'a, char, f64> {
23	let integer = one_of("123456789") - one_of("0123456789").repeat(0..) | sym('0');
24	let frac = sym('.') + one_of("0123456789").repeat(1..);
25	let exp = one_of("eE") + one_of("+-").opt() + one_of("0123456789").repeat(1..);
26	let number = sym('-').opt() + integer + frac.opt() + exp.opt();
27	number
28		.collect()
29		.map(String::from_iter)
30		.convert(|s| f64::from_str(&s))
31}
Source

pub fn repeat<R>(self, range: R) -> Parser<'a, I, Vec<O>>
where R: RangeArgument<usize> + Debug + 'a, O: 'a,

p.repeat(5) repeat p exactly 5 times p.repeat(0..) repeat p zero or more times p.repeat(1..) repeat p one or more times p.repeat(1..4) match p at least 1 and at most 3 times

Examples found in repository?
examples/json.rs (line 19)
18fn space<'a>() -> Parser<'a, u8, ()> {
19	one_of(b" \t\r\n").repeat(0..).discard()
20}
21
22fn number<'a>() -> Parser<'a, u8, f64> {
23	let integer = one_of(b"123456789") - one_of(b"0123456789").repeat(0..) | sym(b'0');
24	let frac = sym(b'.') + one_of(b"0123456789").repeat(1..);
25	let exp = one_of(b"eE") + one_of(b"+-").opt() + one_of(b"0123456789").repeat(1..);
26	let number = sym(b'-').opt() + integer + frac.opt() + exp.opt();
27	number.collect().convert(str::from_utf8).convert(f64::from_str)
28}
29
30fn string<'a>() -> Parser<'a, u8, String> {
31	let special_char = sym(b'\\') | sym(b'/') | sym(b'"')
32		| sym(b'b').map(|_|b'\x08') | sym(b'f').map(|_|b'\x0C')
33		| sym(b'n').map(|_|b'\n') | sym(b'r').map(|_|b'\r') | sym(b't').map(|_|b'\t');
34	let escape_sequence = sym(b'\\') * special_char;
35	let char_string = (none_of(b"\\\"") | escape_sequence).repeat(1..).convert(String::from_utf8);
36	let utf16_char = seq(b"\\u") * is_a(hex_digit).repeat(4).convert(String::from_utf8).convert(|digits|u16::from_str_radix(&digits, 16));
37	let utf16_string = utf16_char.repeat(1..).map(|chars|decode_utf16(chars).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect::<String>());
38	let string = sym(b'"') * (char_string | utf16_string).repeat(0..) - sym(b'"');
39	string.map(|strings| strings.concat())
40}
More examples
Hide additional examples
examples/json_char.rs (line 19)
18fn space<'a>() -> Parser<'a, char, ()> {
19	one_of(" \t\r\n").repeat(0..).discard()
20}
21
22fn number<'a>() -> Parser<'a, char, f64> {
23	let integer = one_of("123456789") - one_of("0123456789").repeat(0..) | sym('0');
24	let frac = sym('.') + one_of("0123456789").repeat(1..);
25	let exp = one_of("eE") + one_of("+-").opt() + one_of("0123456789").repeat(1..);
26	let number = sym('-').opt() + integer + frac.opt() + exp.opt();
27	number
28		.collect()
29		.map(String::from_iter)
30		.convert(|s| f64::from_str(&s))
31}
32
33fn string<'a>() -> Parser<'a, char, String> {
34	let special_char = sym('\\')
35		| sym('/')
36		| sym('"')
37		| sym('b').map(|_| '\x08')
38		| sym('f').map(|_| '\x0C')
39		| sym('n').map(|_| '\n')
40		| sym('r').map(|_| '\r')
41		| sym('t').map(|_| '\t');
42	let escape_sequence = sym('\\') * special_char;
43	let char_string = (none_of("\\\"") | escape_sequence)
44		.repeat(1..)
45		.map(String::from_iter);
46	let utf16_char = tag("\\u") * is_a(|c: char| c.is_digit(16))
47		.repeat(4)
48		.map(String::from_iter)
49		.convert(|digits| u16::from_str_radix(&digits, 16));
50	let utf16_string = utf16_char.repeat(1..).map(|chars| {
51		decode_utf16(chars)
52			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
53			.collect::<String>()
54	});
55	let string = sym('"') * (char_string | utf16_string).repeat(0..) - sym('"');
56	string.map(|strings| strings.concat())
57}
examples/whitespace.rs (line 15)
14fn whitespace<'a>() -> Parser<'a, u8, ()> {
15	one_of(b" \t\r\n").repeat(0..).discard()
16}
17
18fn linebreak<'a>() -> Parser<'a, u8, ()> {
19	sym(b'\r').opt() * sym(b'\n').discard()
20}
21
22fn indented<'a>() -> Parser<'a, u8, Vec<u8>> {
23	sym(b'\t') * none_of(b"\n\r").repeat(1..) - linebreak()
24}
25
26fn empty<'a>() -> Parser<'a, u8, ()> {
27	one_of(b" \t").repeat(0..).discard() - linebreak()
28}
29
30fn content<'a>() -> Parser<'a, u8, String> {
31	none_of(b" \t\r\n").repeat(1..).convert(String::from_utf8) - linebreak()
32}
33
34fn subcontainer<'a>() -> Parser<'a, u8, (Vec<Container>, Vec<String>)> {
35	(
36		call(container).map(|ctr| TmpContainerOrContent::Container(ctr)) |
37		content().map(|ctn| TmpContainerOrContent::Content(ctn))
38	).repeat(1..).map(
39		|tmp| {
40			tmp.into_iter().fold(
41				(vec![], vec![]),
42				|acc, x| match x {
43					TmpContainerOrContent::Container(ct) => (
44						acc.0.into_iter().chain(vec![ct].into_iter()).collect(),
45						acc.1,
46					),
47					TmpContainerOrContent::Content(cn) => (
48						acc.0,
49						acc.1.into_iter().chain(vec![cn].into_iter()).collect(),
50					),
51				}
52			)
53		}
54	)
55}
56
57fn container<'a>() -> Parser<'a, u8, Container> {
58	seq(b"Container\n") *
59	(
60		indented() |
61		empty().map(|()| vec![])
62	).repeat(1..).map(
63		|lines| lines.into_iter().filter(
64			|line| line.len() > 0
65		).fold(
66			vec![],
67			|accum, line| accum.into_iter().chain(
68				line.into_iter().chain(vec![b'\n'].into_iter())
69			).collect()
70		)
71	).map(|deden| {
72		subcontainer().parse(&deden).expect("subcont")
73	}).map(|(containers, contents)| Container { containers, contents })
74}
examples/duration.rs (line 23)
22fn number() -> Parser<u8, f32> {
23	let integer = one_of(b"0123456789").repeat(0..);
24	let frac = number_separator() + one_of(b"0123456789").repeat(1..);
25	let number = integer + frac.opt();
26	number
27		.collect()
28		.convert(str::from_utf8)
29		.convert(f32::from_str)
30}
Source

pub fn name(self, name: &'a str) -> Parser<'a, I, O>
where O: 'a,

Give parser a name to identify parsing errors.

Source

pub fn expect(self, name: &'a str) -> Parser<'a, I, O>
where O: 'a,

Mark parser as expected, abort early when failed in ordered choice.

Trait Implementations§

Source§

impl<'a, I, O: 'a, U: 'a> Add<Parser<'a, I, U>> for Parser<'a, I, O>

Sequence reserve value

Source§

type Output = Parser<'a, I, (O, U)>

The resulting type after applying the + operator.
Source§

fn add(self, other: Parser<'a, I, U>) -> Self::Output

Performs the + operation. Read more
Source§

impl<'a, I, O: 'a> BitOr for Parser<'a, I, O>

Ordered choice

Source§

type Output = Parser<'a, I, O>

The resulting type after applying the | operator.
Source§

fn bitor(self, other: Parser<'a, I, O>) -> Self::Output

Performs the | operation. Read more
Source§

impl<'a, I: 'a, O: 'a, U: 'a> Mul<Parser<'a, I, U>> for Parser<'a, I, O>

Sequence discard first value

Source§

type Output = Parser<'a, I, U>

The resulting type after applying the * operator.
Source§

fn mul(self, other: Parser<'a, I, U>) -> Self::Output

Performs the * operation. Read more
Source§

impl<'a, I, O: 'a> Neg for Parser<'a, I, O>

And predicate

Source§

type Output = Parser<'a, I, bool>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Self::Output

Performs the unary - operation. Read more
Source§

impl<'a, I, O: 'a> Not for Parser<'a, I, O>

Not predicate

Source§

type Output = Parser<'a, I, bool>

The resulting type after applying the ! operator.
Source§

fn not(self) -> Self::Output

Performs the unary ! operation. Read more
Source§

impl<'a, I, O: 'a, U: 'a, F: Fn(O) -> Parser<'a, I, U> + 'a> Shr<F> for Parser<'a, I, O>

Chain two parsers where the second parser depends on the first’s result.

Source§

type Output = Parser<'a, I, U>

The resulting type after applying the >> operator.
Source§

fn shr(self, other: F) -> Self::Output

Performs the >> operation. Read more
Source§

impl<'a, I, O: 'a, U: 'a> Sub<Parser<'a, I, U>> for Parser<'a, I, O>

Sequence discard second value

Source§

type Output = Parser<'a, I, O>

The resulting type after applying the - operator.
Source§

fn sub(self, other: Parser<'a, I, U>) -> Self::Output

Performs the - operation. Read more

Auto Trait Implementations§

§

impl<'a, I, O> Freeze for Parser<'a, I, O>

§

impl<'a, I, O> !RefUnwindSafe for Parser<'a, I, O>

§

impl<'a, I, O> !Send for Parser<'a, I, O>

§

impl<'a, I, O> !Sync for Parser<'a, I, O>

§

impl<'a, I, O> Unpin for Parser<'a, I, O>

§

impl<'a, I, O> !UnwindSafe for Parser<'a, I, O>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.