sqruff_lib_dialects/
db2.rs1use itertools::Itertools;
2use sqruff_lib_core::dialects::Dialect;
3use sqruff_lib_core::dialects::init::DialectKind;
4use sqruff_lib_core::dialects::syntax::SyntaxKind;
5use sqruff_lib_core::helpers::{Config, ToMatchable};
6use sqruff_lib_core::parser::grammar::Ref;
7use sqruff_lib_core::parser::grammar::anyof::{AnyNumberOf, one_of};
8use sqruff_lib_core::parser::grammar::sequence::{Bracketed, Sequence};
9use sqruff_lib_core::parser::lexer::Matcher;
10use sqruff_lib_core::parser::node_matcher::NodeMatcher;
11use sqruff_lib_core::parser::parsers::RegexParser;
12use sqruff_lib_core::parser::segments::generator::SegmentGenerator;
13
14use crate::db2_keywords::UNRESERVED_KEYWORDS;
15
16use sqruff_lib_core::dialects::init::DialectConfig;
17use sqruff_lib_core::value::Value;
18
19sqruff_lib_core::dialect_config!(Db2DialectConfig {});
20
21pub fn dialect(config: Option<&Value>) -> Dialect {
22 let _dialect_config: Db2DialectConfig =
23 config.map(Db2DialectConfig::from_value).unwrap_or_default();
24
25 raw_dialect().config(|dialect| dialect.expand())
26}
27
28pub fn raw_dialect() -> Dialect {
29 let mut db2_dialect = super::ansi::dialect(None);
30 db2_dialect.name = DialectKind::Db2;
31
32 for kw in UNRESERVED_KEYWORDS {
33 db2_dialect.add_keyword_to_set("unreserved_keywords", kw);
34 }
35
36 db2_dialect.patch_lexer_matchers(vec![
38 Matcher::regex("inline_comment", r"(--)[^\n]*", SyntaxKind::InlineComment),
40 Matcher::regex("word", r"[0-9a-zA-Z_#]+", SyntaxKind::Word),
42 ]);
43
44 db2_dialect.add([
45 (
47 "NakedIdentifierSegment".into(),
48 SegmentGenerator::new(|dialect| {
49 let reserved_keywords = dialect.sets("reserved_keywords");
50 let pattern = reserved_keywords.iter().join("|");
51 let anti_template = format!("^({pattern})$");
52
53 RegexParser::new("[A-Z0-9_#]*[A-Z#][A-Z0-9_#]*", SyntaxKind::NakedIdentifier)
54 .anti_template(&anti_template)
55 .to_matchable()
56 })
57 .into(),
58 ),
59 (
61 "PostFunctionGrammar".into(),
62 one_of(vec![
63 Ref::new("OverClauseSegment").to_matchable(),
64 Ref::new("WithinGroupClauseSegment").to_matchable(),
65 ])
66 .to_matchable()
67 .into(),
68 ),
69 (
71 "Expression_C_Grammar".into(),
72 one_of(vec![
73 Sequence::new(vec![
74 Ref::keyword("EXISTS").to_matchable(),
75 Bracketed::new(vec![Ref::new("SelectableGrammar").to_matchable()])
76 .to_matchable(),
77 ])
78 .to_matchable(),
79 Sequence::new(vec![
80 one_of(vec![
81 Ref::new("Expression_D_Grammar").to_matchable(),
82 Ref::new("CaseExpressionSegment").to_matchable(),
83 ])
84 .to_matchable(),
85 AnyNumberOf::new(vec![Ref::new("TimeZoneGrammar").to_matchable()])
86 .config(|this| this.optional())
87 .to_matchable(),
88 ])
89 .to_matchable(),
90 Ref::new("ShorthandCastSegment").to_matchable(),
91 Sequence::new(vec![
92 Ref::new("NumericLiteralSegment").to_matchable(),
93 one_of(vec![
94 Ref::keyword("DAYS").to_matchable(),
95 Ref::keyword("DAY").to_matchable(),
96 ])
97 .to_matchable(),
98 ])
99 .to_matchable(),
100 ])
101 .config(|this| this.terminators = vec![Ref::new("CommaSegment").to_matchable()])
102 .to_matchable()
103 .into(),
104 ),
105 (
107 "WithinGroupClauseSegment".into(),
108 NodeMatcher::new(SyntaxKind::WithingroupClause, |_| {
109 Sequence::new(vec![
110 Ref::keyword("WITHIN").to_matchable(),
111 Ref::keyword("GROUP").to_matchable(),
112 Bracketed::new(vec![
113 Ref::new("OrderByClauseSegment").optional().to_matchable(),
114 ])
115 .to_matchable(),
116 ])
117 .to_matchable()
118 })
119 .to_matchable()
120 .into(),
121 ),
122 ]);
123
124 db2_dialect
125}