|
1 | 1 | //! A parser for CDDL, utilized for parsing in accordance with RFC 8610. |
2 | 2 |
|
3 | | -#![allow(missing_docs)] // TODO(apskhem): Temporary, to bo removed in a subsequent PR |
| 3 | +mod parser; |
| 4 | +mod preprocessor; |
4 | 5 |
|
5 | | -use derive_more::{Display, From}; |
6 | | -pub use pest::Parser; |
7 | | -use pest::{error::Error, iterators::Pairs}; |
8 | | - |
9 | | -pub mod rfc_8610 { |
10 | | - pub use pest::Parser; |
11 | | - |
12 | | - #[derive(pest_derive::Parser)] |
13 | | - #[grammar = "grammar/rfc_8610.pest"] |
14 | | - pub struct RFC8610Parser; |
15 | | -} |
16 | | - |
17 | | -pub mod rfc_9165 { |
18 | | - pub use pest::Parser; |
19 | | - |
20 | | - #[derive(pest_derive::Parser)] |
21 | | - #[grammar = "grammar/rfc_8610.pest"] |
22 | | - #[grammar = "grammar/rfc_9165.pest"] |
23 | | - pub struct RFC8610Parser; |
24 | | -} |
25 | | - |
26 | | -pub mod cddl { |
27 | | - pub use pest::Parser; |
28 | | - |
29 | | - #[derive(pest_derive::Parser)] |
30 | | - #[grammar = "grammar/rfc_8610.pest"] |
31 | | - #[grammar = "grammar/rfc_9165.pest"] |
32 | | - #[grammar = "grammar/cddl_modules.pest"] |
33 | | - pub struct RFC8610Parser; |
34 | | -} |
35 | | - |
36 | | -pub mod cddl_test { |
37 | | - pub use pest::Parser; |
38 | | - |
39 | | - // Parser with DEBUG rules. These rules are only used in tests. |
40 | | - #[derive(pest_derive::Parser)] |
41 | | - #[grammar = "grammar/rfc_8610.pest"] |
42 | | - #[grammar = "grammar/rfc_9165.pest"] |
43 | | - #[grammar = "grammar/cddl_modules.pest"] |
44 | | - #[grammar = "grammar/cddl_test.pest"] // Ideally this would only be used in tests. |
45 | | - pub struct CDDLTestParser; |
46 | | -} |
47 | | - |
48 | | -/// Represents different parser extensions for handling CDDL specifications. |
| 6 | +/// Represents different grammar extensions for handling CDDL specifications. |
49 | 7 | pub enum Extension { |
50 | | - /// RFC8610 ONLY limited parser. |
51 | | - RFC8610Parser, |
52 | | - /// RFC8610 and RFC9165 limited parser. |
53 | | - RFC9165Parser, |
54 | | - /// RFC8610, RFC9165, and CDDL modules. |
55 | | - CDDLParser, |
56 | | -} |
57 | | - |
58 | | -// CDDL Standard Postlude - read from an external file |
59 | | -pub const POSTLUDE: &str = include_str!("grammar/postlude.cddl"); |
60 | | - |
61 | | -/// Abstract Syntax Tree (AST) representing parsed CDDL syntax. |
62 | | -// TODO: this is temporary. need to add more pragmatic nodes |
63 | | -#[derive(Debug)] |
64 | | -pub enum AST<'a> { |
65 | | - /// Represents the AST for RFC 8610 CDDL rules. |
66 | | - RFC8610(Pairs<'a, rfc_8610::Rule>), |
67 | | - /// Represents the AST for RFC 9165 CDDL rules. |
68 | | - RFC9165(Pairs<'a, rfc_9165::Rule>), |
69 | | - /// Represents the AST for CDDL Modules rules. |
70 | | - CDDL(Pairs<'a, cddl::Rule>), |
| 8 | + /// RFC8610 ONLY limited grammar. |
| 9 | + RFC8610, |
| 10 | + /// RFC8610 and RFC9165 limited grammar. |
| 11 | + RFC9165, |
| 12 | + /// RFC8610, RFC9165, and CDDL grammar. |
| 13 | + CDDL, |
71 | 14 | } |
72 | 15 |
|
73 | | -/// Represents different types of errors related to different types of extension. |
74 | | -#[derive(Display, Debug)] |
75 | | -pub enum CDDLErrorType { |
76 | | - /// An error related to RFC 8610 extension. |
77 | | - RFC8610(Error<rfc_8610::Rule>), |
78 | | - /// An error related to RFC 9165 extension. |
79 | | - RFC9165(Error<rfc_9165::Rule>), |
80 | | - /// An error related to CDDL modules extension. |
81 | | - CDDL(Error<cddl::Rule>), |
82 | | -} |
83 | | - |
84 | | -/// Represents an error that may occur during CDDL parsing. |
85 | | -#[derive(thiserror::Error, Debug, From)] |
86 | | -#[error("{0}")] |
87 | | -pub struct CDDLError(CDDLErrorType); |
88 | | - |
89 | | -/// Parses and checks semantically a CDDL input string. |
90 | | -/// |
91 | | -/// # Arguments |
92 | | -/// |
93 | | -/// * `input` - A string containing the CDDL input to be parsed. |
94 | | -/// |
95 | | -/// # Returns |
96 | | -/// |
97 | | -/// Returns `Ok(())` if parsing is successful, otherwise returns an `Err` containing |
98 | | -/// a boxed `CDDLError` indicating the parsing error. |
| 16 | +/// Verifies semantically a CDDL input string. |
99 | 17 | /// |
100 | 18 | /// # Errors |
101 | 19 | /// |
102 | 20 | /// This function may return an error in the following cases: |
103 | 21 | /// |
104 | 22 | /// - If there is an issue with parsing the CDDL input. |
105 | | -/// |
106 | | -/// # Examples |
107 | | -/// |
108 | | -/// ```rs |
109 | | -/// use cbork_cddl_parser::{parse_cddl, Extension}; |
110 | | -/// use std:fs; |
111 | | -/// |
112 | | -/// let mut input = fs::read_to_string("path/to/your/file.cddl").unwrap(); |
113 | | -/// let result = parse_cddl(&mut input, &Extension::CDDLParser); |
114 | | -/// assert!(result.is_ok()); |
115 | | -/// ``` |
116 | | -pub fn parse_cddl<'a>( |
117 | | - input: &'a mut String, extension: &Extension, |
118 | | -) -> Result<AST<'a>, Box<CDDLError>> { |
119 | | - input.push_str("\n\n"); |
120 | | - input.push_str(POSTLUDE); |
121 | | - |
122 | | - let result = match extension { |
123 | | - Extension::RFC8610Parser => { |
124 | | - rfc_8610::RFC8610Parser::parse(rfc_8610::Rule::cddl, input) |
125 | | - .map(AST::RFC8610) |
126 | | - .map_err(CDDLErrorType::RFC8610) |
127 | | - }, |
128 | | - Extension::RFC9165Parser => { |
129 | | - rfc_9165::RFC8610Parser::parse(rfc_9165::Rule::cddl, input) |
130 | | - .map(AST::RFC9165) |
131 | | - .map_err(CDDLErrorType::RFC9165) |
132 | | - }, |
133 | | - Extension::CDDLParser => { |
134 | | - cddl::RFC8610Parser::parse(cddl::Rule::cddl, input) |
135 | | - .map(AST::CDDL) |
136 | | - .map_err(CDDLErrorType::CDDL) |
137 | | - }, |
138 | | - }; |
139 | | - |
140 | | - result.map_err(|e| Box::new(CDDLError::from(e))) |
141 | | -} |
142 | | - |
143 | | -#[cfg(test)] |
144 | | -mod tests { |
145 | | - use crate::*; |
146 | | - |
147 | | - #[test] |
148 | | - fn it_works() { |
149 | | - let mut input = String::new(); |
150 | | - let result = parse_cddl(&mut input, &Extension::CDDLParser); |
151 | | - |
152 | | - match result { |
153 | | - Ok(c) => println!("{c:?}"), |
154 | | - Err(e) => { |
155 | | - println!("{e:?}"); |
156 | | - println!("{e}"); |
157 | | - }, |
158 | | - } |
159 | | - } |
| 23 | +pub fn validate_cddl(input: &mut String, extension: &Extension) -> anyhow::Result<()> { |
| 24 | + let ast = parser::parse_cddl(input, extension)?; |
| 25 | + let _ast = preprocessor::process_ast(ast)?; |
| 26 | + Ok(()) |
160 | 27 | } |
0 commit comments