carbon_parser/lib.rs
1//! # Carbon Parser
2//!
3//! Бібліотека для парсингу мови програмування Carbon від Google.
4//!
5//! ## Приклад використання
6//!
7//! ```rust
8//! use carbon_parser::parse_carbon;
9//!
10//! let code = r#"
11//! fn main() -> i32 {
12//! var x: i32 = 42;
13//! return x;
14//! }
15//! "#;
16//!
17//! let result = parse_carbon(code);
18//! assert!(result.is_ok());
19use pest::Parser;
20use pest_derive::Parser;
21use thiserror::Error;
22
23/// Парсер Carbon, згенерований за допомогою Pest
24#[derive(Parser)]
25#[grammar = "carbon.pest"]
26pub struct CarbonParser;
27
28/// Помилки парсингу
29#[derive(Error, Debug)]
30pub enum ParseError {
31 #[error("Синтаксична помилка: {0}")]
32 SyntaxError(String),
33
34 #[error("Помилка парсера: {0}")]
35 PestError(#[from] pest::error::Error<Rule>),
36}
37
38pub type ParseResult<T> = Result<T, ParseError>;
39
40/// Парсить код Carbon та повертає дерево розбору
41///
42/// # Аргументи
43///
44/// * `input` - Вхідний код Carbon як рядок
45///
46/// # Повертає
47///
48/// * `ParseResult<pest::iterators::Pairs<Rule>>` - Результат парсингу
49///
50/// # Приклад
51///
52/// ```rust
53/// use carbon_parser::parse_carbon;
54///
55/// let code = "fn test() -> i32 { return 42; }";
56/// let result = parse_carbon(code);
57/// assert!(result.is_ok());
58/// ```
59pub fn parse_carbon(input: &str) -> ParseResult<pest::iterators::Pairs<Rule>> {
60 CarbonParser::parse(Rule::program, input).map_err(ParseError::from)
61}
62
63/// Парсить декларацію функції
64/// Декларація функції має форму:
65/// ```carbon
66/// fn function_name(param1: Type1, param2: Type2) -> ReturnType {
67/// // тіло функції
68/// }
69/// ```
70///
71/// # Аргументи
72///
73/// * `input` - Вхідний код з декларацією функції
74///
75/// # Повертає
76///
77/// * `ParseResult<pest::iterators::Pairs<Rule>>` - Результат парсингу
78///
79/// # Приклад
80///
81/// ```rust
82/// use carbon_parser::parse_function_decl;
83///
84/// let code = "fn add(x: i32, y: i32) -> i32 { return x; }";
85/// let result = parse_function_decl(code);
86/// assert!(result.is_ok());
87/// ```
88pub fn parse_function_decl(input: &str) -> ParseResult<pest::iterators::Pairs<Rule>> {
89 CarbonParser::parse(Rule::function_decl, input).map_err(ParseError::from)
90}
91
92/// Парсить декларацію змінної
93/// Декларація змінної має форму:
94/// ```carbon
95/// var variable_name: Type = initial_value;
96/// ```
97///
98/// # Аргументи
99///
100/// * `input` - Вхідний код з декларацією змінної
101///
102/// # Повертає
103///
104/// * `ParseResult<pest::iterators::Pairs<Rule>>` - Результат парсингу
105///
106/// # Приклад
107///
108/// ```rust
109/// use carbon_parser::parse_var_decl;
110///
111/// let code = "var x: i32 = 42;";
112/// let result = parse_var_decl(code);
113/// assert!(result.is_ok());
114/// ```
115pub fn parse_var_decl(input: &str) -> ParseResult<pest::iterators::Pairs<Rule>> {
116 CarbonParser::parse(Rule::var_decl, input).map_err(ParseError::from)
117}
118
119/// Парсить вираз
120///
121/// Вирази включають літерали, ідентифікатори, бінарні операції та виклики функцій.
122///
123/// # Аргументи
124///
125/// * `input` - Вхідний код з виразом
126///
127/// # Повертає
128///
129/// * `ParseResult<pest::iterators::Pairs<Rule>>` - Результат парсингу
130///
131/// # Приклад
132///
133/// ```rust
134/// use carbon_parser::parse_expression;
135///
136/// let code = "42 + x * 2";
137/// let result = parse_expression(code);
138/// assert!(result.is_ok());
139/// ```
140pub fn parse_expression(input: &str) -> ParseResult<pest::iterators::Pairs<Rule>> {
141 CarbonParser::parse(Rule::expression, input).map_err(ParseError::from)
142}
143
144/// Парсить ім'я типу
145///
146/// Підтримувані типи: i32, i64, f32, f64, bool, String та користувацькі типи.
147///
148/// # Аргументи
149///
150/// * `input` - Вхідний код з іменем типу
151///
152/// # Повертає
153///
154/// * `ParseResult<pest::iterators::Pairs<Rule>>` - Результат парсингу
155///
156/// # Приклад
157///
158/// ```rust
159/// use carbon_parser::parse_type_name;
160///
161/// let code = "i32";
162/// let result = parse_type_name(code);
163/// assert!(result.is_ok());
164/// ```
165pub fn parse_type_name(input: &str) -> ParseResult<pest::iterators::Pairs<Rule>> {
166 CarbonParser::parse(Rule::type_name, input).map_err(ParseError::from)
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn test_simple_function() {
175 let code = r#"
176 fn main() -> i32 {
177 return 42;
178 }
179 "#;
180 assert!(parse_carbon(code).is_ok());
181 }
182
183 #[test]
184 fn test_function_with_params() {
185 let code = "fn add(x: i32, y: i32) -> i32 { return x; }";
186 assert!(parse_function_decl(code).is_ok());
187 }
188
189 #[test]
190 fn test_variable_declaration() {
191 let code = "var x: i32 = 42;";
192 assert!(parse_var_decl(code).is_ok());
193 }
194
195 #[test]
196 fn test_expression() {
197 let code = "42 + 10 * 2";
198 assert!(parse_expression(code).is_ok());
199 }
200
201 #[test]
202 fn test_type_names() {
203 assert!(parse_type_name("i32").is_ok());
204 assert!(parse_type_name("bool").is_ok());
205 assert!(parse_type_name("String").is_ok());
206 }
207}