#![forbid(unsafe_code)]
mod generated {
#![allow(warnings)]
#![allow(clippy::all, clippy::pedantic, clippy::nursery)]
pub mod gremlin;
pub mod gremlin_lexer;
}
use antlr4_runtime::{CommonTokenStream, InputStream, Parser};
pub use antlr4_runtime::tree::ParseTree;
use generated::gremlin::Gremlin;
use generated::gremlin_lexer::GremlinLexer;
#[derive(Debug)]
pub enum GremlinParseError {
Runtime(antlr4_runtime::AntlrError),
Syntax { count: usize, tree: ParseTree },
}
impl core::fmt::Display for GremlinParseError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Runtime(e) => write!(f, "gremlin parse failed: {e}"),
Self::Syntax { count, .. } => {
write!(f, "gremlin input has {count} syntax error(s)")
}
}
}
}
impl std::error::Error for GremlinParseError {}
impl From<antlr4_runtime::AntlrError> for GremlinParseError {
fn from(e: antlr4_runtime::AntlrError) -> Self {
Self::Runtime(e)
}
}
pub fn parse(input: &str) -> Result<ParseTree, GremlinParseError> {
parse_with(input, Gremlin::query_list)
}
pub fn parse_query(input: &str) -> Result<ParseTree, GremlinParseError> {
parse_with(input, Gremlin::query)
}
fn parse_with<F>(input: &str, entry: F) -> Result<ParseTree, GremlinParseError>
where
F: FnOnce(
&mut Gremlin<GremlinLexer<InputStream>>,
) -> Result<ParseTree, antlr4_runtime::AntlrError>,
{
let lexer = GremlinLexer::new(InputStream::new(input));
let tokens = CommonTokenStream::new(lexer);
let mut parser = Gremlin::new(tokens);
let tree = entry(&mut parser)?;
let count = parser.number_of_syntax_errors();
if count > 0 {
return Err(GremlinParseError::Syntax { count, tree });
}
Ok(tree)
}