conjure_cp_essence_parser/parser/
keyword_checks.rs1use crate::errors::RecoverableParseError;
2
3const KEYWORDS: [&str; 21] = [
4 "forall", "exists", "such", "that", "letting", "find", "minimise", "maximise", "subject", "to",
5 "where", "and", "or", "not", "if", "then", "else", "in", "sum", "product", "bool",
6];
7
8pub fn keyword_as_identifier(
9 root: tree_sitter::Node,
10 source: &str,
11 errors: &mut Vec<RecoverableParseError>,
12) {
13 let mut stack = vec![root];
14 while let Some(node) = stack.pop() {
15 if (node.kind() == "variable" || node.kind() == "identifier" || node.kind() == "parameter")
16 && let Ok(text) = node.utf8_text(source.as_bytes())
17 {
18 let ident = text.trim();
19 if KEYWORDS.contains(&ident) {
20 let start_point = node.start_position();
21 let end_point = node.end_position();
22 errors.push(RecoverableParseError::new(
23 format!("Keyword '{ident}' used as identifier"),
24 Some(tree_sitter::Range {
25 start_byte: node.start_byte(),
26 end_byte: node.end_byte(),
27 start_point,
28 end_point,
29 }),
30 ));
31 }
32 }
33
34 for i in 0..node.child_count() {
35 if let Some(child) = u32::try_from(i).ok().and_then(|i| node.child(i)) {
36 stack.push(child);
37 }
38 }
39 }
40}