1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use nom::{
IResult,
character::complete::*,
bytes::complete::*,
};
use nom::branch::*;
use nom::combinator::*;
use nom::sequence::*;
use nom::multi::*;
use nom::AsChar;
use crate::{seimcolon_comment, Comment, comment};
use super::{
ArgOrComment,
};
type ArgOrCommentResult<'r> = IResult<&'r str, ArgOrComment<'r>>;
pub type ManyArgOrCommentsResult<'r> = IResult<&'r str, Option<Vec<ArgOrComment<'r>>>>;
fn string_arg<'r>(input: &'r str) -> ArgOrCommentResult<'r> {
map(
preceded(
space1,
escaped(
is_not("\n\r;("),
'\\',
one_of("(); \t\n\\"),
),
),
ArgOrComment::TextArg
)(input)
}
#[inline(always)]
fn key_value_arg<'r>(input: &'r str) -> ArgOrCommentResult<'r> {
map(
pair(
satisfy(AsChar::is_alpha),
opt(map_res(
is_not(" \t\n\r;("),
|s: &str| s.parse(),
)),
),
ArgOrComment::KeyValue,
)(input)
}
fn combine_args_and_comments<'r>(
parser_outputs: (Vec<ArgOrComment<'r>>, Option<&'r str>),
) -> Option<Vec<ArgOrComment<'r>>> {
let (mut args_or_comments, final_comment) = parser_outputs;
if let Some(final_comment) = final_comment {
args_or_comments.push(
ArgOrComment::Comment(Comment(final_comment)),
);
}
if args_or_comments.is_empty() {
None
} else {
Some(args_or_comments)
}
}
pub fn parse_args<'r>(
string_arg_mcode: bool,
input: &'r str,
) -> ManyArgOrCommentsResult<'r> {
if string_arg_mcode {
map(
tuple((
opt(map(comment, |c| ArgOrComment::Comment(c))),
opt(string_arg),
opt(map(comment, |c| ArgOrComment::Comment(c))),
),
),
|(c1, arg, c2)| Some(vec![c1, arg, c2].into_iter().flatten().collect()),
)(input)
} else {
map(
tuple((
many0(
alt((
preceded(
space1,
key_value_arg,
),
map(comment, |c| ArgOrComment::Comment(c)),
)),
),
opt(seimcolon_comment),
)),
combine_args_and_comments,
)(input)
}
}
pub fn parse_kv_arg<'r>(
input: &'r str,
) -> ArgOrCommentResult<'r> {
alt((
preceded(
space1,
key_value_arg,
),
map(comment, ArgOrComment::Comment),
))(input)
}