polka/parser/
symbols.rs

1use crate::dot::{AttributeType, GraphType};
2use crate::parser::ident::ident;
3
4use pom::parser::{end, one_of, sym, tag, Parser};
5// use pom::Parser;
6
7pub fn strict_symbol<'a>() -> Parser<'a, char, String> {
8  (tag("strict") | tag("STRICT")).map(|_| "strict".to_string())
9}
10
11pub fn graph_symbol<'a>() -> Parser<'a, char, AttributeType> {
12  (tag("graph") | tag("GRAPH")).map(|_| AttributeType::Graph)
13}
14
15pub fn digraph_symbol<'a>() -> Parser<'a, char, bool> {
16  (tag("digraph") | tag("DIGRAPH")).map(|_| true)
17}
18
19pub fn graph_type<'a>() -> Parser<'a, char, GraphType> {
20  graph_symbol().map(|_| GraphType::Graph) | digraph_symbol().map(|_| GraphType::Digraph)
21}
22
23pub fn subgraph_symbol<'a>() -> Parser<'a, char, bool> {
24  (tag("subgraph") | tag("SUBGRAPH")).map(|_| true)
25}
26
27pub fn node_symbol<'a>() -> Parser<'a, char, AttributeType> {
28  (tag("node") | tag("NODE")).map(|_| AttributeType::Node)
29}
30
31pub fn edge_symbol<'a>() -> Parser<'a, char, AttributeType> {
32  (tag("edge") | tag("EDGE")).map(|_| AttributeType::Edge)
33}
34
35pub fn space<'a>() -> Parser<'a, char, ()> {
36  one_of(" \t\r\n").repeat(0..).discard()
37}
38
39pub fn id<'a>() -> Parser<'a, char, String> {
40  ident()
41}
42
43pub fn comment<'a>() -> Parser<'a, char, ()> {
44  let eol = (sym('\n').discard() | end()).name("eol");
45  let not_eol = !(sym('\n').discard() | end()).name("not_eol");
46  (tag("//") - (not_eol).repeat(1..) - eol).discard()
47}
48
49
50#[cfg(test)]
51mod test {
52  #[cfg(test)]
53  mod comment {
54    use super::super::comment;
55
56    #[test]
57    fn mixed_tokens() {
58      let input1: Vec<char> = "// some stuff here.".chars().collect();
59      match comment().parse(&input1) {
60        Ok(r) => assert_eq!(r, ()),
61        Err(e) => panic!(format!(
62          "failed with input: {:?} with error: {:?}",
63          input1, e
64        )),
65      };
66    }
67
68  }
69
70  #[cfg(test)]
71  mod strict {
72    use super::super::strict_symbol;
73
74    #[test]
75    fn mixed_tokens() {
76      let input1: Vec<char> = "strict".chars().collect();
77      match strict_symbol().parse(&input1) {
78        Ok(r) => assert_eq!(r, "strict".to_string()),
79        _ => panic!(format!("failed with input: {:?}", input1)),
80      };
81
82      let input2: Vec<char> = "STRICT".chars().collect();
83      match strict_symbol().parse(&input2) {
84        Ok(r) => assert_eq!(r, "strict".to_string()),
85        _ => panic!(format!("failed with input: {:?}", input2)),
86      };
87
88      let input3: Vec<char> = "strect".chars().collect();
89      if strict_symbol().parse(&input3).is_ok() {
90        panic!("Should have failed")
91      }
92    }
93
94  }
95
96  #[cfg(test)]
97  mod graph {
98    use super::super::*;
99
100    #[test]
101    fn mixed_tokens() {
102      let input1: Vec<char> = "graph".chars().collect();
103      match graph_symbol().parse(&input1) {
104        Ok(r) => assert_eq!(r, AttributeType::Graph),
105        _ => panic!(format!("failed with input: {:?}", input1)),
106      };
107
108      let input2: Vec<char> = "GRAPH".chars().collect();
109      match graph_symbol().parse(&input2) {
110        Ok(r) => assert_eq!(r, AttributeType::Graph),
111        _ => panic!(format!("failed with input: {:?}", input2)),
112      };
113
114      let input3: Vec<char> = "greph".chars().collect();
115      if strict_symbol().parse(&input3).is_ok() {
116        panic!("Should have failed")
117      }
118    }
119
120  }
121
122  #[cfg(test)]
123  mod digraph {
124    use super::super::*;
125
126    #[test]
127    fn mixed_tokens() {
128      let input1: Vec<char> = "digraph".chars().collect();
129      match digraph_symbol().parse(&input1) {
130        Ok(r) => assert_eq!(r, true),
131        _ => panic!(format!("failed with input: {:?}", input1)),
132      };
133
134      let input2: Vec<char> = "DIGRAPH".chars().collect();
135      match digraph_symbol().parse(&input2) {
136        Ok(r) => assert_eq!(r, true),
137        _ => panic!(format!("failed with input: {:?}", input2)),
138      };
139
140      let input3: Vec<char> = "diegreph".chars().collect();
141      if strict_symbol().parse(&input3).is_ok() {
142        panic!("Should have failed")
143      }
144    }
145
146  }
147
148  #[cfg(test)]
149  mod subgraph {
150    use super::super::*;
151
152    #[test]
153    fn mixed_tokens() {
154      let input1: Vec<char> = "subgraph".chars().collect();
155      match subgraph_symbol().parse(&input1) {
156        Ok(r) => assert_eq!(r, true),
157        _ => panic!(format!("failed with input: {:?}", input1)),
158      };
159
160      let input2: Vec<char> = "SUBGRAPH".chars().collect();
161      match subgraph_symbol().parse(&input2) {
162        Ok(r) => assert_eq!(r, true),
163        _ => panic!(format!("failed with input: {:?}", input2)),
164      };
165
166      let input3: Vec<char> = "subgreph".chars().collect();
167      if strict_symbol().parse(&input3).is_ok() {
168        panic!("Should have failed")
169      }
170    }
171  }
172
173  #[cfg(test)]
174  mod node {
175    use super::super::*;
176
177    #[test]
178    fn mixed_tokens() {
179      let input1: Vec<char> = "node".chars().collect();
180      match node_symbol().parse(&input1) {
181        Ok(r) => assert_eq!(r, AttributeType::Node),
182        _ => panic!(format!("failed with input: {:?}", input1)),
183      };
184
185      let input2: Vec<char> = "NODE".chars().collect();
186      match node_symbol().parse(&input2) {
187        Ok(r) => assert_eq!(r, AttributeType::Node),
188        _ => panic!(format!("failed with input: {:?}", input2)),
189      };
190
191      let input3: Vec<char> = "nodd".chars().collect();
192      if strict_symbol().parse(&input3).is_ok() {
193        panic!("Should have failed")
194      }
195    }
196
197  }
198
199  #[cfg(test)]
200  mod edge {
201    use super::super::*;
202
203    #[test]
204    fn mixed_tokens() {
205      let input1: Vec<char> = "edge".chars().collect();
206      match edge_symbol().parse(&input1) {
207        Ok(r) => assert_eq!(r, AttributeType::Edge),
208        _ => panic!(format!("failed with input: {:?}", input1)),
209      };
210
211      let input2: Vec<char> = "EDGE".chars().collect();
212      match edge_symbol().parse(&input2) {
213        Ok(r) => assert_eq!(r, AttributeType::Edge),
214        _ => panic!(format!("failed with input: {:?}", input2)),
215      };
216
217      let input3: Vec<char> = "egde".chars().collect();
218      if strict_symbol().parse(&input3).is_ok() {
219        panic!("Should have failed")
220      }
221    }
222
223  }
224}