roup/parser/
openmp.rs

1use super::{
2    ClauseRegistry, ClauseRegistryBuilder, ClauseRule, DirectiveRegistry, DirectiveRegistryBuilder,
3    Parser,
4};
5
6const OPENMP_DEFAULT_CLAUSE_RULE: ClauseRule = ClauseRule::Unsupported;
7
8macro_rules! openmp_clauses {
9    ($( $variant:ident => { name: $name:literal, rule: $rule:expr } ),+ $(,)?) => {
10        #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
11        pub enum OpenMpClause {
12            $( $variant, )+
13        }
14
15        impl OpenMpClause {
16            pub const ALL: &'static [OpenMpClause] = &[ $( OpenMpClause::$variant, )+ ];
17
18            pub const fn name(self) -> &'static str {
19                match self {
20                    $( OpenMpClause::$variant => $name, )+
21                }
22            }
23
24            pub const fn rule(self) -> ClauseRule {
25                match self {
26                    $( OpenMpClause::$variant => $rule, )+
27                }
28            }
29        }
30    };
31}
32
33openmp_clauses! {
34    AcqRel => { name: "acq_rel", rule: ClauseRule::Bare },
35    Acquire => { name: "acquire", rule: ClauseRule::Bare },
36    Affinity => { name: "affinity", rule: ClauseRule::Parenthesized },
37    Aligned => { name: "aligned", rule: ClauseRule::Parenthesized },
38    Allocate => { name: "allocate", rule: ClauseRule::Parenthesized },
39    Allocator => { name: "allocator", rule: ClauseRule::Parenthesized },
40    AtomicDefaultMemOrder => { name: "atomic_default_mem_order", rule: ClauseRule::Parenthesized },
41    Bind => { name: "bind", rule: ClauseRule::Parenthesized },
42    Capture => { name: "capture", rule: ClauseRule::Flexible },
43    Collapse => { name: "collapse", rule: ClauseRule::Parenthesized },
44    Compare => { name: "compare", rule: ClauseRule::Flexible },
45    Copyin => { name: "copyin", rule: ClauseRule::Parenthesized },
46    Copyprivate => { name: "copyprivate", rule: ClauseRule::Parenthesized },
47    Default => { name: "default", rule: ClauseRule::Parenthesized },
48    Defaultmap => { name: "defaultmap", rule: ClauseRule::Parenthesized },
49    Depend => { name: "depend", rule: ClauseRule::Parenthesized },
50    Destroy => { name: "destroy", rule: ClauseRule::Flexible },
51    Detach => { name: "detach", rule: ClauseRule::Parenthesized },
52    Device => { name: "device", rule: ClauseRule::Parenthesized },
53    DeviceResident => { name: "device_resident", rule: ClauseRule::Parenthesized },
54    DeviceType => { name: "device_type", rule: ClauseRule::Parenthesized },
55    DistSchedule => { name: "dist_schedule", rule: ClauseRule::Parenthesized },
56    Doacross => { name: "doacross", rule: ClauseRule::Parenthesized },
57    DynamicAllocators => { name: "dynamic_allocators", rule: ClauseRule::Bare },
58    Exclusive => { name: "exclusive", rule: ClauseRule::Bare },
59    Fail => { name: "fail", rule: ClauseRule::Flexible },
60    Final => { name: "final", rule: ClauseRule::Parenthesized },
61    Filter => { name: "filter", rule: ClauseRule::Parenthesized },
62    Firstprivate => { name: "firstprivate", rule: ClauseRule::Parenthesized },
63    From => { name: "from", rule: ClauseRule::Parenthesized },
64    Grainsize => { name: "grainsize", rule: ClauseRule::Parenthesized },
65    Hint => { name: "hint", rule: ClauseRule::Parenthesized },
66    Holds => { name: "holds", rule: ClauseRule::Parenthesized },
67    If => { name: "if", rule: ClauseRule::Parenthesized },
68    InReduction => { name: "in_reduction", rule: ClauseRule::Parenthesized },
69    Inbranch => { name: "inbranch", rule: ClauseRule::Bare },
70    Inclusive => { name: "inclusive", rule: ClauseRule::Bare },
71    Init => { name: "init", rule: ClauseRule::Parenthesized },
72    Interop => { name: "interop", rule: ClauseRule::Parenthesized },
73    IsDevicePtr => { name: "is_device_ptr", rule: ClauseRule::Parenthesized },
74    Label => { name: "label", rule: ClauseRule::Parenthesized },
75    Lastprivate => { name: "lastprivate", rule: ClauseRule::Parenthesized },
76    Linear => { name: "linear", rule: ClauseRule::Parenthesized },
77    Link => { name: "link", rule: ClauseRule::Parenthesized },
78    Map => { name: "map", rule: ClauseRule::Parenthesized },
79    Match => { name: "match", rule: ClauseRule::Parenthesized },
80    Message => { name: "message", rule: ClauseRule::Parenthesized },
81    Mergeable => { name: "mergeable", rule: ClauseRule::Bare },
82    Nogroup => { name: "nogroup", rule: ClauseRule::Bare },
83    NoOpenmp => { name: "no_openmp", rule: ClauseRule::Flexible },
84    NoOpenmpRoutines => { name: "no_openmp_routines", rule: ClauseRule::Flexible },
85    NoParallelism => { name: "no_parallelism", rule: ClauseRule::Flexible },
86    Notinbranch => { name: "notinbranch", rule: ClauseRule::Bare },
87    Novariants => { name: "novariants", rule: ClauseRule::Flexible },
88    Nowait => { name: "nowait", rule: ClauseRule::Bare },
89    NumTasks => { name: "num_tasks", rule: ClauseRule::Parenthesized },
90    NumTeams => { name: "num_teams", rule: ClauseRule::Parenthesized },
91    NumThreads => { name: "num_threads", rule: ClauseRule::Parenthesized },
92    Nontemporal => { name: "nontemporal", rule: ClauseRule::Parenthesized },
93    Order => { name: "order", rule: ClauseRule::Parenthesized },
94    Ordered => { name: "ordered", rule: ClauseRule::Flexible },
95    Partial => { name: "partial", rule: ClauseRule::Flexible },
96    Priority => { name: "priority", rule: ClauseRule::Parenthesized },
97    Private => { name: "private", rule: ClauseRule::Parenthesized },
98    ProcBind => { name: "proc_bind", rule: ClauseRule::Parenthesized },
99    Public => { name: "public", rule: ClauseRule::Flexible },
100    Reduction => { name: "reduction", rule: ClauseRule::Parenthesized },
101    Release => { name: "release", rule: ClauseRule::Bare },
102    Relaxed => { name: "relaxed", rule: ClauseRule::Bare },
103    Reverse => { name: "reverse", rule: ClauseRule::Flexible },
104    Reproducible => { name: "reproducible", rule: ClauseRule::Bare },
105    Safelen => { name: "safelen", rule: ClauseRule::Parenthesized },
106    Schedule => { name: "schedule", rule: ClauseRule::Parenthesized },
107    SeqCst => { name: "seq_cst", rule: ClauseRule::Bare },
108    Shared => { name: "shared", rule: ClauseRule::Parenthesized },
109    Simdlen => { name: "simdlen", rule: ClauseRule::Parenthesized },
110    Sizes => { name: "sizes", rule: ClauseRule::Parenthesized },
111    TaskReduction => { name: "task_reduction", rule: ClauseRule::Parenthesized },
112    ThreadLimit => { name: "thread_limit", rule: ClauseRule::Parenthesized },
113    Tile => { name: "tile", rule: ClauseRule::Parenthesized },
114    To => { name: "to", rule: ClauseRule::Parenthesized },
115    UnifiedAddress => { name: "unified_address", rule: ClauseRule::Flexible },
116    UnifiedSharedMemory => { name: "unified_shared_memory", rule: ClauseRule::Flexible },
117    Unroll => { name: "unroll", rule: ClauseRule::Flexible },
118    Untied => { name: "untied", rule: ClauseRule::Bare },
119    Update => { name: "update", rule: ClauseRule::Flexible },
120    UseDeviceAddr => { name: "use_device_addr", rule: ClauseRule::Parenthesized },
121    UseDevicePtr => { name: "use_device_ptr", rule: ClauseRule::Parenthesized },
122    UsesAllocators => { name: "uses_allocators", rule: ClauseRule::Parenthesized },
123    Weak => { name: "weak", rule: ClauseRule::Flexible },
124    When => { name: "when", rule: ClauseRule::Parenthesized },
125}
126
127macro_rules! openmp_directives {
128    ($( $variant:ident => $name:literal ),+ $(,)?) => {
129        #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
130        pub enum OpenMpDirective {
131            $( $variant, )+
132        }
133
134        impl OpenMpDirective {
135            pub const ALL: &'static [OpenMpDirective] = &[ $( OpenMpDirective::$variant, )+ ];
136
137            pub const fn as_str(self) -> &'static str {
138                match self {
139                    $( OpenMpDirective::$variant => $name, )+
140                }
141            }
142        }
143    };
144}
145
146openmp_directives! {
147    Assume => "assume",
148    Atomic => "atomic",
149    AtomicCapture => "atomic capture",
150    AtomicCompareCapture => "atomic compare capture",
151    AtomicRead => "atomic read",
152    AtomicUpdate => "atomic update",
153    AtomicWrite => "atomic write",
154    Barrier => "barrier",
155    BeginDeclareTarget => "begin declare target",
156    Cancel => "cancel",
157    CancellationPoint => "cancellation point",
158    Critical => "critical",
159    DeclareMapper => "declare mapper",
160    DeclareReduction => "declare reduction",
161    DeclareSimd => "declare simd",
162    DeclareTarget => "declare target",
163    DeclareVariant => "declare variant",
164    Depobj => "depobj",
165    Dispatch => "dispatch",
166    Distribute => "distribute",
167    DistributeParallelFor => "distribute parallel for",
168    DistributeParallelForSimd => "distribute parallel for simd",
169    DistributeParallelLoop => "distribute parallel loop",
170    DistributeParallelLoopSimd => "distribute parallel loop simd",
171    DistributeSimd => "distribute simd",
172    // --- Fortran variants ---
173    DistributeParallelDo => "distribute parallel do",  // Fortran variant
174    DistributeParallelDoSimd => "distribute parallel do simd",  // Fortran variant
175    Do => "do",  // Fortran equivalent of FOR
176    DoSimd => "do simd",  // Fortran equivalent of FOR SIMD
177    EndDeclareTarget => "end declare target",
178    Error => "error",
179    Flush => "flush",
180    For => "for",
181    ForSimd => "for simd",
182    Interop => "interop",
183    Loop => "loop",
184    Masked => "masked",
185    MaskedTaskloop => "masked taskloop",
186    MaskedTaskloopSimd => "masked taskloop simd",
187    Master => "master",
188    Metadirective => "metadirective",
189    Nothing => "nothing",
190    Ordered => "ordered",
191    Parallel => "parallel",
192    ParallelDo => "parallel do",  // Fortran equivalent of PARALLEL FOR
193    ParallelDoSimd => "parallel do simd",  // Fortran equivalent of PARALLEL FOR SIMD
194    ParallelFor => "parallel for",
195    ParallelForSimd => "parallel for simd",
196    ParallelLoop => "parallel loop",
197    ParallelLoopSimd => "parallel loop simd",
198    ParallelMasked => "parallel masked",
199    ParallelMaskedTaskloop => "parallel masked taskloop",
200    ParallelMaskedTaskloopSimd => "parallel masked taskloop simd",
201    ParallelMaster => "parallel master",
202    ParallelMasterTaskloop => "parallel master taskloop",
203    ParallelMasterTaskloopSimd => "parallel master taskloop simd",
204    ParallelSections => "parallel sections",
205    Requires => "requires",
206    Scope => "scope",
207    Sections => "sections",
208    Simd => "simd",
209    Single => "single",
210    Target => "target",
211    TargetData => "target data",
212    TargetEnterData => "target enter data",
213    TargetExitData => "target exit data",
214    TargetLoop => "target loop",
215    TargetLoopSimd => "target loop simd",
216    TargetParallel => "target parallel",
217    TargetParallelDo => "target parallel do",  // Fortran variant
218    TargetParallelDoSimd => "target parallel do simd",  // Fortran variant
219    TargetParallelFor => "target parallel for",
220    TargetParallelForSimd => "target parallel for simd",
221    TargetParallelLoop => "target parallel loop",
222    TargetParallelLoopSimd => "target parallel loop simd",
223    TargetSimd => "target simd",
224    TargetTeams => "target teams",
225    TargetTeamsDistribute => "target teams distribute",
226    TargetTeamsDistributeParallelDo => "target teams distribute parallel do",  // Fortran variant
227    TargetTeamsDistributeParallelDoSimd => "target teams distribute parallel do simd",  // Fortran variant
228    TargetTeamsDistributeParallelFor => "target teams distribute parallel for",
229    TargetTeamsDistributeParallelForSimd => "target teams distribute parallel for simd",
230    TargetTeamsDistributeParallelLoop => "target teams distribute parallel loop",
231    TargetTeamsDistributeParallelLoopSimd => "target teams distribute parallel loop simd",
232    TargetTeamsDistributeSimd => "target teams distribute simd",
233    TargetTeamsLoop => "target teams loop",
234    TargetTeamsLoopSimd => "target teams loop simd",
235    TargetUpdate => "target update",
236    Task => "task",
237    Taskgroup => "taskgroup",
238    Taskgraph => "taskgraph",
239    Taskloop => "taskloop",
240    TaskloopSimd => "taskloop simd",
241    Taskwait => "taskwait",
242    Taskyield => "taskyield",
243    Teams => "teams",
244    TeamsDistribute => "teams distribute",
245    TeamsDistributeParallelDo => "teams distribute parallel do",  // Fortran variant
246    TeamsDistributeParallelDoSimd => "teams distribute parallel do simd",  // Fortran variant
247    TeamsDistributeParallelFor => "teams distribute parallel for",
248    TeamsDistributeParallelForSimd => "teams distribute parallel for simd",
249    TeamsDistributeParallelLoop => "teams distribute parallel loop",
250    TeamsDistributeParallelLoopSimd => "teams distribute parallel loop simd",
251    TeamsDistributeSimd => "teams distribute simd",
252    TeamsLoop => "teams loop",
253    TeamsLoopSimd => "teams loop simd",
254    Threadprivate => "threadprivate",
255}
256
257pub fn clause_registry() -> ClauseRegistry {
258    let mut builder = ClauseRegistryBuilder::new().with_default_rule(OPENMP_DEFAULT_CLAUSE_RULE);
259
260    for clause in OpenMpClause::ALL {
261        builder.register_with_rule_mut(clause.name(), clause.rule());
262    }
263
264    builder.build()
265}
266
267pub fn directive_registry() -> DirectiveRegistry {
268    let mut builder = DirectiveRegistryBuilder::new();
269
270    for directive in OpenMpDirective::ALL {
271        builder = builder.register_generic(directive.as_str());
272    }
273
274    builder.build()
275}
276
277pub fn parser() -> Parser {
278    Parser::new(directive_registry(), clause_registry())
279}