kproc_parser/
kparser.rs

1//! KParser tracer API
2use std::result;
3
4use crate::kdiagnostic::KDiagnInfo;
5use crate::kproc_macros::KTokenStream;
6use crate::proc_macro::TokenTree;
7
8/// Trace Trait to inject inside the parser to keep track
9/// what the parser is doing.
10pub trait KParserTracer {
11    fn log(&self, msg: &str);
12}
13
14/// A dummy tracer, no always we want
15/// trace the parser (maybe).
16pub struct DummyTracer;
17
18impl KParserTracer for DummyTracer {
19    fn log(&self, _: &str) {}
20}
21
22pub type Result<T> = result::Result<T, KParserError>;
23
24/// Generic error where with an specific
25/// token Tree and and error message that
26/// it is used to generate the diagnostic
27/// later.
28#[derive(Debug)]
29pub struct KParserError {
30    dig: KDiagnInfo,
31}
32
33impl KParserError {
34    pub fn new(dig: KDiagnInfo) -> Self {
35        KParserError { dig }
36    }
37
38    pub fn with_msg(tok: TokenTree, msg: &str, line: String, file: String) -> Self {
39        let diag = KDiagnInfo::new(msg, tok, line, file);
40        Self::new(diag)
41    }
42
43    pub fn expect(expect_tok: &str, tok: &TokenTree, line: String, file: String) -> Result<()> {
44        if expect_tok != &tok.to_string() {
45            let msg = format!("expected `{expect_tok}` but got `{tok}`");
46            return Err(KParserError {
47                dig: KDiagnInfo::new(&msg, tok.to_owned(), line, file),
48            });
49        }
50        Ok(())
51    }
52
53    pub fn emit(self) {
54        self.dig.emit()
55    }
56
57    pub fn span(&self) -> TokenTree {
58        self.dig.span()
59    }
60}
61
62/// KParser generic parser that it is used to
63/// parse any kind of token stream.
64pub trait KParser {
65    /// try to parse the token stream inside the type E, and if
66    /// there is no option for kparser, return an error.
67    fn parse<E>(&self, stream: &mut KTokenStream, tracer: &dyn KParserTracer) -> Result<E>;
68}