leo_parser_rowan/lib.rs
1// Copyright (C) 2019-2026 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17//! Rowan-based lossless syntax tree and parser for Leo.
18//!
19//! This crate provides a lossless parser using the rowan library, designed for
20//! IDE-grade error recovery.
21
22mod lexer;
23mod parser;
24mod syntax_kind;
25
26use leo_errors::Result;
27pub use lexer::{LexError, LexErrorKind, Token, lex};
28pub use parser::{
29 Parse,
30 ParseError,
31 Parser,
32 parse_expression_entry,
33 parse_file,
34 parse_module_entry,
35 parse_statement_entry,
36};
37pub use rowan::TextRange;
38pub use syntax_kind::{SyntaxKind, syntax_kind_from_raw};
39
40/// Returns whether `s` is a Leo keyword recognized by the lexer.
41pub fn is_keyword(s: &str) -> bool {
42 lexer::is_keyword(s)
43}
44
45/// The Leo language type for rowan.
46#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
47pub enum LeoLanguage {}
48
49impl rowan::Language for LeoLanguage {
50 type Kind = SyntaxKind;
51
52 fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {
53 syntax_kind_from_raw(raw)
54 }
55
56 fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {
57 kind.into()
58 }
59}
60
61/// A syntax node in the Leo syntax tree.
62pub type SyntaxNode = rowan::SyntaxNode<LeoLanguage>;
63
64/// A syntax token in the Leo syntax tree.
65pub type SyntaxToken = rowan::SyntaxToken<LeoLanguage>;
66
67/// Either a syntax node or token.
68pub type SyntaxElement = rowan::SyntaxElement<LeoLanguage>;
69
70/// Parse an expression from source code.
71///
72/// # Arguments
73/// * `source` - The source code to parse.
74///
75/// # Returns
76/// A syntax node representing the parsed expression.
77pub fn parse_expression(source: &str) -> Result<SyntaxNode> {
78 let parse = parse_expression_entry(source);
79 // TODO: Convert ParseErrors to leo_errors::Result when needed
80 Ok(parse.syntax())
81}
82
83/// Parse a statement from source code.
84///
85/// # Arguments
86/// * `source` - The source code to parse.
87///
88/// # Returns
89/// A syntax node representing the parsed statement.
90pub fn parse_statement(source: &str) -> Result<SyntaxNode> {
91 let parse = parse_statement_entry(source);
92 // TODO: Convert ParseErrors to leo_errors::Result when needed
93 Ok(parse.syntax())
94}
95
96/// Parse a module from source code.
97///
98/// # Arguments
99/// * `source` - The source code to parse.
100///
101/// # Returns
102/// A syntax node representing the parsed module.
103pub fn parse_module(source: &str) -> Result<SyntaxNode> {
104 let parse = parse_module_entry(source);
105 // TODO: Convert ParseErrors to leo_errors::Result when needed
106 Ok(parse.syntax())
107}
108
109/// Parse a main program file from source code.
110///
111/// # Arguments
112/// * `source` - The source code to parse.
113///
114/// # Returns
115/// A syntax node representing the parsed program.
116pub fn parse_main(source: &str) -> Result<SyntaxNode> {
117 let parse = parse_file(source);
118 // TODO: Convert ParseErrors to leo_errors::Result when needed
119 Ok(parse.syntax())
120}