1use winnow::ascii::{multispace0, newline, till_line_ending};
2use winnow::combinator::opt;
3use winnow::token::literal;
4use winnow::{ModalResult as WResult, Parser};
5
6#[derive(Debug)]
7enum DslStatus {
8 Comment,
9 Code,
10}
11pub struct CommentParser {}
12impl Default for CommentParser {
13 fn default() -> Self {
14 Self::new()
15 }
16}
17
18impl CommentParser {
19 pub fn new() -> Self {
20 CommentParser {}
21 }
22 pub fn ignore_comment(input: &mut &str) -> WResult<String> {
23 let mut status = DslStatus::Code;
24 let mut out = String::new();
25 while !input.is_empty() {
26 match status {
27 DslStatus::Code => {
28 multispace0.parse_next(input)?;
29 let long_comment: WResult<&str> = literal("/*").parse_next(input);
30 if long_comment.is_ok() {
31 status = DslStatus::Comment;
32 continue;
33 }
34 let short_comment: WResult<&str> = literal("//").parse_next(input);
35 if short_comment.is_ok() {
36 let _ = till_line_ending.parse_next(input)?;
37 continue;
38 }
39 let code = till_line_ending.parse_next(input)?;
40 out += code;
41 if opt(newline).parse_next(input)?.is_some() {
42 out += "\n";
43 }
44 continue;
45 }
46
47 DslStatus::Comment => {
48 multispace0.parse_next(input)?;
49 let is_end: WResult<&str> = literal("*/").parse_next(input);
50 if is_end.is_ok() {
51 status = DslStatus::Code;
52 continue;
53 }
54 let _ = till_line_ending.parse_next(input)?;
55 opt(newline).parse_next(input)?;
56 }
57 }
58 }
59 Ok(out)
60 }
61}
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_comment() {
68 let mut code = r#"
69 a=1;
70 //b=1;
71 /*
72 c=1;
73 d=1;
74 */
75 x=1;
76 "#;
77
78 let p_code = CommentParser::ignore_comment(&mut code).expect("ignore comment fail");
79 println!("{}", p_code)
80 }
81}