use anyhow::{Context, Result};
use std::fs;
use tree_sitter::{Language, Parser, Tree};
pub fn c_language() -> Language {
lang_parsing_substrate::tree_sitter_c::LANGUAGE.into()
}
pub struct CParser {
parser: Parser,
}
impl CParser {
pub fn new() -> Result<Self> {
let mut parser = Parser::new();
parser
.set_language(&c_language())
.context("Failed to set C language for parser")?;
Ok(Self { parser })
}
pub fn parse_file(&mut self, file_path: &str) -> Result<(Tree, String)> {
let source = fs::read_to_string(file_path)
.with_context(|| format!("Failed to read file: {}", file_path))?;
let source = crate::analyze::empty_macro_blank::blank_empty_object_macros(&source);
let source = crate::analyze::preproc_dangling_else::blank_dangling_else_preproc(&source);
let source = crate::analyze::label_preproc_guard::blank_label_guarded_preproc(&source);
let (tree, source) = crate::analyze::unknown_identifier_recovery::parse_with_recovery(
&mut self.parser,
source,
)
.with_context(|| format!("Failed to parse file: {}", file_path))?;
Ok((tree, source))
}
pub fn parse_source(&mut self, source: &str) -> Result<(Tree, String)> {
let source = crate::analyze::empty_macro_blank::blank_empty_object_macros(source);
let source = crate::analyze::preproc_dangling_else::blank_dangling_else_preproc(&source);
let source = crate::analyze::label_preproc_guard::blank_label_guarded_preproc(&source);
let (tree, source) = crate::analyze::unknown_identifier_recovery::parse_with_recovery(
&mut self.parser,
source,
)
.context("Failed to parse source code")?;
Ok((tree, source))
}
}
impl Default for CParser {
fn default() -> Self {
Self::new().expect("Failed to create C parser")
}
}